| Line |
Branch |
Exec |
Source |
| 1 |
|
|
/***************************************************************************** |
| 2 |
|
|
* |
| 3 |
|
|
* This file is part of the ecapp library (EtherCAT application devices). |
| 4 |
|
|
* |
| 5 |
|
|
* Copyright (C) 2026 Florian Pose <fp@igh.de> |
| 6 |
|
|
* |
| 7 |
|
|
* The ecapp library is free software: you can redistribute it and/or |
| 8 |
|
|
* modify it under the terms of the GNU Lesser General Public License |
| 9 |
|
|
* as published by the Free Software Foundation, version 3 of the |
| 10 |
|
|
* License. |
| 11 |
|
|
* |
| 12 |
|
|
* The ecapp library is distributed in the hope that it will be useful, |
| 13 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 |
|
|
* Lesser General Public License for more details. |
| 16 |
|
|
* |
| 17 |
|
|
* You should have received a copy of the GNU Lesser General Public |
| 18 |
|
|
* License along with the ecapp library. If not, see |
| 19 |
|
|
* <https://www.gnu.org/licenses/>. |
| 20 |
|
|
* |
| 21 |
|
|
* Beckhoff/Wago-style analog input terminals with a scaled double-value |
| 22 |
|
|
* channel plus a status byte per channel: EL3008, EL3024, EL3054, |
| 23 |
|
|
* EL3062(-0030), EL3068, EL3074, EL3102, EL3104, EL3122, EL3164, |
| 24 |
|
|
* EL3182, EL3311, EL3318, EL3602-0010, EM3702, EPP3184. This grouping |
| 25 |
|
|
* is an implementation detail -- application code never names Ex3xxx |
| 26 |
|
|
* directly, it goes through createSubDevice("EL3008") and gets an |
| 27 |
|
|
* EcApp::SubDevice back. |
| 28 |
|
|
* |
| 29 |
|
|
* A subset (EL3074, EPP3184) supports a switchable measuring range, |
| 30 |
|
|
* exposed generically via the IAnalogInputType capability rather than |
| 31 |
|
|
* as a plain virtual on SubDevice -- most Ex3xxx types don't have it, |
| 32 |
|
|
* and every future analog family would otherwise have to grow the base |
| 33 |
|
|
* interface too. |
| 34 |
|
|
* |
| 35 |
|
|
****************************************************************************/ |
| 36 |
|
|
|
| 37 |
|
|
#ifndef ECAPP_EX3XXX_H |
| 38 |
|
|
#define ECAPP_EX3XXX_H |
| 39 |
|
|
|
| 40 |
|
|
/****************************************************************************/ |
| 41 |
|
|
|
| 42 |
|
|
#include "ecapp/Mode.h" |
| 43 |
|
|
|
| 44 |
|
|
#include <ecrt.h> // EtherCAT realtime interface |
| 45 |
|
|
#include <pdserv.h> |
| 46 |
|
|
#include <stdint.h> |
| 47 |
|
|
#include <string> |
| 48 |
|
|
#include <vector> |
| 49 |
|
|
|
| 50 |
|
|
/****************************************************************************/ |
| 51 |
|
|
|
| 52 |
|
|
namespace EcApp { |
| 53 |
|
|
|
| 54 |
|
|
class Master; |
| 55 |
|
|
class Domain; |
| 56 |
|
|
|
| 57 |
|
|
struct Ex3xxxType; |
| 58 |
|
|
|
| 59 |
|
|
template <Mode mode> |
| 60 |
|
2 |
class Ex3xxx |
| 61 |
|
|
{ |
| 62 |
|
|
public: |
| 63 |
|
|
enum Type { |
| 64 |
|
|
EL3008, |
| 65 |
|
|
EL3024, |
| 66 |
|
|
EL3054, |
| 67 |
|
|
EL3062, |
| 68 |
|
|
EL3062_0030, |
| 69 |
|
|
EL3068, |
| 70 |
|
|
EL3074, |
| 71 |
|
|
EL3102, |
| 72 |
|
|
EL3104, |
| 73 |
|
|
EL3122, |
| 74 |
|
|
EL3164, |
| 75 |
|
|
EL3182, |
| 76 |
|
|
EL3311, |
| 77 |
|
|
EL3318, |
| 78 |
|
|
EL3602_0010, |
| 79 |
|
|
EM3702, |
| 80 |
|
|
EPP3184, |
| 81 |
|
|
NumTypes |
| 82 |
|
|
}; |
| 83 |
|
|
|
| 84 |
|
|
Ex3xxx(pdserv *, |
| 85 |
|
|
pdtask *, |
| 86 |
|
|
const std::string &, |
| 87 |
|
|
Master *, |
| 88 |
|
|
uint16_t, |
| 89 |
|
|
uint16_t, |
| 90 |
|
|
Domain *, |
| 91 |
|
|
Type); |
| 92 |
|
|
|
| 93 |
|
|
enum InputType { |
| 94 |
|
|
InputPlusMinus10V = 0, |
| 95 |
|
|
Input0To20mA = 1, |
| 96 |
|
|
Input4To20mA = 2, |
| 97 |
|
|
InputPlusMinus20mA = 3, |
| 98 |
|
|
Input0To10V = 6 |
| 99 |
|
|
}; |
| 100 |
|
|
|
| 101 |
|
|
// Pushes the requested range to the slave via SDO immediately; does |
| 102 |
|
|
// nothing for a channel whose terminal type has no switchable range |
| 103 |
|
|
// (see supportsInputType()). Must be called before the master is |
| 104 |
|
|
// activated, and at most once per channel: the EtherCAT master |
| 105 |
|
|
// queues every ecrt_slave_config_sdo*() call as a separate SDO |
| 106 |
|
|
// download rather than replacing an earlier one for the same |
| 107 |
|
|
// index/subindex, so a second call would not be an overwrite but |
| 108 |
|
|
// an extra (wasted) download at activation time. Throws |
| 109 |
|
|
// std::logic_error if called twice for the same channel. |
| 110 |
|
|
void setInputType(unsigned int, InputType); |
| 111 |
|
|
|
| 112 |
|
|
void update(); // reads status + scaled input for every channel |
| 113 |
|
|
|
| 114 |
|
|
void setScale(unsigned int, double); |
| 115 |
|
|
void setOffset(unsigned int, double); |
| 116 |
|
|
|
| 117 |
|
|
uint8_t getStatus(unsigned int) const; // Control |
| 118 |
|
|
double getInput(unsigned int) const; // Control |
| 119 |
|
|
|
| 120 |
|
|
void setStatus(unsigned int, uint8_t) const; // Simulation |
| 121 |
|
|
void setInput(unsigned int, double) const; // Simulation |
| 122 |
|
|
|
| 123 |
|
|
unsigned int numChannels() const; |
| 124 |
|
|
bool supportsInputType() const; |
| 125 |
|
|
|
| 126 |
|
|
private: |
| 127 |
|
|
const Ex3xxxType &type; |
| 128 |
|
|
ec_slave_config_t *sc; |
| 129 |
|
|
Domain *const domainIn; |
| 130 |
|
|
|
| 131 |
|
|
std::vector<InputType> inputType; |
| 132 |
|
|
std::vector<bool> inputTypeSet; // guards against a second |
| 133 |
|
|
// setInputType() call per channel |
| 134 |
|
|
|
| 135 |
|
|
std::vector<int> off_sts; |
| 136 |
|
|
std::vector<int> off_in; |
| 137 |
|
|
std::vector<uint8_t> status; |
| 138 |
|
|
std::vector<double> scale; |
| 139 |
|
|
std::vector<double> offset; |
| 140 |
|
|
std::vector<double> input; |
| 141 |
|
|
}; |
| 142 |
|
|
|
| 143 |
|
|
} // namespace EcApp |
| 144 |
|
|
|
| 145 |
|
|
#endif // ECAPP_EX3XXX_H |
| 146 |
|
|
|
| 147 |
|
|
/****************************************************************************/ |
| 148 |
|
|
|