Lydia - Printhead
OmronPIDModbus.cpp
Go to the documentation of this file.
1 #include <xmath.h>
2 
3 #include "OmronPID.h"
4 #include "ModbusBridge.h"
5 #include "./OmronE5.h"
6 #include "./enums.h"
7 #include "./config.h"
8 #include "./utils.h"
9 
10 bool printModbus = false;
11 bool printPIDUpdates = false;
12 bool _debugQuery = false;
13 bool _debugQueryState = false;
14 bool debugResponse = false;
15 bool debugRawResponse = false;
16 bool debugNextUpdates = false;
17 bool printMBErrors = true;
18 
19 #define DEBUG_OPID_ERRORS
20 #ifdef DEBUG_OPID_ERRORS
21  #define _DEBUG_OPID_ERRORS(format, ...) Log.verboseln(format, ##__VA_ARGS__)
22 #else
23  #define _DEBUG_OPID_ERRORS(format, ...)
24 #endif
25 
27  return pidBySlave(queue.val());
28 }
30 {
31  OmronState *oldest = NULL;
32  for (short i = 0; i < NB_OMRON_PIDS; i++)
33  {
34  OmronState *c = &states[i];
35  if (c->flags == OmronState::FLAGS::UPDATING &&
36  millis() - c->lastUpdated > (1000 * 2))
37  {
38  c->flags == OmronState::FLAGS::DIRTY;
39  }
40  if (c->flags == OmronState::FLAGS::UPDATING)
41  {
42  continue;
43  }
44  if (!oldest)
45  {
46  oldest = c;
47  }
48  if (c != oldest && c->lastUpdated < oldest->lastUpdated)
49  {
50  oldest = c;
51  }
52  }
53  return oldest;
54 }
56 {
57  OmronState *next = nextToUpdate2();
58  if (next != NULL)
59  {
61  next->flags = OmronState::FLAGS::UPDATING;
62  next->lastUpdated = millis();
63  if(_debugQuery){
64  Log.verboseln("OmronPID::updateState : Slave=%d", next->slaveID);
65  }
67  }
68 }
70 {
71  if (modbus->qstate() != IDLE)
72  return E_SKIP;
73 
74  if (millis() - last < OMRON_PID_UPDATE_INTERVAL)
75  return E_SKIP;
76 
77  last = now;
78  fromTCP();
79  updateState();
81  if (!nextCommand)
82  return E_SKIP;
83 
84  if (printModbus)
85  modbus->print();
86 
87  nextCommand->state = QUERY_STATE::PROCESSING;
88  nextCommand->ts = millis();
90  if (_debugQueryState)
91  {
92  if (millis() - d0TS > 1000)
93  {
94  Log.verboseln("OmronPID::loop : Query Modbus : Slave=%d | FN=%d | Addr=%d | Nb=%d",
95  nextCommand->slave,
96  nextCommand->fn,
97  nextCommand->addr,
98  nextCommand->value);
99 
100  nextCommand->print();
101  Serial.println();
102  d0TS = now;
103  }
104  }
105 
106 
107  modbus->query(
108  nextCommand->slave,
109  nextCommand->fn,
110  nextCommand->addr,
111  nextCommand->value,
112  id);
113 
114  return E_OK;
115 }
116 short OmronPID::read10_16(int slaveAddress, int addr, int prio)
117 {
119  {
120  return E_SKIP;
121  }
122  Query *next = modbus->nextQueryByState(DONE);
123  if (next != NULL)
124  {
125  next->reset();
127  next->slave = slaveAddress;
129  next->addr = addr;
130  next->state = QUERY_STATE::QUEUED;
131  next->prio = prio;
132  next->owner = id;
133  next->ts = millis();
134  return E_QUEUED;
135  }
136  return E_SKIP;
137 }
138 short OmronPID::onRawResponse(short size, uint8_t rxBuffer[])
139 {
140  Query *current = modbus->nextQueryByState(PROCESSING, id);
141  if (debugRawResponse)
142  {
143  Log.verboseln("OmronPID::rawResponse : size=%d | %X", size, rxBuffer);
144  }
145  if (current)
146  {
147  switch (current->fn)
148  {
150  {
151 
152  if (size == 5 && rxBuffer[1] == OR_E5_RESPONSE_CODE::OR_COMMAND_ERROR)
153  {
154  Serial.print("------ \n Command Error: ");
155  Serial.print(rxBuffer[2]);
156  Serial.print(" : ");
157  switch (rxBuffer[2])
158  {
160  {
161  Serial.println(OR_E_MSG_INVALID_ADDRESS);
162  break;
163  }
165  {
166  Serial.println(OR_E_MSG_INVALID_RANGE);
167  break;
168  }
170  {
171  Serial.println(OR_E_MSG_OPERATION_ERROR);
172  break;
173  }
174  }
175  Serial.println("\n------");
176  return rxBuffer[2];
177  }
178 
179  if (size == 8 && (rxBuffer[0] != current->slave || rxBuffer[2] != current->addr))
180  {
181  return OR_COMMAND_ERROR;
182  }
183  break;
184  }
185  }
186  }
187  return ERROR_OK;
188 }
189 short OmronPID::onResponse(short error)
190 {
192  if (!last || last->owner != id)
193  {
194  return E_SKIP;
195  }
196 
197  OmronState *state = pidBySlave(last->slave);
198  if (!state)
199  {
200  Log.warningln("Omron-PID :: invalid slave : %d", last->slave);
201  modbus->print();
202  return E_NO_SUCH_PID;
203  }
204 
205  if (last->fn == ku8MBWriteSingleRegister)
206  {
207  last->reset();
208  state->flags = OmronState::FLAGS::UPDATED;
209  state->lastWritten = now;
210  lastError = E_OK;
212  return E_OK;
213  }
214 
215  if (last->fn == ku8MBReadHoldingRegisters)
216  {
217  state->lastDT = now - state->lastUpdated;
218  state->lastUpdated = millis();
221  state->pv = modbus->ModbusSlaveRegisters[1];
222  state->sp = modbus->ModbusSlaveRegisters[5];
223  state->flags = OmronState::FLAGS::UPDATED;
224  state->state = state->isHeating() ? 1 : 0;
225  lastError = E_OK;
227  if (printPIDUpdates)
228  {
229  Log.verboseln("Omron-PID :: Updated Slave : %d : ", state->slaveID);
230  state->print();
231  }
232  queue.incr();
233  }
234  last->reset();
235  updateTCP();
236  return E_OK;
237 }
238 short OmronPID::onError(short error)
239 {
240  if (printMBErrors)
241  {
242  Log.verboseln("Omron PID :: onError %d : %d", error, readInterval);
243  }
245  if (last)
246  {
247  last->reset();
248  }
249  else
250  {
251  Log.errorln("Omron PID :: onError - can't find last query! ");
252  }
253  resetStates();
254 
255  // Modbus Errors
257  {
259  }
260 
261  lastError = error;
262 
263  readInterval = clamp<millis_t>(readInterval, 0, MB_MAX_POLL_INTERVAL);
265  {
266  owner->onError(id, E_PID_TIMEOUT);
267  }
268 
269  return E_OK;
270 }
272 {
273  millis_t t = now;
274  short ret = E_SKIP;
275  for (short i = 0; i < NB_OMRON_PIDS; i++)
276  {
277  switch (i)
278  {
279  case 0:
280  {
281  if (modbus->mb->R[MB_W_PID_1_SP] > 0)
282  {
283  short temp = clamp<short>(modbus->mb->R[MB_W_PID_1_SP], 0, OMRON_PID_MAX_TEMPERATURE);
285  modbus->mb->R[MB_W_PID_1_SP] = 0;
286  ret = E_QUEUED;
287  }
288  break;
289  }
290  case 1:
291  {
292 
293  if (modbus->mb->R[MB_W_PID_2_SP] > 0)
294  {
295  short temp = clamp<short>(modbus->mb->R[MB_W_PID_2_SP], 0, OMRON_PID_MAX_TEMPERATURE);
297  modbus->mb->R[MB_W_PID_2_SP] = 0;
298  ret = E_QUEUED;
299  }
300  break;
301  }
302  case 2:
303  {
304  if (modbus->mb->R[MB_W_PID_3_SP])
305  {
306  short temp = clamp<short>(modbus->mb->R[MB_W_PID_3_SP], 0, OMRON_PID_MAX_TEMPERATURE);
308  modbus->mb->R[MB_W_PID_3_SP] = 0;
309  ret = E_QUEUED;
310  }
311  break;
312  }
313  }
314  }
315  return ret;
316 }
318 {
319  for (int i = 0; i < NB_OMRON_PIDS; i++)
320  {
324  }
325 }
326 short OmronPID::queryResponse(short error)
327 {
329  if (last)
330  {
331  last->state = QUERY_STATE::DONE;
332  }
333  return E_OK;
334 }
336 {
337  for (short i = 0; i < NB_OMRON_PIDS; i++)
338  {
339  if (states[i].slaveID == slave)
340  {
341  return &states[i];
342  }
343  }
344  return NULL;
345 }
Query::value
short value
Definition: ModbusBridge.h:23
printPIDUpdates
bool printPIDUpdates
Definition: OmronPIDModbus.cpp:11
ModbusBridge::skipRead
bool skipRead(int slave, int fn, int addr, int num, int prio)
Definition: ModbusBridge.cpp:96
ku8MBWriteSingleRegister
#define ku8MBWriteSingleRegister
Modbus function 0x06 Write Single Register.
Definition: enums.h:105
OmronState
Definition: OmronPID.h:26
OmronState::statusLow
short statusLow
Definition: OmronPID.h:36
OmronState::flags
short flags
Definition: OmronPID.h:39
MB_REGISTER_OFFSET_TC
#define MB_REGISTER_OFFSET_TC
Definition: enums.h:182
ku8MBReadHoldingRegisters
#define ku8MBReadHoldingRegisters
Modbus function 0x03 Read Holding Registers.
Definition: enums.h:103
debugNextUpdates
bool debugNextUpdates
Definition: OmronPIDModbus.cpp:16
OmronPID.h
OmronState::sp
short sp
Definition: OmronPID.h:38
ModbusBridge::nextWaitingTime
int nextWaitingTime
Definition: ModbusBridge.h:165
OmronPID::modbusLoop
short modbusLoop()
Definition: OmronPIDModbus.cpp:69
OmronPID::modbus
ModbusBridge * modbus
Definition: OmronPID.h:171
printModbus
bool printModbus
Definition: OmronPIDModbus.cpp:10
PROCESSING
@ PROCESSING
Definition: enums.h:91
MB_MAX_POLL_INTERVAL
#define MB_MAX_POLL_INTERVAL
Definition: config_adv.h:29
OMRON_PID_MAX_TEMPERATURE
#define OMRON_PID_MAX_TEMPERATURE
Definition: config.h:101
MB_W_PID_3_SP
#define MB_W_PID_3_SP
Definition: enums.h:178
_debugQueryState
bool _debugQueryState
Definition: OmronPIDModbus.cpp:13
OmronPID::queryResponse
short queryResponse(short error)
Definition: OmronPIDModbus.cpp:326
ModbusBridge::query
short query(int slave, short function, long start, int coils, Component *_owner, ComponentFnPtr _responseFn)
Definition: ModbusBridge.cpp:316
OmronPID::nextToUpdate2
OmronState * nextToUpdate2()
Definition: OmronPIDModbus.cpp:26
OmronPID::updateState
void updateState()
Definition: OmronPIDModbus.cpp:55
OmronState::pv
short pv
Definition: OmronPID.h:37
OmronPID::fromTCP
short fromTCP()
Definition: OmronPIDModbus.cpp:271
ModbusBridge::print
void print()
Definition: ModbusBridge.cpp:273
OR_E5_SWR_SP
@ OR_E5_SWR_SP
Definition: OmronE5.h:162
OmronPID::onRawResponse
short onRawResponse(short size, uint8_t rxBuffer[])
Definition: OmronPIDModbus.cpp:138
Query::ts
millis_t ts
Definition: ModbusBridge.h:29
IDLE
@ IDLE
Definition: enums.h:83
ModbusBridge::ModbusSlaveRegisters
uint16_t ModbusSlaveRegisters[8]
Definition: ModbusBridge.h:131
OmronPID::readInterval
millis_t readInterval
Definition: OmronPID.h:190
VARIABLE_OPERATION_ERROR
@ VARIABLE_OPERATION_ERROR
Definition: OmronE5.h:345
OmronPID::lastError
short lastError
Definition: OmronPID.h:174
OmronState::slaveID
short slaveID
Definition: OmronPID.h:40
ERR_MODBUS_TIMEOUT
#define ERR_MODBUS_TIMEOUT
Definition: enums.h:133
OmronPID::pidBySlave
OmronState * pidBySlave(int slave)
Definition: OmronPIDModbus.cpp:335
OmronPID::queue
ShiftRegister< uchar, E_PID_MB_M_QUEUE_LENGTH > queue
Definition: OmronPID.h:195
OR_E_MSG_OPERATION_ERROR
#define OR_E_MSG_OPERATION_ERROR
Definition: OmronE5.h:358
debugRawResponse
bool debugRawResponse
Definition: OmronPIDModbus.cpp:15
ModbusBridge::mb
Mudbus * mb
Definition: ModbusBridge.h:166
OmronPID::singlePID
int singlePID(int slave, short fn, int addr, int value)
Definition: OmronPID.cpp:70
OmronState::lastUpdated
millis_t lastUpdated
Definition: OmronPID.h:44
ModbusBridge::nextQueryByState
Query * nextQueryByState(uchar state=DONE, int owner=-1)
Definition: ModbusBridge.cpp:138
utils.h
OmronE5.h
OR_E_MSG_INVALID_ADDRESS
#define OR_E_MSG_INVALID_ADDRESS
Definition: OmronE5.h:356
NB_OMRON_PIDS
#define NB_OMRON_PIDS
Definition: config.h:97
MB_QUERY_TYPE_STATUS_POLL
#define MB_QUERY_TYPE_STATUS_POLL
Definition: config_adv.h:17
ModbusBridge.h
Query::reset
void reset()
Definition: ModbusBridge.h:94
MODBUS_CMD_WAIT
#define MODBUS_CMD_WAIT
Definition: config_adv.h:8
Query::print
void print()
Definition: ModbusBridge.h:55
OR_E_MSG_INVALID_RANGE
#define OR_E_MSG_INVALID_RANGE
Definition: OmronE5.h:357
OmronState::lastDT
short lastDT
Definition: OmronPID.h:42
OmronState::state
short state
Definition: OmronPID.h:47
Query::addr
long addr
Definition: ModbusBridge.h:22
OmronState::print
void print()
Definition: OmronPID.h:83
OR_COMMAND_ERROR
@ OR_COMMAND_ERROR
Definition: OmronE5.h:353
OmronPID::nextToUpdate
OmronState * nextToUpdate()
Definition: OmronPIDModbus.cpp:29
ERROR_OK
@ ERROR_OK
Definition: enums.h:73
OMRON_PID_UPDATE_INTERVAL
#define OMRON_PID_UPDATE_INTERVAL
Definition: config.h:99
OmronPID::onError
short onError(short error)
Definition: OmronPIDModbus.cpp:238
E_QUEUED
#define E_QUEUED
Definition: enums.h:13
DONE
@ DONE
Definition: enums.h:94
_debugQuery
bool _debugQuery
Definition: OmronPIDModbus.cpp:12
VARIABLE_RANGE_ERROR
@ VARIABLE_RANGE_ERROR
Definition: OmronE5.h:344
ModbusBridge::nextQueryByState2
Query * nextQueryByState2(uchar state, int owner)
Definition: ModbusBridge.cpp:76
QUEUED
@ QUEUED
Definition: enums.h:90
OmronPID::read10_16
short read10_16(int slaveAddress, int addr, int prio)
Definition: OmronPIDModbus.cpp:116
debugResponse
bool debugResponse
Definition: OmronPIDModbus.cpp:14
Query::prio
int prio
Definition: ModbusBridge.h:27
E_NO_SUCH_PID
#define E_NO_SUCH_PID
Definition: enums.h:15
Query::state
short state
Definition: ModbusBridge.h:24
printMBErrors
bool printMBErrors
Definition: OmronPIDModbus.cpp:17
OmronPID::d0TS
millis_t d0TS
Definition: OmronPID.h:192
OmronPID::resetStates
void resetStates()
Definition: OmronPID.cpp:158
E_OK
#define E_OK
Definition: enums.h:11
MB_REGISTER_OFFSET_TC_RANGE
#define MB_REGISTER_OFFSET_TC_RANGE
Definition: enums.h:183
enums.h
OMRON_PID_READ_STATUS_REGISTERS
#define OMRON_PID_READ_STATUS_REGISTERS
Definition: config.h:102
MB_W_PID_2_SP
#define MB_W_PID_2_SP
Definition: enums.h:177
OmronPID::updateTCP
void updateTCP()
Definition: OmronPIDModbus.cpp:317
config.h
Query
Definition: ModbusBridge.h:18
MB_POLL_RETRY_STEP
#define MB_POLL_RETRY_STEP
Definition: config_adv.h:31
OmronPID::onResponse
short onResponse(short error)
Definition: OmronPIDModbus.cpp:189
Query::owner
short owner
Definition: ModbusBridge.h:28
E_SKIP
#define E_SKIP
Definition: enums.h:12
VARIABLE_ADDRESS_ERROR
@ VARIABLE_ADDRESS_ERROR
Definition: OmronE5.h:343
Query::fn
short fn
Definition: ModbusBridge.h:25
MB_W_PID_1_SP
#define MB_W_PID_1_SP
Definition: enums.h:176
OmronState::statusHigh
short statusHigh
Definition: OmronPID.h:35
ModbusBridge::qstate
short qstate()
Definition: ModbusBridge.cpp:304
OmronState::isHeating
bool isHeating()
Definition: OmronPID.h:69
OmronPID::states
OmronState states[NB_OMRON_PIDS]
Definition: OmronPID.h:170
E_PID_TIMEOUT
#define E_PID_TIMEOUT
Definition: enums.h:33
OmronState::lastWritten
millis_t lastWritten
Definition: OmronPID.h:45
Query::slave
short slave
Definition: ModbusBridge.h:21