Skip to content

Commit b23e29a

Browse files
committed
Tutorial content update (Example defined)
1 parent 70c5bf0 commit b23e29a

File tree

1 file changed

+107
-132
lines changed
  • content/hardware/07.opta/opta-family/opta/tutorials/19.getting-started-with-modbus-tcp

1 file changed

+107
-132
lines changed

content/hardware/07.opta/opta-family/opta/tutorials/19.getting-started-with-modbus-tcp/content.md

Lines changed: 107 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -106,211 +106,186 @@ The setup incorporates an Ethernet switch that monitors both Opta™ devices usi
106106

107107
### Code Overview
108108

109-
...
109+
The following example aims to configure and use the Modbus TCP communication protocol over the Ethernet interface between two Opta™ devices.
110+
111+
Modbus is a well-known client-server protocol for its reliability. The Modbus client is responsible for sending requests, and the Modbus server provides the requested information when available. Multiple Modbus servers can be present, but only one Modbus client can be active.
112+
113+
In this example, an Opta™ client handles writing and reading coil values. At the same time, an Opta™ server polls for Modbus TCP requests and returns the appropriate values, with LED output as a visual indicator.
114+
115+
You can access the complete example code below.
110116

111117
#### Modbus TCP Client
112118

113-
The Opta™ Client will require the following setup:
119+
The Opta™ Client uses the following example:
114120

115121
```arduino
122+
// Include necessary libraries for Ethernet and Modbus communication
116123
#include <SPI.h>
117124
#include <Ethernet.h>
118-
119-
#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
125+
#include <ArduinoRS485.h>
120126
#include <ArduinoModbus.h>
121127
122-
// Enter a MAC address for your controller below.
123-
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
124-
// The IP address will be dependent on your local network:
125-
byte mac[] = {
126-
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
127-
};
128-
IPAddress ip(192, 168, 1, 177);
129-
130128
EthernetClient ethClient;
131129
ModbusTCPClient modbusTCPClient(ethClient);
132130
133-
IPAddress server(192, 168, 1, 10); // update with the IP Address of your Modbus server
131+
// Define the IP address for Opta
132+
IPAddress ip(10, 0, 0, 157);
134133
135-
void setup() {
136-
//Initialize serial and wait for port to open:
137-
Serial.begin(9600);
138-
while (!Serial) {
139-
; // wait for serial port to connect. Needed for native USB port only
140-
}
134+
// Define the IP Address of the Modbus TCP server (Opta device)
135+
IPAddress server(10, 0, 0, 227);
141136
142-
// start the Ethernet connection and the server:
143-
Ethernet.begin(mac, ip);
137+
void setup() {
138+
// Initialize serial communication at 9600 bauds,
139+
// wait for the serial port to connect
140+
Serial.begin(9600);
141+
while (!Serial);
142+
143+
// Initialize Ethernet connection with the specified IP address
144+
// Using NULL for MAC to auto-assign the device's MAC address
145+
Ethernet.begin(NULL, ip);
146+
147+
// Check Ethernet hardware presence
148+
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
149+
Serial.println("- Ethernet interface was not found!");
150+
while (true);
151+
}
144152
145-
// Check for Ethernet hardware present
146-
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
147-
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
148-
while (true) {
149-
delay(1); // do nothing, no point running without Ethernet hardware
153+
// Check Ethernet cable connection
154+
if (Ethernet.linkStatus() == LinkOFF) {
155+
Serial.println("- Ethernet cable is not connected!");
150156
}
151-
}
152-
if (Ethernet.linkStatus() == LinkOFF) {
153-
Serial.println("Ethernet cable is not connected.");
154-
}
155157
}
156158
157159
void loop() {
158-
if (!modbusTCPClient.connected()) {
159-
// client not connected, start the Modbus TCP client
160-
Serial.println("Attempting to connect to Modbus TCP server");
161-
162-
if (!modbusTCPClient.begin(server, 502)) {
163-
Serial.println("Modbus TCP Client failed to connect!");
160+
// Attempt to connect to Modbus TCP server if not already connected
161+
if (!modbusTCPClient.connected()) {
162+
Serial.println("- Attempting to connect to Modbus TCP server...");
163+
164+
// Start Modbus TCP client
165+
if (!modbusTCPClient.begin(server, 502)) {
166+
Serial.println("- Failed to connect to Modbus TCP server!");
167+
} else {
168+
Serial.println("- Connected to Modbus TCP server!");
169+
}
164170
} else {
165-
Serial.println("Modbus TCP Client connected");
166-
}
167-
} else {
168-
// client connected
169-
170-
// write the value of 0x01, to the coil at address 0x00
171-
if (!modbusTCPClient.coilWrite(0x00, 0x01)) {
172-
Serial.print("Failed to write coil! ");
173-
Serial.println(modbusTCPClient.lastError());
174-
}
175-
176-
// wait for 1 second
177-
delay(1000);
178-
179-
// write the value of 0x00, to the coil at address 0x00
180-
if (!modbusTCPClient.coilWrite(0x00, 0x00)) {
181-
Serial.print("Failed to write coil! ");
182-
Serial.println(modbusTCPClient.lastError());
171+
// Modbus TCP client is connected, perform communication;
172+
// write a value to a coil at address 0x00
173+
if (!modbusTCPClient.coilWrite(0x00, 0x01)) {
174+
Serial.print("- Failed to write coil: ");
175+
Serial.println(modbusTCPClient.lastError());
176+
}
177+
178+
// Wait for a second
179+
delay(1000);
180+
181+
// Reset the coil at address 0x00
182+
if (!modbusTCPClient.coilWrite(0x00, 0x00)) {
183+
Serial.print("- Failed to reset coil: ");
184+
Serial.println(modbusTCPClient.lastError());
185+
}
186+
187+
// Wait for a second
188+
delay(1000);
183189
}
184-
185-
// wait for 1 second
186-
delay(1000);
187-
}
188190
}
189191
```
190192

