Neu: Die KI-Firewall überwacht die gesamte Plattform und erklärt jeden Vorfall in einfachen Worten. So funktioniert es

SDM120 meter ignores my hand-built Modbus frame from a Nano

SDM120 meter ignores my hand-built Modbus frame from a Nano

Gelöst 7 5

Back again with another newbie one, sorry.

I want my house’s Eastron SDM120 energy meter’s voltage and power in Hermetry. Arduino Nano + MAX485 module on the meter’s RS485 terminals, A to A and B to B, 120 ohm across at the meter end. DE and RE tied together on D2. The Nano will hand the values to an ESP32 later; right now I’m just trying to get any answer.

I didn’t want a library because I wanted to understand it, so I build the frame by hand. Read input register 0x0000 (voltage), 2 registers, slave address 1:

byte frame[] = {0x01, 0x04, 0x00, 0x00, 0x00, 0x02, 0x71, 0xCB};
digitalWrite(2, HIGH);
for (int i = 0; i < 8; i++) Serial.print(frame[i]);
digitalWrite(2, LOW);

Then I wait for bytes. Nothing ever comes back. Meter display shows address 001.

Ask me about 4–20 mA.
♥ 2

Why not just use a Modbus library? Seems like a lot of pain.

Still waiting for the gateway to reconnect.
♥ 1

Which baud rate is the meter on? The SDM120 ships at 2400 if I remember right, lots of people miss that.

♥ 0

Checked the meter menu, 2400 8N1 and my Serial.begin(2400, SERIAL_8N1). So that’s not it.

Ask me about 4–20 mA.
♥ 0

print and write do the same thing I think, maybe the CRC bytes are in the wrong order?

Measure twice, poll once.
♥ 2

CRC order is right, Modbus sends the low byte first and 0x71 0xCB is correct for that frame. The problem is print.

Serial.print(0x01) sends the text „1“, the byte 0x31. Serial.print(0x71) sends „113“, three bytes. So the meter receives something like „1400021137…“ in ASCII, which isn’t a Modbus frame at all, and it stays quiet. Serial.write sends the raw byte, which is what Modbus RTU needs.

Second problem: you drop DE the moment the loop ends, but at 2400 baud the bytes are still going out of the UART for another ~30 ms. Switching to receive cuts the end of the frame. Wait for the transmit to finish:

digitalWrite(2, HIGH);
Serial.write(frame, sizeof frame);
Serial.flush();            // returns when the last byte has left the UART
digitalWrite(2, LOW);

The answer is 9 bytes: address, 0x04, byte count 0x04, four data bytes, CRC. The SDM120 voltage is a 32-bit float, big-endian, high word first:

union { uint32_t u; float f; } v;
v.u = ((uint32_t)r[3] << 24) | ((uint32_t)r[4] << 16) | (r[5] << 8) | r[6];
// v.f is the voltage

Since the Nano’s only hardware UART is now on the RS485 side, debug through a SoftwareSerial pin or a blink, not the USB serial monitor. When you send it on, send {"voltage": 231.4} as a number so the chart works.

Akzeptierte Lösung♥ 9

Serial.write + flush and the meter answered first time! 9 bytes, 233.1 V. I had no idea print turned it into text. Writing power (register 0x000C) next, then it goes over to the ESP32.

Ask me about 4–20 mA.
♥ 0

ok so print converts to text. Makes sense now, I was wrong about the CRC.

Measure twice, poll once.
♥ 2
Ansicht von 8 Beiträgen – 1 bis 8 (von insgesamt 8)
  • Du musst angemeldet sein, um auf dieses Thema antworten zu können.

Mitdiskutieren

Melde dich an, um Fragen zu stellen und zu beantworten, hilfreiche Beiträge mit „Gefällt mir“ zu markieren und die Antwort zu kennzeichnen, die dein Problem gelöst hat. Jeder Beitrag bringt Punkte und Stufen.

Teilen