Lydia - Printhead
OmronVFDModbus.cpp
Go to the documentation of this file.
1 #ifdef MB_MONITORING_STATUS_VFD_MAX_LOAD
2 #include <xstatistics.h>
3 #endif
4 
5 #include <SRegister.h>
6 #include "./OmronVFD.h"
7 #include "./ModbusBridge.h"
8 #include "./OmronMX2.h"
9 
10 #include "PHApp.h"
11 #include "enums.h"
12 #include "utils.h"
13 
14 bool didTest = true;
15 bool debugReceive = false;
16 bool debugSend = false;
17 bool debugFilter = false;
18 bool debugMultiRegs = false;
19 bool debugModQueries = false;
20 bool printModbusErrors = true;
21 bool debugStateUpdate = false;
22 bool debugSkipping = true;
23 
25 {
26  if (now - mbTS > mbInterval)
27  {
28  OmronVFDState *state = getVFDState();
29  short req = state->queue.val();
30  bool queued = false;
31  switch (req)
32  {
34  {
36  break;
37  }
38  case E_VFD_MB_QUEUE_DIR:
39  {
40  queued = read_coil_single(MX2_C_DIR - 1) == E_QUEUED;
41  break;
42  }
44  {
46  break;
47  }
48  }
49  mbTS = now;
50  return queued ? E_QUEUED : E_OK;
51  }
52  return E_SKIP;
53 }
55 {
56 
57  if (millis() - last < OMRON_MX2_LOOP_INTERVAL)
58  {
59  return E_SKIP;
60  }
61  if (modbus->qstate() != IDLE)
62  {
63  return E_SKIP;
64  }
65 
66  last = now;
67  updateState();
68  fromTCP();
70  if (!nextCommand)
71  {
72  return E_SKIP;
73  }
74  nextCommand->state = QUERY_STATE::PROCESSING;
75  nextCommand->ts = now;
77  if (debugSend)
78  {
80  {
81  debugTS = now;
82  nextCommand->print();
83  Serial.println();
84  }
85  }
86 
87  modbus->query(
88  nextCommand->slave,
89  nextCommand->fn,
90  nextCommand->addr,
91  nextCommand->value,
92  id);
93 }
94 short OmronVFD::onResponse(short error)
95 {
97  if (!last || last->slave != slaveAddress || last->owner != id)
98  {
99  return E_SKIP;
100  }
101  OmronVFDState *state = getVFDState();
102  short req = state->queue.val();
103 
104  switch (req)
105  {
107  {
108  states[0].FC = modbus->ModbusSlaveRegisters[0] / 100;
112  lastError = E_OK;
113  state->queue.incr();
114  break;
115  }/*
116  case E_VFD_MB_QUEUE_DIR:
117  {
118  states[0].direction = modbus->ModbusSlaveRegisters[0];
119  readInterval = OMRON_MX2_MB_INTERVAL;
120  lastError = E_OK;
121  state->queue.incr();
122  break;
123  }*/
124  case E_VFD_MB_QUEUE_AMPS:
125  {
128  lastError = E_OK;
129  state->queue.incr();
130  break;
131  }
132  }
133 
135  {
136  last->print();
137  modbus->print();
139  lastError = E_OK;
140  }
141  last->reset();
142  updateTCP();
143  return E_OK;
144 }
145 short OmronVFD::onError(short error)
146 {
147  // 01 : 86 : 21 : 82 : 78
148  if (printModbusErrors)
149  {
150  Log.verboseln("Omron VFD onError : %d : %d", error, readInterval);
151  }
153  {
155  }
156 
157  lastError = error;
158  readInterval = clamp<millis_t>(readInterval, 0, MB_MAX_POLL_INTERVAL);
160  {
162  }
163  // App Level Errors
164  if (error > E_VFD_CUSTOM)
165  {
166  switch (error)
167  {
168  case E_VFD_OVERLOAD:
169  lastError = error;
170  Log.verboseln("Omron VFD :: Overload Error ! %d", error);
171  owner->onError(id, error);
172  break;
173 
174  default:
175  break;
176  }
177  return error;
178  }
179 
181  if (last)
182  {
183  last->reset();
184  }
185  return E_OK;
186 }
187 short OmronVFD::onRawResponse(short size, uint8_t rxBuffer[])
188 {
189  if (!size)
190  {
191  Log.verboseln("OmronVFD::rawResponse - Invalid Size : %d", size);
192  return E_OK;
193  }
194  if (debugReceive)
195  {
196  // Log.verboseln("OmronVFD::rawResponse - Size : %d", size);
197  // printHex(rxBuffer, size);
198  }
199  if (size == 5)
200  {
201  Log.verboseln("Error - Modbus, invalid response size : %d", size);
202  }
203  return ERROR_OK;
204 }
206 {
207  Query *next = modbus->nextQueryByState(DONE);
208  if (next)
209  {
211  next->slave = slaveAddress;
212  next->value = 1234;
213  next->addr = 0;
214  next->state = QUERY_STATE::QUEUED;
215  next->ts = millis();
216  return E_OK;
217  }
218  return E_QUERY_BUFFER_END;
219 }
221 {
223  modbus->mb->R[MB_R_VFD_STATE] = states[0].state;
224  // modbus->mb->R[MB_R_VFD_DIRECTION] = states[0].direction;
225  modbus->mb->R[MB_R_FREQ_TARGET] = states[0].FC;
226 #ifdef MB_MONITORING_STATUS_VFD_MAX_LOAD
230  // modbus->mb->R[75] = states[0].status2;
231  // modbus->mb->R[76] = states[0].status3;
232 #endif
233  // fromTCP();
234 }
236 {
237  if (modbus->mb->R[9] == 1)
238  {
239  modbus->mb->R[9] = 0;
240  modbus->print();
241  }
242 
243  short ret = E_SKIP;
244  if (!directDirection())
245  {
246  if (modbus->mb->R[MB_W_VFD_RUN] == E_VFD_RUN_MODE::E_VFD_RUN_MODE_RUN)
247  {
248  onStart();
249  write_Bit(MX2_START, 1);
250  modbus->mb->R[MB_W_VFD_RUN] = 0;
251  runMode = E_VFD_RUN_MODE::E_VFD_RUN_MODE_RUN;
252  ret = E_QUEUED;
253  }
254 
255  if (modbus->mb->R[MB_W_VFD_RUN] == E_VFD_RUN_MODE::E_VFD_RUN_MODE_STOP)
256  {
257  onStop();
258  write_Bit(MX2_START, 0);
259  owner->onStop(0);
260  modbus->mb->R[MB_W_VFD_RUN] = 0;
261  runMode = E_VFD_RUN_MODE::E_VFD_RUN_MODE_STOP;
262  ret = E_QUEUED;
263  }
264 
265  if (modbus->mb->R[MB_W_VFD_RUN] == E_VFD_RUN_MODE::E_VFD_RUN_MODE_STOP_RETRACT)
266  {
267  onStop();
268  write_Bit(MX2_START, 0);
269  owner->onStop(0);
270  modbus->mb->R[MB_W_VFD_RUN] = 0;
271  runMode = E_VFD_RUN_MODE::E_VFD_RUN_MODE_STOP_RETRACT;
272  retractState = E_VFD_RETRACT_STATE::E_VFD_RETRACT_STATE_BRAKING;
273  ret = E_QUEUED;
274  }
275 
276  short dir = modbus->mb->R[MB_W_DIRECTION];
277  if (dir)
278  {
279  switch (dir)
280  {
281  case OmronVFD::E_VFD_DIR::E_VFD_DIR_FORWARD:
282  forward();
283  ret = E_QUEUED;
284  break;
285  case OmronVFD::E_VFD_DIR::E_VFD_DIR_REVERSE:
286  reverse();
287  ret = E_QUEUED;
288  break;
289  default:
290  stop();
291  ret = E_QUEUED;
292  break;
293  }
294  modbus->mb->R[MB_W_DIRECTION] = 0;
295  }
296  }
297  if (modbus->mb->R[MB_W_FREQ_TARGET] > 0)
298  {
300  modbus->mb->R[MB_W_FREQ_TARGET] = 0;
301  ret = E_QUEUED;
302  }
303  return ret;
304 }
305 uint16_t OmronVFD::write_Single(uint16_t addr, unsigned int data)
306 {
307  Query *next = modbus->nextQueryByState(DONE);
308  if (next)
309  {
311  next->slave = slaveAddress;
312  next->value = data;
313  next->addr = addr;
314  next->state = QUERY_STATE::QUEUED;
315  next->ts = millis();
316  next->owner = id;
317  next->prio = MB_QUERY_TYPE_CMD;
318  lastWriteAddress = addr;
319  lastWriteValue = data;
320  return E_QUEUED;
321  }
322  return E_SKIP;
323 }
324 uint16_t OmronVFD::read_coil_single(uint16_t addr)
325 {
326  Query *next = modbus->nextQueryByState(DONE);
327  if (next)
328  {
329  next->fn = ku8MBReadCoils;
330  next->slave = slaveAddress;
331  next->value = 1;
332  next->addr = addr;
333  next->state = QUERY_STATE::QUEUED;
334  next->ts = millis();
335  next->owner = id;
337  return E_QUEUED;
338  }
339  return E_SKIP;
340 }
341 uint16_t OmronVFD::write_Bit(uint16_t addr, int on)
342 {
344  if (same && millis() - same->ts < 300)
345  {
346  }
347 
348  Query *next = modbus->nextQueryByState(DONE);
349  if (next)
350  {
351  next->fn = ku8MBWriteSingleCoil;
352  next->slave = slaveAddress;
353  next->addr = addr;
354  next->value = on;
355  next->state = QUERY_STATE::QUEUED;
356  next->ts = millis();
357  next->owner = id;
358  next->prio = MB_QUERY_TYPE_CMD;
359  lastWriteAddress = addr;
360  lastWriteValue = on;
361  return E_OK;
362  }
363  return E_QUERY_BUFFER_END;
364 }
365 short OmronVFD::readSingle_16(int addr, int prio)
366 {
367  if (skipRead(slaveAddress, ku8MBReadHoldingRegisters, addr, 1, prio))
368  {
369  return E_SKIP;
370  }
371  Query *next = modbus->nextQueryByState(DONE);
372  if (next)
373  {
375  next->slave = slaveAddress;
376  next->value = 1;
377  next->addr = addr;
378  next->state = QUERY_STATE::QUEUED;
379  next->ts = millis();
380  next->prio = prio;
381  next->owner = id;
382  return E_QUEUED;
383  }
384  return E_SKIP;
385 }
386 short OmronVFD::read_16(int addr, int num, int prio)
387 {
388  if (skipRead(slaveAddress, ku8MBReadHoldingRegisters, addr, num, prio))
389  {
390  return E_SKIP;
391  }
392 
393  Query *next = modbus->nextQueryByState(DONE);
394  if (next)
395  {
397  next->slave = slaveAddress;
398  next->value = num;
399  next->addr = addr;
400  next->state = QUERY_STATE::QUEUED;
401  next->ts = millis();
402  next->prio = prio;
403  next->owner = id;
404  return E_QUEUED;
405  }
406  return E_SKIP;
407 }
408 bool OmronVFD::skipRead(int slave, int fn, int addr, int num, int prio)
409 {
410  Query *same = modbus->nextSame(QUEUED, slave, addr, fn, num);
411  if (same && millis() - same->ts < OMRON_MX2_SAME_REQUEST_INTERVAL)
412  {
413  return true;
414  }
415 
417  {
418  return true;
419  }
420 
421  if (modbus->numSame(QUEUED, slave, addr, fn, num) >= 1)
422  {
423  return true;
424  }
425 
426  if (modbus->numSame(PROCESSING, slave, addr, fn, num) >= 1)
427  {
428  return true;
429  }
430  return false;
431 }
OmronVFD::write_Single
uint16_t write_Single(uint16_t cmd, unsigned int data)
Definition: OmronVFDModbus.cpp:305
Query::value
short value
Definition: ModbusBridge.h:23
MB_MONITORING_STATUS_VFD_MAX_LOAD
#define MB_MONITORING_STATUS_VFD_MAX_LOAD
Definition: enums.h:260
ku8MBWriteSingleRegister
#define ku8MBWriteSingleRegister
Modbus function 0x06 Write Single Register.
Definition: enums.h:105
E_VFD_MB_QUEUE_STATUS
#define E_VFD_MB_QUEUE_STATUS
Definition: OmronVFD.h:22
OmronVFD::updateTCP
void updateTCP()
Definition: OmronVFDModbus.cpp:220
OmronVFD::directDirection
short directDirection()
Definition: OmronVFD.cpp:107
OmronVFDState::current
uint16_t current
Definition: OmronVFD.h:62
OmronVFD::runMode
E_VFD_RUN_MODE runMode
Definition: OmronVFD.h:226
ku8MBReadHoldingRegisters
#define ku8MBReadHoldingRegisters
Modbus function 0x03 Read Holding Registers.
Definition: enums.h:103
OmronVFD::readInterval
millis_t readInterval
Definition: OmronVFD.h:220
OMRON_MX2_LOOP_INTERVAL
#define OMRON_MX2_LOOP_INTERVAL
Definition: config.h:112
OmronVFD::mbInterval
millis_t mbInterval
Definition: OmronVFD.h:221
ModbusBridge::nextWaitingTime
int nextWaitingTime
Definition: ModbusBridge.h:165
PROCESSING
@ PROCESSING
Definition: enums.h:91
OmronVFD::skipRead
bool skipRead(int slave, int fn, int addr, int num, int prio)
Definition: OmronVFDModbus.cpp:408
MB_MAX_POLL_INTERVAL
#define MB_MAX_POLL_INTERVAL
Definition: config_adv.h:29
ku8MBReadCoils
#define ku8MBReadCoils
Modbus function 0x01 Read Coils.
Definition: enums.h:97
MB_W_VFD_RUN
#define MB_W_VFD_RUN
Definition: enums.h:150
OMRON_MX2_SAME_REQUEST_INTERVAL
#define OMRON_MX2_SAME_REQUEST_INTERVAL
Definition: config.h:113
OMRON_MX2_DEBUG_INTERVAL
#define OMRON_MX2_DEBUG_INTERVAL
Definition: config.h:111
OmronVFD::mbTS
millis_t mbTS
Definition: OmronVFD.h:188
E_VFD_MB_QUEUE_DIR
#define E_VFD_MB_QUEUE_DIR
Definition: OmronVFD.h:23
OmronVFD::stop
uint16_t stop()
Definition: OmronVFD.cpp:76
ModbusBridge::numByState
int numByState(int state=DONE)
Definition: ModbusBridge.cpp:261
OmronVFDState::FC
uint16_t FC
Definition: OmronVFD.h:60
ku8MBWriteSingleCoil
#define ku8MBWriteSingleCoil
Modbus function 0x05 Write Single Coil.
Definition: enums.h:99
E_VFD_MB_QUEUE_AMPS
#define E_VFD_MB_QUEUE_AMPS
Definition: OmronVFD.h:24
ModbusBridge::query
short query(int slave, short function, long start, int coils, Component *_owner, ComponentFnPtr _responseFn)
Definition: ModbusBridge.cpp:316
OmronMX2.h
OmronVFD::modbus
ModbusBridge * modbus
Definition: OmronVFD.h:210
OmronVFD::retractState
E_VFD_RETRACT_STATE retractState
Definition: OmronVFD.h:227
MB_R_VFD_STATUS
#define MB_R_VFD_STATUS
Definition: enums.h:145
debugModQueries
bool debugModQueries
Definition: OmronVFDModbus.cpp:19
E_VFD_OVERLOAD
#define E_VFD_OVERLOAD
Definition: enums.h:27
ModbusBridge::print
void print()
Definition: ModbusBridge.cpp:273
E_VFD_CUSTOM
#define E_VFD_CUSTOM
Definition: enums.h:24
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
OmronVFD::lastError
short lastError
Definition: OmronVFD.h:219
OmronVFD::modbusLoop
short modbusLoop()
Definition: OmronVFDModbus.cpp:54
OmronVFD::forward
uint16_t forward()
Definition: OmronVFD.cpp:92
debugFilter
bool debugFilter
Definition: OmronVFDModbus.cpp:17
OmronVFD::onRawResponse
short onRawResponse(short size, uint8_t rxBuffer[])
Definition: OmronVFDModbus.cpp:187
debugSend
bool debugSend
Definition: OmronVFDModbus.cpp:16
ERR_MODBUS_TIMEOUT
#define ERR_MODBUS_TIMEOUT
Definition: enums.h:133
MB_MONITORING_STATUS_VFD_CURRENT
#define MB_MONITORING_STATUS_VFD_CURRENT
Definition: enums.h:265
MB_MONITORING_STATUS_VFD_RUN_MODE
#define MB_MONITORING_STATUS_VFD_RUN_MODE
Definition: enums.h:264
ModbusBridge::nextSame
Query * nextSame(uchar state, short slave, int addr, short fn, int value)
Definition: ModbusBridge.cpp:206
OmronVFD::dir
Pos3Analog * dir
Definition: OmronVFD.h:197
debugSkipping
bool debugSkipping
Definition: OmronVFDModbus.cpp:22
ModbusBridge::mb
Mudbus * mb
Definition: ModbusBridge.h:166
MX2_C_DIR
#define MX2_C_DIR
Definition: OmronMX2.h:5
OmronVFD::lastWriteAddress
uint16_t lastWriteAddress
Definition: OmronVFD.h:230
MB_QUERY_TYPE_STATUS_POLL_2
#define MB_QUERY_TYPE_STATUS_POLL_2
Definition: config_adv.h:19
OmronVFDState::status
int16_t status
Definition: OmronVFD.h:66
ModbusBridge::nextQueryByState
Query * nextQueryByState(uchar state=DONE, int owner=-1)
Definition: ModbusBridge.cpp:138
E_VFD_TIMEOUT
#define E_VFD_TIMEOUT
Definition: enums.h:28
utils.h
OmronVFD::readSingle_16
short readSingle_16(int addr, int prio=0)
Definition: OmronVFDModbus.cpp:365
OmronVFD::read_coil_single
uint16_t read_coil_single(uint16_t addr)
Definition: OmronVFDModbus.cpp:324
MB_W_DIRECTION
#define MB_W_DIRECTION
Definition: enums.h:152
MB_QUERY_TYPE_STATUS_POLL
#define MB_QUERY_TYPE_STATUS_POLL
Definition: config_adv.h:17
OmronVFD::owner
PHApp * owner
Definition: OmronVFD.h:200
OmronVFDState
Definition: OmronVFD.h:29
OmronVFD::fromTCP
short fromTCP()
Definition: OmronVFDModbus.cpp:235
OmronVFD::last
millis_t last
Definition: OmronVFD.h:186
OmronVFDState::state
int16_t state
Definition: OmronVFD.h:65
ku8MBLinkTestOmronMX2Only
#define ku8MBLinkTestOmronMX2Only
Modbus function 0x08 Test.
Definition: enums.h:109
ModbusBridge.h
OmronVFD::lastWriteValue
uint16_t lastWriteValue
Definition: OmronVFD.h:231
MX2_START
#define MX2_START
Definition: OmronMX2.h:85
OmronVFD::getVFDState
OmronVFDState * getVFDState()
Definition: OmronVFD.h:201
OmronVFD::setTargetFreq
uint16_t setTargetFreq(uint16_t freq)
Definition: OmronVFD.cpp:97
MODBUS_CMD_WAIT
#define MODBUS_CMD_WAIT
Definition: config_adv.h:8
MB_QUERY_TYPE_CMD
#define MB_QUERY_TYPE_CMD
Definition: config_adv.h:21
Query::print
void print()
Definition: ModbusBridge.h:55
PHApp::onError
short onError(short id, short code)
Definition: PHApp.cpp:278
debugMultiRegs
bool debugMultiRegs
Definition: OmronVFDModbus.cpp:18
Query::addr
long addr
Definition: ModbusBridge.h:22
OmronVFDState::max_current
int8_t max_current
Definition: OmronVFD.h:63
MX2_R_TORQUE
#define MX2_R_TORQUE
Definition: OmronMX2.h:8
ModbusBridge::numSame
int numSame(uchar state, short slave, int addr, short fn, int value)
Definition: ModbusBridge.cpp:229
OMRON_STATUS_POLL_REGISTERS
#define OMRON_STATUS_POLL_REGISTERS
Definition: enums.h:281
ERROR_OK
@ ERROR_OK
Definition: enums.h:73
E_QUEUED
#define E_QUEUED
Definition: enums.h:13
OmronVFD::onStop
short onStop()
Definition: OmronVFD.cpp:49
OmronVFD::debugTS
millis_t debugTS
Definition: OmronVFD.h:189
OmronVFD::read_16
short read_16(int addr, int num, int prio=0)
Definition: OmronVFDModbus.cpp:386
MB_R_FREQ_TARGET
#define MB_R_FREQ_TARGET
Definition: enums.h:143
DONE
@ DONE
Definition: enums.h:94
OmronVFDState::queue
ShiftRegister< uchar, E_VFD_MB_QUEUE_LENGTH > queue
Definition: OmronVFD.h:74
ModbusBridge::nextQueryByState2
Query * nextQueryByState2(uchar state, int owner)
Definition: ModbusBridge.cpp:76
QUEUED
@ QUEUED
Definition: enums.h:90
didTest
bool didTest
Definition: OmronVFDModbus.cpp:14
Query::prio
int prio
Definition: ModbusBridge.h:27
OmronVFD::reverse
uint16_t reverse()
Definition: OmronVFD.cpp:87
Query::state
short state
Definition: ModbusBridge.h:24
OmronVFD::onError
short onError(short error)
Definition: OmronVFDModbus.cpp:145
debugReceive
bool debugReceive
Definition: OmronVFDModbus.cpp:15
E_OK
#define E_OK
Definition: enums.h:11
printModbusErrors
bool printModbusErrors
Definition: OmronVFDModbus.cpp:20
OmronVFD.h
PHApp::onStop
short onStop(short code=0)
Definition: PHApp.cpp:312
enums.h
MODBUS_QUEUE_MIN_FREE
#define MODBUS_QUEUE_MIN_FREE
Definition: config.h:91
OMRON_MX2_MB_INTERVAL
#define OMRON_MX2_MB_INTERVAL
Definition: config.h:110
OmronVFD::updateState
uint16_t updateState()
Definition: OmronVFDModbus.cpp:24
Query
Definition: ModbusBridge.h:18
PHApp.h
MB_R_VFD_STATE
#define MB_R_VFD_STATE
Definition: enums.h:146
MB_POLL_RETRY_STEP
#define MB_POLL_RETRY_STEP
Definition: config_adv.h:31
Query::owner
short owner
Definition: ModbusBridge.h:28
debugStateUpdate
bool debugStateUpdate
Definition: OmronVFDModbus.cpp:21
E_SKIP
#define E_SKIP
Definition: enums.h:12
OmronVFD::write_Bit
uint16_t write_Bit(uint16_t addr, int on)
Definition: OmronVFDModbus.cpp:341
OmronVFD::slaveAddress
short slaveAddress
Definition: OmronVFD.h:211
Query::fn
short fn
Definition: ModbusBridge.h:25
E_QUERY_BUFFER_END
#define E_QUERY_BUFFER_END
Definition: enums.h:16
ModbusBridge::qstate
short qstate()
Definition: ModbusBridge.cpp:304
OmronVFD::onResponse
short onResponse(short error)
Definition: OmronVFDModbus.cpp:94
OmronVFD::ping
short ping()
Definition: OmronVFDModbus.cpp:205
OmronVFD::states
OmronVFDState states[1]
Definition: OmronVFD.h:212
MB_W_FREQ_TARGET
#define MB_W_FREQ_TARGET
Definition: enums.h:151
OmronVFD::onStart
short onStart()
Definition: OmronVFD.cpp:30
Query::slave
short slave
Definition: ModbusBridge.h:21