I'm using ESP32 with the RS485 converter with DE/RE pins. For the slave I'm using Wemos D1 Mini ESP8266 with the auto-flow version of RS485 converter. I have the following connections:
MASTER:
ESP32 PIN 16 -> RS485 RO
ESP32 PIN 17 -> RS485 DI
ESP32 PIN 32 -> RS485 DE and also RE
SLAVE
WEMOS D1 MINI PIN 4 -> RS485 RX
WEMOS D1 MINI PIN 5 -> RS485 TX
and naturally 3.3V to VCC and GND to GND for both boards.
I'm having hard time reading from the slave and I can't figure out why. I tried multiple different libraries but none of them worked. I also tried to setup just a simple serial communication and send a message to the slave and that was working. But I can't read the register with the following code.
MASTER
#include <ModbusRTUMaster.h>
const byte rxPin = 16; // RX pin for RS-485
const byte txPin = 17; // TX pin for RS-485
const byte dePin = 32; // Driver Enable pin (set to LOW for auto flow control)
ModbusRTUMaster modbus(Serial, dePin); // Create Modbus master object
void setup() {
Serial.begin(115200); // Serial monitor for debugging
// Initialize Modbus communication
modbus.begin(38400); // Baud rate for RS-485
// Initialize the RS-485 driver enable pin
pinMode(dePin, OUTPUT);
digitalWrite(dePin, LOW); // Set DE pin low for auto flow control
}
void loop() {
uint16_t holdingRegisterValue = 0; // Variable to store the register value
// Request the value of holding register 0 from slave with ID 1
bool success = modbus.readHoldingRegisters(1, 0, &holdingRegisterValue, 1); // slave ID, register address, pointer to store value, number of registers
// Check if the request was successful
if (success) {
Serial.print("Holding Register Value: ");
Serial.println(holdingRegisterValue);
} else {
Serial.println("Failed to read holding register");
if (modbus.getTimeoutFlag()) {
Serial.println("Error: Timeout");
modbus.clearTimeoutFlag();
} else if (modbus.getExceptionResponse() != 0) {
Serial.print("Error: Exception Response ");
Serial.print(modbus.getExceptionResponse());
Serial.println();
modbus.clearExceptionResponse();
} else {
Serial.println("Error: Unknown");
}
}
delay(1000); // Wait before making the next request
}
and the SLAVE:
#if __AVR__
// Uncomment the following line if you want to use SoftwareSerial on pins 10 and 11; note this only works on AVR boards.
//# define USE_SOFTWARE_SERIAL
#endif
#if defined USE_SOFTWARE_SERIAL
#include <SoftwareSerial.h>
#endif
#include <ModbusRTUSlave.h>
#if defined USE_SOFTWARE_SERIAL
const byte rxPin = 4; // RX pin for SoftwareSerial
const byte txPin = 5; // TX pin for SoftwareSerial
SoftwareSerial mySerial(rxPin, txPin);
ModbusRTUSlave modbus(mySerial); // Use SoftwareSerial without DE pin
#else
#if defined ESP32
ModbusRTUSlave modbus(Serial2); // Use Serial2 without DE pin for ESP32
#else
ModbusRTUSlave modbus(Serial); // Use Serial without DE pin for ESP8266
#endif
#endif
const byte pinToRead = 14; // The pin whose state you want to read
uint16_t holdingRegister = 0; // Single holding register
void setup() {
pinMode(pinToRead, INPUT); // Set the pin as input
// Configure Modbus registers
modbus.configureHoldingRegisters(&holdingRegister, 1); // Single holding register
modbus.begin(1, 38400); // Initialize Modbus with slave ID 1 and baud rate 38400
}
void loop() {
holdingRegister = digitalRead(pinToRead); // Read the state of the pin and store in holding register
modbus.poll(); // Handle Modbus communication
// You can add additional code here if needed
}
on the master serial monitor I'm seeing this output. And also on the slave's converter I don't see any action on the TX or RX leds indicators.
�
Failed to read holding register
Error: Timeout
I'm not sure if my code is right since I got it using chatgpt. My goal for now is just to be able to read one register from the slave.