You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/hardware/05.pro-solutions/solutions-and-kits/portenta-machine-control/tutorials/user-manual/content.md
+218-1
Original file line number
Diff line number
Diff line change
@@ -1232,10 +1232,227 @@ To use the Modbus protocol with your Portenta Machine Control, you will need the
1232
1232
1233
1233
#### Modbus RTU
1234
1234
1235
-
Modbus RTU, generally operating in half-duplex mode, with its capability to handle noisy and long-distance transmission lines, makes it an excellent choice for industrial environments. Modbus RTU communication is supported using Portenta's Machine Control RS-485 physical interface.
1235
+
Modbus RTU, generally operating in half-duplex mode, has the capability to handle noisy and long-distance transmission lines, which makes it an excellent choice for industrial environments. Modbus RTU communication is supported using Portenta Machine Control's RS-485 physical interface.
1236
1236
1237
1237
***The Portenta Machine Control has onboard termination resistors; its RS-485 interface can be configured as a half or full duplex.***
1238
1238
1239
+
#### Using Two Portenta Machine Controls
1240
+
1241
+
The following example shows how to establish Modbus RTU communication between **two Portenta Machine Control devices**. We will use four LEDs from the Digital Output port of the Portenta Machine Control as the visual indicator to confirm the communication is working as intended. Since Portenta Machine Control supports half-duplex and full-duplex modes, each mode requires a different wiring setup.
1242
+
1243
+
We will begin showing the **Full-Duplex mode** example following the connection diagram below between two Portenta Machine Control devices:
1244
+
1245
+

