Modbus communication Arduino MKR 485 and A9MEM2055 energy meter

Hi,

I'm using an Arduino MKR 485 connected to an Arduino MKR WIFI 1010 module.
I'm trying to read out the modbus from a Schneider A9MEM2055 energy meter (manual: https://www.productinfo.schneider-electric.com/iem2050/5b3e7b76d674a900015d9be8/iEM2050%20User%20Manual/English/BM_iEM2000seriesUserManual_0000207501.ditamap).

The settings of the energy meter are: Modbus Id: 001, Baudrate: 9600, Parity: even, Stop bit: 1 and 8 data bits.

However when I run the program I get an error: Connection timed out.
I tried the program with another energy meter (A9MEM3150) and that works.

I have put the Arduino in half duplex (can't find if the A9MEM2055 support this but that is my assumption), so only the third switch is set to ON. Port 23 (A) on the energy meter is connected to Z on the Arduino and port 24 (B) is connected to Y.
I also tried to use an 120 ohm resistor between port 23 & 24 without any luck. But the MKR 485 should take care of this right?



Here is my code:

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

float volt;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(1500);

    // Start Modbus RTU client
  if (!ModbusRTUClient.begin(9600, SERIAL_8E1)) {
    Serial.println("- Failed to start Modbus RTU Client!");
    while (1);
  }
  
}
void loop() {
  volt = readVoltage();
  Serial.print("Voltage: ");
  Serial.print(volt);
  Serial.println(" V");
  delay(1000); // Delay between readings
}

float readVoltage() {
    float volt = 0.;
    if (!ModbusRTUClient.requestFrom(1, HOLDING_REGISTERS, 0x0BD4, 2)) {
    // Error handling
    Serial.print("- Failed to read the voltage! ");
    Serial.println(ModbusRTUClient.lastError()); 
  } else {
    // Response handler 
    uint16_t word1 = ModbusRTUClient.read();  // Read word1 from buffer
    uint16_t word2 = ModbusRTUClient.read();  // Read word2 from buffer
    uint32_t p = word1 << 16 | word2; // Join word1 and word2 to retrieve voltage value in millivolts
    volt  =  *(float*)&p;  //convert 32 bit int into float.
  }
  return volt;
}

Thanks!

Tom

Try the other way around, A+ to Y, B- to Z

1 Like

Jeezz, so simple!
Thank you so much!
Any idea why this works? It is documented that it should be the other way around.

Because it's a wild west. Most devices are using A+/B-, but original RS485 standard defines A-/B+.

1 Like

Ah ok, good to know!
Thanks again!