@@ -27,6 +27,7 @@ extern "C" {
27
27
#include " ModbusT1SServer.h"
28
28
29
29
size_t const UDP_RX_MSG_BUF_SIZE = 16 + 1 ;
30
+ RS485Class serial485 (RS485_SERIAL, RS485_TX_PIN, RS485_DE_PIN, RS485_RE_PIN);
30
31
31
32
/* *
32
33
* @class ModbusT1SServerClass
@@ -108,10 +109,72 @@ int ModbusT1SServerClass::begin(RS485Class& rs485, unsigned long baudrate, uint1
108
109
{
109
110
_rs485 = &rs485;
110
111
if (!ModbusRTUClient.begin (rs485, baudrate, config)) {
111
- return -1 ;
112
+ return 0 ;
113
+ }
114
+ return 1 ;
115
+ }
116
+
117
+
118
+ int ModbusT1SServerClass::begin (int node_id)
119
+ {
120
+ _node_id = node_id;
121
+ pinMode (IRQ_PIN, INPUT_PULLUP);
122
+ attachInterrupt (digitalPinToInterrupt (IRQ_PIN),
123
+
124
+ []() {
125
+ tc6_io->onInterrupt ();
126
+ },
127
+ FALLING);
128
+
129
+ /* Initialize IO module. */
130
+ if (!tc6_io->begin ())
131
+ {
132
+ return 0 ;
133
+ }
134
+
135
+ IPAddress ip_addr = IPAddress (192 , 168 , 42 , 100 + _node_id);
136
+ IPAddress network_mask = IPAddress (255 , 255 , 255 , 0 );
137
+ IPAddress gateway = IPAddress (192 , 168 , 42 , 100 );
138
+
139
+ T1SPlcaSettings t1s_plca_settings {
140
+ _node_id
141
+ };
142
+ T1SMacSettings const t1s_default_mac_settings;
143
+ MacAddress const mac_addr = MacAddress::create_from_uid ();
144
+
145
+ if (!tc6_inst->begin (ip_addr
146
+ , network_mask
147
+ , gateway
148
+ , mac_addr
149
+ , t1s_plca_settings
150
+ , t1s_default_mac_settings))
151
+ {
152
+ return 0 ;
153
+ }
154
+
155
+ Serial.print (" IP\t " );
156
+ Serial.println (ip_addr);
157
+ Serial.println (mac_addr);
158
+ Serial.println (t1s_plca_settings);
159
+ Serial.println (t1s_default_mac_settings);
160
+
161
+ if (!_server->begin (udp_port))
162
+ {
163
+ return 0 ;
164
+ }
165
+
166
+ float MODBUS_BIT_DURATION = 1 .f / _baudrate;
167
+ float MODBUS_PRE_DELAY_BR = MODBUS_BIT_DURATION * 9 .6f * 3 .5f * 1e6 ;
168
+ float MODBUS_POST_DELAY_BR = MODBUS_BIT_DURATION * 9 .6f * 3 .5f * 1e6 ;
169
+
170
+ serial485.setDelays (MODBUS_PRE_DELAY_BR, MODBUS_POST_DELAY_BR);
171
+
172
+ if (!ModbusRTUClient.begin (serial485, (unsigned long ) _baudrate, (uint16_t ) SERIAL_8N1)) {
173
+ return 0 ;
112
174
}
113
175
114
176
ModbusRTUClient.setTimeout (2 *1000UL );
177
+
115
178
return 1 ;
116
179
}
117
180
@@ -250,7 +313,6 @@ long ModbusT1SServerClass::inputRegisterRead(int address)
250
313
if (_server == nullptr ) {
251
314
return res;
252
315
}
253
-
254
316
int modbus_id = udp_rx_buf.at (2 ) << 8 | udp_rx_buf.at (3 );
255
317
int address_mod = udp_rx_buf.at (4 ) << 8 | udp_rx_buf.at (5 );
256
318
if (address != -1 ) {
@@ -371,6 +433,67 @@ int ModbusT1SServerClass::parsePacket() {
371
433
return res;
372
434
}
373
435
436
+ void ModbusT1SServerClass::checkPLCAStatus ()
437
+ {
438
+ tc6_inst->service ();
439
+
440
+ static unsigned long prev_beacon_check = 0 ;
441
+ static unsigned long prev_udp_packet_sent = 0 ;
442
+
443
+ auto const now = millis ();
444
+
445
+ if ((now - prev_beacon_check) > 1000 )
446
+ {
447
+ prev_beacon_check = now;
448
+ if (callback == nullptr )
449
+ {
450
+ if (!tc6_inst->getPlcaStatus (OnPlcaStatus_server)) {
451
+ Serial.println (" getPlcaStatus(...) failed" );
452
+ }
453
+ } else {
454
+ if (!tc6_inst->getPlcaStatus (callback)) {
455
+ Serial.println (" getPlcaStatus(...) failed" );
456
+ }
457
+ }
458
+ }
459
+ }
460
+
461
+ void ModbusT1SServerClass::update () {
462
+ /* Services the hardware and the protocol stack.
463
+ Must be called cyclic. The faster the better.
464
+ */
465
+ checkPLCAStatus ();
466
+ switch (ModbusT1SServer.parsePacket ())
467
+ {
468
+ case UDP_READ_COIL_PORT:
469
+ ModbusT1SServer.coilRead ();
470
+ break ;
471
+
472
+ case UDP_WRITE_COIL_PORT:
473
+ ModbusT1SServer.coilWrite ();
474
+ break ;
475
+
476
+ case UDP_READ_DI_PORT:
477
+ discreteInputRead ();
478
+ break ;
479
+
480
+ case UDP_READ_IR_PORT:
481
+ inputRegisterRead ();
482
+ break ;
483
+
484
+ case UDP_READ_HR_PORT:
485
+ holdingRegisterRead ();
486
+ break ;
487
+
488
+ case UDP_WRITE_HR_PORT:
489
+ holdingRegisterWrite ();
490
+ break ;
491
+
492
+ default :
493
+ break ;
494
+ }
495
+ }
496
+
374
497
/* *
375
498
* Sets the Arduino_10BASE_T1S_UDP server for communication.
376
499
*
@@ -382,5 +505,35 @@ void ModbusT1SServerClass::setT1SServer(Arduino_10BASE_T1S_UDP * server) {
382
505
_server = server;
383
506
}
384
507
508
+
509
+ void ModbusT1SServerClass::setT1SPort (int port) {
510
+ udp_port = port;
511
+ }
512
+ void ModbusT1SServerClass::setBadrate (int baudrate) {
513
+ _baudrate = baudrate;
514
+ }
515
+
516
+ void ModbusT1SServerClass::setCallback (callback_f cb) {
517
+ if (cb != nullptr ) {
518
+ callback = cb;
519
+ }
520
+ }
521
+
522
+ static void OnPlcaStatus_server (bool success, bool plcaStatus)
523
+ {
524
+ if (!success)
525
+ {
526
+ Serial.println (" PLCA status register read failed" );
527
+ return ;
528
+ }
529
+
530
+ if (plcaStatus) {
531
+ Serial.println (" PLCA Mode active" );
532
+ } else {
533
+ Serial.println (" CSMA/CD fallback" );
534
+ tc6_inst->enablePlca ();
535
+ }
536
+ }
537
+
385
538
ModbusT1SServerClass ModbusT1SServer;
386
539
#endif
0 commit comments