Nouveau : le pare-feu IA surveille toute la plateforme et explique chaque incident en termes simples. Découvrez comment ça marche

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

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

Résolu 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.

Solution acceptée♥ 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
8 sujets de 1 à 8 (sur un total de 8)
  • Vous devez être connecté pour répondre à ce sujet.

Rejoignez la discussion

Connectez-vous pour poser et répondre à des questions, aimer les messages utiles et marquer la réponse qui a résolu votre problème. Chaque contribution rapporte des points et des niveaux.

Partager