I encountered a problem when I mixed setting coil registers and querying holding registers in a program. It works 95% of the time, but occasionally the holding register cannot be set. When I only query holding registers or only set coil registers, everything works great.
It doesn't seem to be the client's fault either. When I analyze the data sent by the client, it seems that the correct protocols are always being sent. It appears that the server occasionally does not respond because it detects a CRC error.
#include <CSE_ArduinoRS485.h>
#include <CSE_ModbusRTU.h>
//===================================================================================//
const int ledPin = 2;
int counter = 0;
// Declare the RS485 interface here with a hardware serial port.
// auto send/receive: Dip Switch S1: OFF - ON - ON - OFF
RS485Class RS485 (Serial2, -1, -1, -1); // (Serial Port, DE, RE, TX)
//RS485Class RS485 (Serial1, 6, 6, 1); // (Serial Port, DE, RE, TX)
// Create a Modbus RTU node instance with the RS485 interface.
CSE_ModbusRTU modbusRTU (&RS485, 0x01, "modbusRTU-0x01"); // (RS-485 Port, Device Address, Device Name)
// Create a Modbus RTU server instance with the Modbus RTU node.
CSE_ModbusRTU_Server modbusRTUServer (modbusRTU, "modbusRTUServer"); // (CSE_ModbusRTU, Server Name)
//===================================================================================//
void setup() {
// Initialize the default serial port for debug messages
Serial.begin (115200);
delay (1000);
Serial.println ("Modbus RTU Server with Arduino UNO R4");
// Initialize the RS485 interface. If you are initializing the RS485 interface
// manually, then the parameter can be empty.
Serial2.setPins(16,17); // pins of U5
RS485.begin (9600,SERIAL_8N1);
// Initialize the Modbus RTU server
modbusRTUServer.begin();
// Configure the LED
pinMode (ledPin, OUTPUT);
digitalWrite (ledPin, LOW);
// Configure four coils starting at address 0x00
// build-in LED is coil 0x00
modbusRTUServer.configureCoils (0x00, 4);
// Configure four holding registers
// status of build-in LED is holding register 0x00
// status of counter is holding register 0x01
modbusRTUServer.configureHoldingRegisters (0x00, 4);
// Enable/Disable the debug messages here.
CSE_ModbusRTU_Debug:: enableDebugMessages();
}
//===================================================================================//
void loop() {
// increment counter
counter++;
// holding registers
// save adc values
modbusRTUServer.writeHoldingRegister(0x00,analogRead(2));
modbusRTUServer.writeHoldingRegister(0x01,analogRead(4));
modbusRTUServer.writeHoldingRegister(0x02,analogRead(35));
// save counter value
modbusRTUServer.writeHoldingRegister(0x03,counter);
// Poll for Modbus RTU requests
int requestReceived = modbusRTUServer.poll();
// proceed Modbus
if ((requestReceived != -1) && (requestReceived < 0x80)) {
Serial.println ("Request received");
// Read the current value of the coil
int coilValue = modbusRTUServer.readCoil (0x00);
// set led according coilValue
if (coilValue != 0) {
// Coil value set, turn LED on
digitalWrite (ledPin, HIGH);
} else if (coilValue == 0) {
// Coil value clear, turn LED off
digitalWrite (ledPin, LOW);
}
}
}
I encountered a problem when I mixed setting coil registers and querying holding registers in a program. It works 95% of the time, but occasionally the holding register cannot be set. When I only query holding registers or only set coil registers, everything works great.
It doesn't seem to be the client's fault either. When I analyze the data sent by the client, it seems that the correct protocols are always being sent. It appears that the server occasionally does not respond because it detects a CRC error.