1
+ /*
2
+ Modbus T1S Client Temperature Humidity sensor
3
+
4
+ This sketch creates a Modbus T1S Client and demonstrates
5
+ how to use the ModbusT1S API to communicate.
6
+ - Arduino Uno Wifi R4
7
+ - T1S shield
8
+ - SPE ethernet connected to the client
9
+ - all the terminations placed on the hardware
10
+ */
11
+
12
+ #include < ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
13
+ #include < ArduinoModbus.h>
14
+ #include " arduino_secrets.h"
15
+
16
+ /* *************************************************************************************
17
+ CONSTANTS
18
+ **************************************************************************************/
19
+ #define RS485_SERIAL Serial1
20
+ #define RS485_TX_PIN 1
21
+ #define RS485_RX_PIN 0
22
+ #define RS485_DE_PIN 8
23
+ #define RS485_RE_PIN 7
24
+ #define PRE_DELAY 100
25
+ #define POST_DELAY 100
26
+ #define PWR_CARRIER_RATIO 0 .18f
27
+ RS485Class serial485 (RS485_SERIAL, RS485_TX_PIN, RS485_DE_PIN, RS485_RE_PIN);
28
+
29
+ static unsigned int const MODBUS_BAUDRATE = 9600 ;
30
+ static float const MODBUS_BIT_DURATION = 1 .f / MODBUS_BAUDRATE;
31
+ static float const MODBUS_PRE_DELAY_BR = MODBUS_BIT_DURATION * 9 .6f * 3 .5f * 1e6 ;
32
+ static float const MODBUS_POST_DELAY_BR = MODBUS_BIT_DURATION * 9 .6f * 3 .5f * 1e6 ;
33
+
34
+ static int const MODBUS_DEVICE_ID = 1 ;
35
+ static int const MODBUS_DEVICE_TEMPERATURE_REGISTER = 0x0001 ;
36
+ static int const MODBUS_DEVICE_HUMIDITY_REGISTER = 0x0002 ;
37
+
38
+ static uint8_t const T1S_PLCA_NODE_ID = 0 ; /* The UDP server doubles as PLCA coordinator. */
39
+
40
+ static IPAddress const ip_addr {
41
+ 192 , 168 , 42 , 100 + T1S_PLCA_NODE_ID
42
+ };
43
+ static IPAddress const network_mask {
44
+ 255 , 255 , 255 , 0
45
+ };
46
+ static IPAddress const gateway {
47
+ 192 , 168 , 42 , 100
48
+ };
49
+
50
+ static T1SPlcaSettings const t1s_plca_settings {
51
+ T1S_PLCA_NODE_ID
52
+ };
53
+ static T1SMacSettings const t1s_default_mac_settings;
54
+
55
+ /* *************************************************************************************
56
+ GLOBAL VARIABLES
57
+ **************************************************************************************/
58
+ auto const tc6_io = new TC6::TC6_Io
59
+ ( SPI
60
+ , CS_PIN
61
+ , RESET_PIN
62
+ , IRQ_PIN);
63
+ auto const tc6_inst = new TC6::TC6_Arduino_10BASE_T1S(tc6_io);
64
+ Arduino_10BASE_T1S_UDP udp_server;
65
+
66
+ /* *************************************************************************************
67
+ SETUP/LOOP
68
+ **************************************************************************************/
69
+ void setup () {
70
+ Serial.begin (115200 );
71
+
72
+ Serial.println (" Modbus RTU Server LED" );
73
+
74
+ /* Initialize digital IO interface for interfacing
75
+ with the LAN8651.
76
+ */
77
+ pinMode (IRQ_PIN, INPUT_PULLUP);
78
+ attachInterrupt (digitalPinToInterrupt (IRQ_PIN),
79
+ []() {
80
+ tc6_io->onInterrupt ();
81
+ },
82
+ FALLING);
83
+
84
+ /* Initialize IO module. */
85
+ if (!tc6_io->begin ())
86
+ {
87
+ Serial.println (" 'TC6_Io::begin(...)' failed." );
88
+ for (;;) { }
89
+ }
90
+
91
+ MacAddress const mac_addr = MacAddress::create_from_uid ();
92
+
93
+ if (!tc6_inst->begin (ip_addr
94
+ , network_mask
95
+ , gateway
96
+ , mac_addr
97
+ , t1s_plca_settings
98
+ , t1s_default_mac_settings))
99
+ {
100
+ Serial.println (" 'TC6::begin(...)' failed." );
101
+ for (;;) { }
102
+ }
103
+
104
+ Serial.print (" IP\t " );
105
+ Serial.println (ip_addr);
106
+ Serial.println (mac_addr);
107
+ Serial.println (t1s_plca_settings);
108
+ Serial.println (t1s_default_mac_settings);
109
+
110
+ if (!udp_server.begin (UDP_SERVER_PORT))
111
+ {
112
+ Serial.println (" begin(...) failed for UDP coil read server " );
113
+ for (;;) { }
114
+ }
115
+
116
+ tc6_inst->digitalWrite (TC6::DIO::A0, false );
117
+ /* A1 -> T1S_DISABLE -> close the switch connecting network to board. */
118
+ tc6_inst->digitalWrite (TC6::DIO::A1, true );
119
+
120
+ serial485.setDelays (MODBUS_PRE_DELAY_BR, MODBUS_POST_DELAY_BR);
121
+ unsigned long br = MODBUS_BAUDRATE;
122
+ uint16_t config = SERIAL_8N1;
123
+ if (!ModbusT1SServer.begin (serial485, br, config)) {
124
+ Serial.println (" Failed to start Modbus RTU Client!" );
125
+ while (1 );
126
+ }
127
+
128
+ ModbusT1SServer.setT1SServer (&udp_server);
129
+ Serial.println (" UDP_Server" );
130
+ Serial.println (MODBUS_PRE_DELAY_BR);
131
+ Serial.println (MODBUS_POST_DELAY_BR);
132
+ }
133
+
134
+ void loop () {
135
+ /* Services the hardware and the protocol stack.
136
+ Must be called cyclic. The faster the better.
137
+ */
138
+ tc6_inst->service ();
139
+
140
+ static unsigned long prev_beacon_check = 0 ;
141
+
142
+ auto const now = millis ();
143
+ if ((now - prev_beacon_check) > 1000 )
144
+ {
145
+ prev_beacon_check = now;
146
+ if (!tc6_inst->getPlcaStatus (OnPlcaStatus)) {
147
+ Serial.println (" getPlcaStatus(...) failed" );
148
+ }
149
+ }
150
+
151
+ switch (ModbusT1SServer.parsePacket ())
152
+ {
153
+ case UDP_READ_COIL_PORT:
154
+ Serial.println (" Read coil" );
155
+ ModbusT1SServer.coilRead ();
156
+ break ;
157
+
158
+ case UDP_WRITE_COIL_PORT:
159
+ Serial.println (" Write coil" );
160
+ ModbusT1SServer.coilWrite ();
161
+ break ;
162
+
163
+ case UDP_READ_DI_PORT:
164
+ Serial.println (" Read discrete input" );
165
+ ModbusT1SServer.discreteInputRead ();
166
+ break ;
167
+
168
+ case UDP_READ_IR_PORT:
169
+ Serial.println (" Read input register" );
170
+ ModbusT1SServer.inputRegisterRead ();
171
+ break ;
172
+
173
+ case UDP_READ_HR_PORT:
174
+ Serial.println (" Read holding register" );
175
+ ModbusT1SServer.holdingRegisterRead ();
176
+ break ;
177
+
178
+ case UDP_WRITE_HR_PORT:
179
+ Serial.println (" Write holding register" );
180
+ ModbusT1SServer.holdingRegisterWrite ();
181
+ break ;
182
+
183
+ default :
184
+ break ;
185
+ }
186
+ }
187
+
188
+ static void OnPlcaStatus (bool success, bool plcaStatus)
189
+ {
190
+ if (!success)
191
+ {
192
+ Serial.println (" PLCA status register read failed" );
193
+ return ;
194
+ }
195
+
196
+ if (plcaStatus) {
197
+ Serial.println (" PLCA Mode active" );
198
+ } else {
199
+ Serial.println (" CSMA/CD fallback" );
200
+ tc6_inst->enablePlca ();
201
+ }
202
+ }
0 commit comments