@@ -27,6 +27,7 @@ extern "C" {
2727#include " ModbusT1SServer.h"
2828
2929size_t const UDP_RX_MSG_BUF_SIZE = 16 + 1 ;
30+ RS485Class serial485 (RS485_SERIAL, RS485_TX_PIN, RS485_DE_PIN, RS485_RE_PIN);
3031
3132/* *
3233 * @class ModbusT1SServerClass
@@ -108,10 +109,72 @@ int ModbusT1SServerClass::begin(RS485Class& rs485, unsigned long baudrate, uint1
108109{
109110 _rs485 = &rs485;
110111 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 ;
112174 }
113175
114176 ModbusRTUClient.setTimeout (2 *1000UL );
177+
115178 return 1 ;
116179}
117180
@@ -250,7 +313,6 @@ long ModbusT1SServerClass::inputRegisterRead(int address)
250313 if (_server == nullptr ) {
251314 return res;
252315 }
253-
254316 int modbus_id = udp_rx_buf.at (2 ) << 8 | udp_rx_buf.at (3 );
255317 int address_mod = udp_rx_buf.at (4 ) << 8 | udp_rx_buf.at (5 );
256318 if (address != -1 ) {
@@ -371,6 +433,67 @@ int ModbusT1SServerClass::parsePacket() {
371433 return res;
372434}
373435
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+
374497/* *
375498 * Sets the Arduino_10BASE_T1S_UDP server for communication.
376499 *
@@ -382,5 +505,35 @@ void ModbusT1SServerClass::setT1SServer(Arduino_10BASE_T1S_UDP * server) {
382505 _server = server;
383506}
384507
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+
385538ModbusT1SServerClass ModbusT1SServer;
386539#endif
0 commit comments