List of devices:
- Arduino MKR1000 WiFi
- Arduino MKR485 Shield
- USB to RS485 adapter
Software used:
- Arduino IDE 2.3.2
- Modbus Poll
Wiring connection:
- A and B (Shield) connect to A and B (adapter)
- Shield is directly attached on the board
- DE pin (Shield) to DI2 pin (Arduino)
- RXP pin (Shield) to DI3 pin (Arduino)
Serial Setting in Modbus poll:
- Connection: Serial port
- COM port: USB-SERIAL CH340 (COM12)
- Baud rate: 9600
- Data bits: 8
- Parity: None
- Stop bit: 1
- Mode: RTU
Coding:
#include <ModbusRTU.h>
#include <ArduinoRS485.h> // Arduino RS485 library
// Define the control pins for DE and RXP
const int DEPin = 2;
const int RXPPin = 3;
// ModbusRTU instance
ModbusRTU mb;
bool cb(Modbus::ResultCode event, uint16_t transactionId, void* data) {
char buf[40]; // buffer to hold the formatted string
sprintf(buf, "Request result: 0x%02X\n", event);
Serial.print(buf);
return true;
}
void setup() {
// Start the serial communication with the computer
Serial.begin(9600);
// Wait for the serial port to be available
while (!Serial) {
delay(100);
}
Serial.println("Serial communication initialized.");
// Set up control pins as OUTPUT
pinMode(DEPin, OUTPUT);
pinMode(RXPPin, OUTPUT);
// Ensure RS485 transceiver is in receive mode initially
digitalWrite(DEPin, LOW);
digitalWrite(RXPPin, HIGH);
// Initialize the RS485 communication
RS485.begin(9600, SERIAL_8N1); // Set baud rate, data bits, stop bit, and parity
Serial.println("RS485 communication initialized.");
// Initialize the ModbusRTU slave
mb.begin(&RS485);
mb.slave(1); // Set Modbus slave ID to 1
// Add a holding register (address 0) to respond to read/write requests
// Add 10 holding registers (addresses 0 to 9) to respond to read/write requests
for (int i = 0; i < 10; i++) {
mb.addHreg(i, 0 + i); // Initialize registers with different values
}
Serial.println("ModbusRTU slave initialized.");
}
void loop() {
// Enable reception mode
digitalWrite(DEPin, LOW);
digitalWrite(RXPPin, HIGH);
// Process incoming requests
mb.task();
// If you want to change the holding register value, you can do it here
// For example, updating the register every 5 seconds
static uint32_t lastMillis = 0;
if (millis() - lastMillis > 5000) {
lastMillis = millis();
mb.Hreg(0, mb.Hreg(0) + 1); // Increment the holding register value
Serial.print("Holding Register 0 updated to: ");
Serial.println(mb.Hreg(0));
}
}
My concern is I have tried to communicate with the modbus poll but it turns out Timeout error. Besides, only the RXD led in the adapter lights up but not the TXD led, which may indicates that my arduino didn't get to handle the modbus request from the modbus poll and didn't send any data to it. Anyone have ideas on this?