Arduino Opta not communicating with EM4M energy meter (Modbus RTU)

Hi everyone

I’m trying to read voltage data from a Selec EM4M energy meter using Arduino Opta (as Modbus RTU master) via RS485, but I’m not getting any valid response.

Here’s the sketch I’m using:

#include <ArduinoRS485.h>
#include <ArduinoModbus.h>

const uint8_t  SLAVE_ID = 1;
const uint16_t VOLTAGE_ADDR = 30000;
const uint8_t  NUM_REGS = 2;

void setup() {
  Serial.begin(9600);
  while (!Serial);
  if (!ModbusRTUClient.begin(9600, SERIAL_8N1)) {
    Serial.println("Failed to start Modbus RTU client!");
    while (1);
  }
}

void loop() {
  if (!ModbusRTUClient.requestFrom(SLAVE_ID, HOLDING_REGISTERS, VOLTAGE_ADDR, NUM_REGS)) {
    Serial.print("Error: "); Serial.println(ModbusRTUClient.lastError());
  } else {
    uint16_t hi = ModbusRTUClient.read();
    uint16_t lo = ModbusRTUClient.read();
    uint32_t raw = ((uint32_t)hi << 16) | lo;
    float val; memcpy(&val, &raw, sizeof(val));
    Serial.println(val);
  }
  delay(2000);
}

Connections:

  • Opta A(-) → EM4M B(D−)
  • Opta B(+v) → EM4M A(D+)
  • Baud rate: 9600, ID: 1, Parity: None

I’ve double-checked wiring and settings, but still getting “response not from requested slave” or “timeout”.

Can anyone help me to solve this issue?

30000 points to input register 0

const uint16_t VOLTAGE_ADDR = 0x0000

if (!ModbusRTUClient.requestFrom(SLAVE_ID, INPUT_REGISTERS, VOLTAGE_ADDR, NUM_REGS))

You might have other problems as well if you only get timeout and not some specific error

Thank you for your suggestion, Kmin.
As you mentioned, I think there might be other issues as well. I still could not establish Modbus communication between the Opta and the EM4M.

So did you try to swap A- and B+ lines ?
How long is your wiring?
Do you have termination resistors?

I found the issue — adding the following line solved the communication problem:

RS485.setDelays(1000, 1000);

Now, the Opta is successfully communicating with the EM4M energy meter.

Working setup:

RS485.setDelays(1000, 1000);
if (!ModbusRTUClient.begin(9600, SERIAL_8N1)) {
  Serial.println("Failed to start Modbus RTU Client!");
  while (1);
}

Connections:

  • Opta A (-) → EM4M (+)
  • Opta B (+) → EM4M (-)

The communication is now stable and working perfectly in Arduino IDE.
However, I’m currently facing an issue implementing the same logic in PLC IDE — I’m unable to read the sensor data from the EM4M via RS485 in that environment.

At least now you have correct register address, correct wiring and delays. That makes difference.. :wink:

The same setup works perfectly in the Arduino IDE, but in PLC IDE no data is being received :face_with_diagonal_mouth:.
I would really appreciate your guidance on what configuration or logic might be missing.

I have never used PLC IDE.
But you should stop using addressing like that. 30000 is first input register, either 0x0000 in hex or 1 in decimal.
So replace 30000 with 1 and 30001 with 2.

Thank you buddy!..I have changed the address 30000 to 1..now i could see the modbus data :melting_face:

Nice, you're welcome.