SDM230 Modbus Zähler auslesen - gelöst

Hallo da draußen,

von hier habe ich den Code für meinen Zähler gemopst. Ist keine fancy Seite, für den Code runterscrollen. Ich benutze als Read/Write Pin nur Pin 2.

Läuft auf einem Mega und ich stehe vor einem Rätsel - vielleicht hat hier jemand eine Idee :bulb:

Beim Starten des Sketches wird wie erwartet die Spannung ausgelesen.
Ab dem zweiten Durchlauf kommt ne ganze Weile 0 Volt oder auch mal ein ovf (overflow) oder was abstruses - und dann schlagartig und dauerhaft der richtige Wert. Das ist reproduzierbar.

Hab schon mit der Baudrate gespielt, die Modbus Strippen sind 50 cm lang, 2. Adapter probiert. Immer das gleiche Verhalten.

Wer hat hilfreiche Tipps?

Hier noch den Bandwurm an Ausgaben:

233.4 Volts
0.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
ovf Volts
-0.0 Volts
ovf Volts
0.0 Volts
ovf Volts
233.2 Volts
0.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
ovf Volts
-0.1 Volts
0.0 Volts
0.0 Volts
ovf Volts
233.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
-8388868.0 Volts
-0.0 Volts
-0.0 Volts
0.0 Volts
ovf Volts
233.2 Volts
0.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
2.9 Volts
0.0 Volts
ovf Volts
233.3 Volts
0.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
ovf Volts
0.0 Volts
28583.0 Volts
ovf Volts
ovf Volts
233.5 Volts
0.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
ovf Volts
-0.0 Volts
0.0 Volts
30118606.0 Volts
ovf Volts
233.4 Volts
0.0 Volts
0.0 Volts
0.0 Volts
0.0 Volts
ovf Volts
ovf Volts
ovf Volts
ovf Volts
ovf Volts
233.4 Volts
233.4 Volts
233.4 Volts
233.3 Volts
233.3 Volts
233.3 Volts
233.2 Volts
233.2 Volts
233.2 Volts
233.2 Volts
233.2 Volts
233.2 Volts
233.3 Volts
233.4 Volts

Geht denn der Original-Sketch?
Und was hast du dran geändert, außer die Hex-Ausgaben rauszunehmen?

Ich verwende das Original, nur eben mit Pin 2. und ja, Hex Ausgabe ist auskommentiert. Sonst alles original.

// NOTE:
// RS485 Control pin: 3,     SPEED 2400

/* *** KMTRONIC LTD ****
   www.kmtronic.com


 * ******* LOG COMMANDS *******
  2 - Tx: 01 04 00 00 00 02 71 CB
  3 - Rx: 01 04 04 43 6A 9D 1B E6 87
  4 - Tx: 01 04 00 00 00 02 71 CB
  5 - Rx: 01 04 04 43 6A 6E B1 22 08
  6 - Tx: 01 04 00 00 00 02 71 CB
  7 - Rx: 01 04 04 43 6A 6C 44 E3 2F
*/

/* ******* RESULT ************
  43 67 87 61
  231.53 Volts

  43 67 3E 56
  231.24 Volts

  43 67 3E 56
  231.24 Volts
*/

// RS485 Control pin
const int RS485_control = 2;

// Receive buffer
int Buffer[9];

// This command is to read 2 registers (4 bytes) form meter
// with ID:01 where is Voltage value
int VoltageReadCommand[] = {0x01, 0x04, 0x00, 0x00, 0x00, 0x02, 0x71, 0xCB};
byte status = 0;
byte i;
void setup()
{
  // Init serial communication
  Serial.begin(2400);
  // Set RS485 Control pin to OUTPUT
  pinMode(RS485_control, OUTPUT);
  // Set pin to send data HIGH
  digitalWrite(RS485_control, HIGH);
}

void loop()
{
  switch (status)
  {
    case 0:
      while ( Serial.available())
      { Serial.read(); }
      // Set pin to HIGH > Transmit mode
      digitalWrite(RS485_control, HIGH);
      // Send command to ModBus Meter
      for (int i = 0; i < 8; i++)
      { Serial.write(VoltageReadCommand[i]); }
      delay(50);
      // Set pin to LOW > Receive mode
      digitalWrite(RS485_control, LOW);
      i = 0;
      status++;
      break;
    case 1:
      // Waiting for receive reply
      if ( Serial.available())
        // Read reply in Buffer[];
      { Buffer[i] = Serial.read(); }
      if (Buffer[i] == 0x01)
      {
        i++;
        status ++;
      }
      break;
    case 2:
      if ( Serial.available())
        // Read reply in Buffer[];
      { Buffer[i] = Serial.read(); }
      i++;
      if (i >= 8)
      { status ++; }
      break;
    case 3:
      // Print new line
      Serial.flush();
      Serial.println();
      // Print voltage data received
      Serial.print(Buffer[3], HEX);
      Serial.print(" ");
      Serial.print(Buffer[4], HEX);
      Serial.print(" ");
      Serial.print(Buffer[5], HEX);
      Serial.print(" ");
      Serial.print(Buffer[6], HEX);
      Serial.print(" ");
      Serial.println();
      // Convert to Float
      float x;
      ((byte *)&x)[3] = Buffer[3];
      ((byte *)&x)[2] = Buffer[4];
      ((byte *)&x)[1] = Buffer[5];
      ((byte *)&x)[0] = Buffer[6];
      // Convert to Float
      Serial.print(x, 2);
      Serial.println(" Volts");
      delay(500);
    /* FALLTHRU */
    default:
      status = 0;
      break;
  }
}

