Modbus RTU Arduino MKR1000 WiFi

List of devices:

  1. Arduino MKR1000 WiFi
  2. Arduino MKR485 Shield
  3. USB to RS485 adapter

Software used:

  1. Arduino IDE 2.3.2
  2. Modbus Poll

Wiring connection:

  1. A and B (Shield) connect to A and B (adapter)
  2. Shield is directly attached on the board
  3. DE pin (Shield) to DI2 pin (Arduino)
  4. RXP pin (Shield) to DI3 pin (Arduino)

Serial Setting in Modbus poll:

  1. Connection: Serial port
  2. COM port: USB-SERIAL CH340 (COM12)
  3. Baud rate: 9600
  4. Data bits: 8
  5. Parity: None
  6. Stop bit: 1
  7. 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?

can you give a link to the RS485 module you are using?

if you are using the common max485-module I would connect
RS485 shield RO (receiver output) to MKR pin 13 RX
RS485 shield DI (Driver input) to MKR pin 14 TX
RS485 shield DE (Driver Enable set HIGH to enable) and RE (Receiver Enable set LOW to enable) to suitable GPIO pins (in many cases are connected together to a single GPIO pin)

Hi, I'm using Arduino MKR485 Shield bought from rs online, which can directly attached on the Arduino MKR1000 WiFi. Here's the link: https://my.rs-online.com/web/p/shields-for-arduino/1763643

have you seen mkr-485-communication?

ya. but I'm using only one arduino board with shield.