193+
This example allows the Opta™ client to communicate with the Opta™ server over Modbus TCP. The client attempts to connect to the server and toggles a coil value at address 0x00 every second.
194+
191195
#### Modbus TCP Server
192196

193-
In the Opta™ Server, the main task will be to poll for Modbus TCP requests and return configured values when requested. It requires following the same initial configuration as the Opta™ Client. The main difference between the Client and the Server devices lies in the `setup()` function:
197+
In the Opta™ server, the main task will be to poll for Modbus TCP requests and return configured values when requested. It requires following the same initial configuration as the Opta™ client. The main difference between the client and the server devices lies in the `setup()` function:
194198

195199
```arduino
196-
/*
197-
Ethernet Modbus TCP Server LED
198-
199-
This sketch creates a Modbus TCP Server with a simulated coil.
200-
The value of the simulated coil is set on the LED
201-
202-
Circuit:
203-
- Any Arduino MKR Board
204-
- MKR ETH Shield
205-
206-
created 16 July 2018
207-
by Sandeep Mistry
208-
*/
209-
210200
#include <SPI.h>
211201
#include <Ethernet.h>
212-
213-
#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
202+
#include <ArduinoRS485.h>
214203
#include <ArduinoModbus.h>
215204
216-
// Enter a MAC address for your controller below.
217-
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
218-
// The IP address will be dependent on your local network:
219-
byte mac[] = {
220-
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
221-
};
222-
IPAddress ip(192, 168, 1, 177);
205+
// Define the IP address for the Modbus TCP server
206+
IPAddress ip(10, 0, 0, 227);
223207
224-
EthernetServer ethServer(502);
208+
// Server will listen on Modbus TCP standard port 502
209+
EthernetServer ethServer(502);
225210
211+
// Create a Modbus TCP server instance
226212
ModbusTCPServer modbusTCPServer;
227213
228-
const int ledPin = LED_BUILTIN;
214+
// Define the pin for the LED
215+
const int ledPin = LED_D0; // Use LED_D0 as the LED pin
229216
230217
void setup() {
231-
// You can use Ethernet.init(pin) to configure the CS pin
232-
//Ethernet.init(10); // Most Arduino shields
233-
//Ethernet.init(5); // MKR ETH shield
234-
//Ethernet.init(0); // Teensy 2.0
235-
//Ethernet.init(20); // Teensy++ 2.0
236-
//Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet
237-
//Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet
238-
239-
// Open serial communications and wait for port to open:
218+
// Initialize serial communication at 9600 bauds,
219+
// wait for the serial port to connect,
220+
// initialize Ethernet connection with the specified IP address
240221
Serial.begin(9600);
241-
while (!Serial) {
242-
; // wait for serial port to connect. Needed for native USB port only
243-
}
244-
Serial.println("Ethernet Modbus TCP Example");
245-
246-
// start the Ethernet connection and the server:
247-
Ethernet.begin(mac, ip);
222+
while (!Serial);
223+
Ethernet.begin(NULL, ip);
248224
249-
// Check for Ethernet hardware present
225+
// Check Ethernet hardware and cable connections
250226
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
251-
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
252-
while (true) {
253-
delay(1); // do nothing, no point running without Ethernet hardware
254-
}
227+
Serial.println("- Ethernet interface not found!");
228+
while (true);
255229
}
256230
if (Ethernet.linkStatus() == LinkOFF) {
257-
Serial.println("Ethernet cable is not connected.");
231+
Serial.println("- Ethernet cable not connected!");
258232
}
259233
260-
// start the server
234+
// Start the Modbus TCP server
261235
ethServer.begin();
262-
263-
// start the Modbus TCP server
264236
if (!modbusTCPServer.begin()) {
265-
Serial.println("Failed to start Modbus TCP Server!");
237+
Serial.println("- Failed to start Modbus TCP Server!");
266238
while (1);
267239
}
268240
269-
// configure the LED
241+
// Configure the LED pin as an output
270242
pinMode(ledPin, OUTPUT);
271-
digitalWrite(ledPin, LOW);
272243
273-
// configure a single coil at address 0x00
244+
// Configure a single coil at address 0x00 for Modbus communication
274245
modbusTCPServer.configureCoils(0x00, 1);
275246
}
276247
277248
void loop() {
278-
// listen for incoming clients
249+
// Handle incoming client connections and process Modbus requests
279250
EthernetClient client = ethServer.available();
280-
281251
if (client) {
282-
// a new client connected
283-
Serial.println("new client");
252+
Serial.println("- Client connected!");
284253
285-
// let the Modbus TCP accept the connection
254+
// Accept and handle the client connection for Modbus communication
286255
modbusTCPServer.accept(client);
287256
257+
// Update the LED state based on Modbus coil value
288258
while (client.connected()) {
289-
// poll for Modbus TCP requests, while client connected
290-
modbusTCPServer.poll();
291-
292-
// update the LED
259+
// Process Modbus requests
260+
modbusTCPServer.poll();
293261
updateLED();
294262
}
295263
296-
Serial.println("client disconnected");
264+
Serial.println("Client disconnected.");
297265
}
298266
}
299267
268+
/**
269+
* Updates the LED state based on the Modbus coil value.
270+
* Reads the current value of the coil from the Modbus TCP
271+
* server and sets the LED state. If the coil value is high,
272+
* the LED is turned on. If it is low, the LED is turned off
273+
*
274+
* @param None
275+
*/
300276
void updateLED() {
301-
// read the current value of the coil
277+
// Read the current value of the coil at address 0x00
302278
int coilValue = modbusTCPServer.coilRead(0x00);
303-
304-
if (coilValue) {
305-
// coil value set, turn LED on
306-
digitalWrite(ledPin, HIGH);
307-
} else {
308-
// coild value clear, turn LED off
309-
digitalWrite(ledPin, LOW);
310-
}
279+
280+
// Set the LED state; HIGH if coil value is 1, LOW if coil value is 0
281+
digitalWrite(ledPin, coilValue ? HIGH : LOW);
311282
}
312283
```
313284

285+
This example sets up the Opta™ server to listen for incoming Modbus TCP connections and handle requests. It controls the LED_D0 based on the coil value received from the client.
286+
287+
***You can find more information about Opta™ device's LEDs [here](https://docs.arduino.cc/tutorials/opta/user-manual/#leds).***
288+
314289
### Testing the Modbus TCP Client and Server
315290

316291
Once the Modbus TCP Client and Server code for each Opta™ device has been uploaded, the user LED will be toggles along with the coil value on the Serial Monitor of the Opta™ Client after each read-and-write task:

0 commit comments

Comments
 (0)