Der wird evtl. stecken bleiben.
Aber ein Versuch ist es wert.

Mich wundert es nicht dass der Sketch nicht stabil läuft. Modbus auf der gleichen Schnittstelle wie die debug Ausgaben, fixes auslesen von 9 Bytes, keine CRC Berechnung...

An deiner Stelle würde ich die Library Modbus Master von Doc Walker installieren und mit dieser auslesen.

Aaargh, erwischt :woozy_face:
Das kommt davon, wenn man abends noch Behauptungen aufstellt ...
Der Zähler hängt an Serial1, ich häng jetzt mal den aktuellen Sketch an.
So schaut's aus:

[code]
/* *** KMTRONIC LTD ****
   www.kmtronic.com
  https://web-relays.com/en/blog/arduino-code-read-voltage-from-eas tron-sdm230-modbus-smart-energy-meter-with-modbus-protocol/

 * ******* LOG COMMANDS *******
  2 - Tx: 01 04 00 00 00 02 71 CB
  3 - Rx: 01 04 04 43 6A 9D 1B E6 87
  4 - Tx: 01 04 00 00 00 02 71 CB
  5 - Rx: 01 04 04 43 6A 6E B1 22 08
  6 - Tx: 01 04 00 00 00 02 71 CB
  7 - Rx: 01 04 04 43 6A 6C 44 E3 2F
*/

/* ******* RESULT ************
  43 67 87 61
  231.53 Volts

  43 67 3E 56
  231.24 Volts

  43 67 3E 56
  231.24 Volts
*/

// RS485 Control pin
const int RS485_control = 2;

// Receive buffer
int Buffer[9];

// This command is to read 2 registers (4 bytes) form meter
// with ID:01 where is Voltage value
int VoltageReadCommand[] = {0x01, 0x04, 0x00, 0x00, 0x00, 0x02, 0x71, 0xCB};


void setup()
{
  // Init serial communication
  Serial1.begin(2400);
  Serial.begin(9600);


  // Set RS485 Control pin to OUTPUT
  pinMode(RS485_control, OUTPUT);

  // Set pin to send data HIGH
  digitalWrite(RS485_control, HIGH);

}

void loop()
{

  // Set pin to HIGH > Transmit mode
  digitalWrite(RS485_control, HIGH);
  delay(10);

  // Send command to ModBus Meter
  for (int i = 0; i < 8; i++) Serial1.write(VoltageReadCommand[i]);

  delay(50);

  // Set pin to LOW > Receive mode
  digitalWrite(RS485_control, LOW);

  // Waiting for receive reply
  while ( Serial1.available() < 9);

  // Read reply in Buffer[];
  for (int i = 0; i < 9; i++) Buffer[i] = Serial1.read();

  // Print voltage data received
  Serial.print(Buffer[3], HEX); Serial.print(" ");
  Serial.print(Buffer[4], HEX); Serial.print(" ");
  Serial.print(Buffer[5], HEX); Serial.print(" ");
  Serial.print(Buffer[6], HEX); Serial.print(" ");
  Serial.println();
  // Convert to Float
  float x;
  ((byte*)&x)[3] = Buffer[3];
  ((byte*)&x)[2] = Buffer[4];
  ((byte*)&x)[1] = Buffer[5];
  ((byte*)&x)[0] = Buffer[6];

  // Convert to Float
  Serial.print(x, 1);
  Serial.println(" Volt");

  delay(1000);

}
[/code]

Ich war unterwegs mit der Lib von Reaper7.
Weil das nicht fluppte dann also zu Fuß analog des Manuals mal die Spannung abfragen. Steht auf pdf-Seite 16.
Was ich halt nicht versteht: der 1. Wert passt, dann kommt ne ganze Weile Unsinn, dann total stabil die Spannung.
Vielleicht hat der Zähler ja ne Macke - hab leider keinen zweiten, und irgendwie geht's ja auch :thinking:

Da läuft nix :thinking:
Ich werde nochmal drüber schlafen - kann helfen.

Ich war mir ja auch nicht sicher - aber das Senden funktioniert zumindest :wink:
Und dann kommt das warten auf 0x01.
Das Problem ist, das Du, wie @noiasca schon schrub, Dir die Kontrollmöglichkeit ausgebaut hast.

ICH würde mir einen anderen HardwareSerial für die Kommunikation aufhalten und dort den RS485-Adapter anbauen.
Damit merzt Du vermutlich mehr als 90% der möglichen Probleme aus.

Hab ich ja, Modbus hängt an Serial1.
Werde mal weiter forschen, muss doch hinzubekommen sein ohne Klimmzüge :neutral_face:

Auflösung: ich hatte auf meiner Anschlussplatine noch ne LED für Tx/Rx dran. Das ist für die üblichen TTL-Interfaces kein Problem und ich konnte so optisch schön sehen, ob Datenverkehr stattfindet.
Der MAX485 als Modbus<>TTL Interface mag das aber offenbar nicht an seiner TTL-TX-Seite. Und obwohl die Pegel per Scopemessung in Ordnung waren, fluppt die Übertragung jetzt ohne die LED vom ersten Anlauf ohne jegliche Aussetzer.
Warum immer der erste Wert mit LED ok war, dann ne Weile Unsinn kam und dann wieder alles glatt lief - keine Ahnung.
Egal - Problem gelöst.
Danke für's Mitlesen und unterstützen :+1:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.