1246
+
1247
+
The following script assigns a Portenta Machine Control as a Client device, which sends four coil values to the Portenta Machine Control assigned as a Server.
1248
+
1249
+
```arduino
1250
+
// Include the necessary libraries
1251
+
#include <Arduino_PortentaMachineControl.h>
1252
+
#include <ArduinoRS485.h>
1253
+
#include <ArduinoModbus.h>
1254
+
1255
+
// Define the baud rate for Modbus communication
1256
+
constexpr auto baudrate{ 38400 };
1257
+
1258
+
// Calculate preDelay and postDelay in microseconds as per Modbus RTU Specification
1259
+
// Modbus over serial line specification and implementation guide V1.02
// Check for successful transmission and report errors if any
1313
+
// Print error code if transmission failed
1314
+
// Or confirm successful coil value writing
1315
+
if (!ModbusRTUClient.endTransmission()) {
1316
+
Serial.print("- Failed! Error code: ");
1317
+
Serial.println(ModbusRTUClient.lastError());
1318
+
} else {
1319
+
Serial.println("- Success!");
1320
+
}
1321
+
1322
+
// Delay before next operation to simulate periodic control
1323
+
delay(1000);
1324
+
}
1325
+
```
1326
+
1327
+
Because the Portenta Machine Control is operating in **Full-Duplex mode**, the following line of code is essential and must be included within the code to enable Full-Duplex mode:
1328
+
1329
+
```arduino
1330
+
MachineControl_RS485Comm.setFullDuplex(true);
1331
+
```
1332
+
1333
+
The Server Portenta Machine Control uses the script below, which translates received coil values into corresponding Digital Outputs. It will blink four Digital Outputs accordingly in a timely manner.
1334
+
1335
+
```arduino
1336
+
// Include the necessary libraries
1337
+
#include <ArduinoRS485.h>
1338
+
#include <ArduinoModbus.h>
1339
+
#include <Arduino_PortentaMachineControl.h>
1340
+
1341
+
// Define the number of coils to control LEDs
1342
+
const int numCoils = 4;
1343
+
1344
+
// Define the baud rate for Modbus communication
1345
+
constexpr auto baudrate{ 38400 };
1346
+
1347
+
// Calculate preDelay and postDelay in microseconds as per Modbus RTU Specification
1348
+
// Modbus over serial line specification and implementation guide V1.02
// Enable full duplex mode and 120 Ohm termination resistors
1366
+
MachineControl_RS485Comm.setFullDuplex(true);
1367
+
1368
+
// Set the RS-485 interface in receive mode initially
1369
+
MachineControl_RS485Comm.receive();
1370
+
1371
+
// Start the Modbus RTU server with a specific slave ID and baud rate
1372
+
// Halt execution if the server fails to start
1373
+
if (!ModbusRTUServer.begin(MachineControl_RS485Comm, 1, baudrate, SERIAL_8N1)) {
1374
+
Serial.println("- Failed to start Modbus RTU Server!");
1375
+
while (1)
1376
+
;
1377
+
}
1378
+
1379
+
//Set over current behavior of all channels to latch mode (true)
1380
+
MachineControl_DigitalOutputs.begin(true);
1381
+
1382
+
//At startup set all channels to OPEN
1383
+
MachineControl_DigitalOutputs.writeAll(0);
1384
+
1385
+
// Set 7th Digital Output channel ON to show the port has been correctly configured
1386
+
MachineControl_DigitalOutputs.write(7, HIGH);
1387
+
1388
+
// Configure coils for controlling the onboard LEDs
1389
+
ModbusRTUServer.configureCoils(0x00, numCoils);
1390
+
}
1391
+
1392
+
void loop() {
1393
+
// Poll for Modbus RTU requests and process them
1394
+
int packetReceived = ModbusRTUServer.poll();
1395
+
Serial.println(packetReceived);
1396
+
if (packetReceived) {
1397
+
// Process each coil's state and control LEDs accordingly
1398
+
for (int i = 0; i < numCoils; i++) {
1399
+
// Read coil value
1400
+
// Update discrete input with the coil's state
1401
+
int coilValue = ModbusRTUServer.coilRead(i);
1402
+
ModbusRTUServer.discreteInputWrite(i, coilValue);
1403
+
1404
+
// Debug output to the IDE's serial monitor
1405
+
Serial.print("LED ");
1406
+
Serial.print(i);
1407
+
Serial.print(" = ");
1408
+
Serial.println(coilValue);
1409
+
1410
+
// Control the onboard LEDs based on the coil values
1411
+
switch (i) {
1412
+
case 0:
1413
+
MachineControl_DigitalOutputs.write(0, coilValue ? HIGH : LOW);
1414
+
break;
1415
+
case 1:
1416
+
MachineControl_DigitalOutputs.write(1, coilValue ? HIGH : LOW);
1417
+
break;
1418
+
case 2:
1419
+
MachineControl_DigitalOutputs.write(2, coilValue ? HIGH : LOW);
1420
+
break;
1421
+
case 3:
1422
+
MachineControl_DigitalOutputs.write(3, coilValue ? HIGH : LOW);
1423
+
// New line for better readability
1424
+
Serial.println();
1425
+
break;
1426
+
default:
1427
+
// Error handling for unexpected coil addresses
1428
+
Serial.println("- Output out of scope!");
1429
+
break;
1430
+
}
1431
+
}
1432
+
}
1433
+
}
1434
+
```
1435
+
1436
+
With this, we have two Portenta Machine Control devices, each assigned as a Client and Server correspondingly, communicating with Modbus RTU in full-duplex mode.
Alternatively, to establish communication between two Portenta Machine Control with Modbus RTU in **Half-Duplex mode**, the following wiring setup is required:
1441
+
1442
+

1443
+
1444
+
The previous example can be used in half-duplex mode, but it will require one minor change in the following line of code:
1445
+
1446
+
```arduino
1447
+
MachineControl_RS485Comm.setFullDuplex(false);
1448
+
```
1449
+
1450
+
By modifying this line, *Full-Duplex mode* is deactivated. This minor code tweak, plus the appropriate wiring, enable the two units to communicate using Modbus RTU in half-duplex mode.
The example below shows how to enable Modbus RTU communication between a Portenta Machine Control device and an Opta™ device. For wiring both devices, follow the diagram below:
1240
1457
1241
1458

0 commit comments