SMA Wechselrichter mit RS485 / modbus auslesen

Hallo zusammen,

ich würde gerne meinen SMA Wechselrichter (SMA STP 80) der an unserer Fotovoltaik Anlage hängt, mittels Arduino auslesen.

Der Wechselrichter selbst hat eine RS485 Schnittstelle.

Jetzt hab ich bereits die technische Info über die Register gefunden.
Darin ist als Protokoll das „modbus Protokoll“ erwähnt wobei dieses mit gerätespezifischen Modbus-Profilen funktioniert (SMA Modbus-Profil und das SunSpec Modbus-Profil)

Da ich RS485 und modbus noch recht unerfahren bin, versteh ich nur Bahnhof.

Hardware hab ich bereits.
Zum Testen zwei Nanos mit RS485 TTL umsetzen.
Hat auch gut funktioniert. (Aber waren sehr einfache Beispiele).

Kann mir jemand einen Tipp geben?
Bei Onkel google komm ich irgendwie nicht weiter…

Oder hat jemand sogar einen Beispiel Code für den SMA?
EDMx-Modbus-TI-de-16.pdf (187,6 KB)

Hatten wir grad vor ein paar Tagen ein Beispiel: PV Wechselrichter auslesen - #18 by noiasca
Vielleicht hilfts ja...

Hi, danke!
hab ich gesehen aber was bedeutet für mich "SMA Modbus-Profil und das SunSpec Modbus-Profil"?

Und bei diesem Beispiel sehe ich den "code" nicht an dem die entsprechenden Register angefordert werden.
Oder bin ich falsch?

Schaust du hier und hier

Hi,
danke!!!
Aber genau jetzt wirds für mich etwas suspekt.
Benötige ich mit dem modbus auf der RS485 Schnittstelle eine Portfreigabe?
Ne oder?

Über den Modbus und der RS485 Schnittstelle spricht man doch die Register direkt an oder etwa nicht?

Ich bin verwirrt :crazy_face:

RS485 ist die technische Übertragung, Modbus das Protokoll. Das hat nix mit Ports zu tun, du hängst quasi an einem seriellen Bus mit mehreren Teilnehmern. Das funktioniert, weil Modbus regelt, dass immer nur ein Client (bist in dem Falle du mit deinem Arduino) eine Frage stellen darf (Request) und ein angesprochener Server (dein Wechselrichter) antworten soll (Response).

Hallo zusammen nochmals,

ich hab mich jetzt den halben Mittag durch die Unterlagen gewälzt.
Leider hab ich irgendwo ein (Denk)Fehler oder sonst etwas.

Mal meine Fakten:

Ich hab ein SMA STP80 Wechselrichter mit einer RS485 Schnittstelle auf einem M12 Stecker.
image

Dort Angeschlossen hab ich A/B und Masse. Die 12V kommen sozusagen raus...

Als RS485 TTL Umsetzer habe ich einen selfsensing adapter.

Aus der SMA Modbus Schnittstelle wie ich sie oben bereits verlinkt habe, möchte ich primär das Registrer

Vom Wechselrichter intern habe ich folgende Infos:

Auf Grundlage des Verlinkten Beispieles habe ich folgenden Sketch:

/* *******************************************************
   Serial Interface
 * **************************************************** */
#include <SoftwareSerial.h>
constexpr uint8_t rxPin = 10;                   // for Softserial
constexpr uint8_t txPin = 11;
SoftwareSerial mySerial(rxPin, txPin);

/* **************************************************** *
   Modbus
 * **************************************************** */
#include <ModbusMaster.h>                        // Modbus Master 2.0.0 by Doc Walker - install with Library Manager
constexpr uint8_t modbusEnablePin = 255;         // The GPIO used to control the MAX485 TX pin. Set to 255 if you are not using RS485 or a selfsensing adapter
constexpr uint32_t modbusBaud = 1200;            // use slow speeds with SoftSerial
constexpr uint16_t modbusRestTx = 15000;         // rest time between transmissions - microseconds
uint32_t modbusPreviousTx = 0;                   // timestamp of last transmission - microseconds
ModbusMaster serverA;                            // instantiate ModbusMaster object - slave - node

// this function will be called before the client transmits data
void preTransmission()
{
  while (micros() - modbusPreviousTx < modbusRestTx)   // check last transmission end and wait if the call was to early
  {
    yield();                                           // wait some time and allow background tasks
  }
  digitalWrite(modbusEnablePin, HIGH);
}

// this function will be called after the transmission
void postTransmission()
{
  digitalWrite(modbusEnablePin, LOW);
  modbusPreviousTx = micros();         // remember last timestamp
}

// do all the settings for the Modbus
void modbusInit()
{
  mySerial.begin(modbusBaud);                     // initialize Modbus communication baud rate
  serverA.begin(3, mySerial);                     // communicate with Modbus server ID over the given Serial interface
  pinMode(modbusEnablePin, OUTPUT);               // Init enable pins for modbus master library
  digitalWrite(modbusEnablePin, LOW);
  serverA.preTransmission(preTransmission);       // Callbacks allow us to configure the RS485 transceiver correctly
  serverA.postTransmission(postTransmission);
}

// getdata from Modubs Server(Slave) and print to Serial
void requestData()
{
  constexpr uint16_t interval = 5000;             // interval of modbus requests
  static uint32_t previousMillis = -interval;     // timestamp of last request
  static uint8_t actual = 0;                      // actual iteration
  uint32_t currentMillis = millis();

  if (currentMillis - previousMillis > interval)  // set the interval in ms
  {
    previousMillis = currentMillis;
    uint16_t reg = 0x7837;
    int result;
    result = serverA.readInputRegisters(reg, 2);  // request from startregster, n Registers
    if (result == serverA.ku8MBSuccess)           // do something if read is successfull
    {
      Serial.print(F("Register 1:     ")); Serial.println(serverA.getResponseBuffer(0x00));
      Serial.print(F("Register 2:     ")); Serial.println(serverA.getResponseBuffer(0x01));
    }
    else
    {
      Serial.print(F(" ServerA no success register ")); Serial.print(reg, HEX); Serial.print(F(" result=")); Serial.println(result, HEX);
    }
  }
}
/* **************************************************** *
   setup and loop
 * **************************************************** */

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Modbus Client Example D 485 halfduplex"));

  modbusInit();
}

void loop()
{
  requestData();
}

Im Seriellen Monitor bekomm ich nur die Meldung:
image

Die TX LED auf dem Adapter geht aber schön im Rythmus an.

Hat einer eine Idee wo der Fehler liegt?
(ja ich weiß, ca. 70cm vor dem Monitor :smiling_face:)

Bei ModbusMaster ist der Fehlercode E2 als ku8MBResponseTimedOut = 0xE2; definiert. Da fühlt sich also niemand angrsprochen. Server-ID, Baudrate etc. hast du gecheckt?

0xE2 ist leider gar nicht gut ...

vieleicht die Anschlüsse A / B mal drehen.
mal GND weglassen
auch wenns entgegen der Doku ist, mal mit id 1 oder 2 probieren (was sie da mit den Unit-ID's im Kapitel 3.4.1 meinen kann ich noch nicht ganz nachvollziehen).

Hast du einen USB-RS485 Wandler? Kannst mal direkt mit dem PC versuchen ein Paket zu senden?

Ich hab die Daten AUS dem Wechselrichter

OK ich probier es Mal... Leider hab ich kein USB Umsetzer.

Aber den Fehler auf "da antwortet keiner" eingrenzen zu können ist schon Mal gut.

Gibts dafür eine Quelle?
Nicht das der noch irgendwas braucht....

@nasly-one
Bilder von der Verkabelung wären auch nicht schlecht.
Welchen Arduino verwendest du?
Hat der 485 Adapter irgendwelche LEDs die bei Kommunikation blinken sollen - und was tun sie wirklich?

P.S.: du bist zwar noch nicht so weit, aber als Input Register musst du vermutlich nicht 0x7837 sondern ich glaube eher 30775-30001 = 774 (dec) angeben. ... Die "Adresse" 30775 steht eigentlich bei Unit=2.

Ja hab ich vor paar Tagen auf Amazon gekauft um schon Mal zu spielen.

https://www.amazon.de/gp/product/B09VGJCJKQ/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1

Für den Testaufbau ein Nano.
Ja die TX Led des Umsetzers geht schon im Rhythmus an.

Meine ersten Testaufbauten von Nano zu Nano mit den selben Umsetzern haben auch funktioniert ohne den enable Pin

schick mal was an slave 2 ... blinkt RX?
schick mal was an slave 1 ... blinkt RX?

Oh... Also die brauchen definitiv die vollen 5V.
Und dann nochmal die Pins genau verfolgen, ob die Beschriftung für TX/RX stimmt.

Aus der Rezension:

Morgen zusammen,
also viel neue Erkenntnisse gibt es bei mir nicht.
Ich schreib euch mal was ich versucht habe.
Habe auch Kombinationen aus 1, 2 und 3 Pobiert…

  1. Bezüglich des RS485 Moduls habe ich RX und TX getauscht, RX und TX zusammen verbunden.

ohne Erfolg.
Natürlich ändert sich dann die Anzeige der LEDs entsprechend, aber mehr auch nicht.

  1. Hab mit der Bautrate und mit der ID (wobei man dieses Kombinationsspiel ja endlos treiben könnte)

auch ohne Erfolg.

  1. Ich hab die Verkabelung von A und B getauscht.

hier bekomm ich dann die Fehlermeldung im Seriellen Monitor E0.

Irgendwie komm ich da nicht weiter.
Kann man eigentlich irgendwie feststellen ob am anderen Ende überhaupt „jemand ist“?
Wenn ich zum Beispiel die Spannung zwischen A und B messe, habe ich 5V > das sollte doch soweit stimmen oder?

Wie lang ist das Kabel zwischen Wechselrichter und deinem Board?

Die Spannung ist weitgehend egal, da die RS485-Übertragung auf Spannungsdifferenz beruht.
Hast du ein Oszi verfügbar, mit dem du das Differenzsignal zwischen A und B sichtbar machen kannst?

wenn du mehrere RS485 - TTL board hättest, könntest du auf einem anderen Nano einen einfachen Passthrough sketch laden und diesen auch in den Bus hängen.
Dann

  • in einem anderen seriellen Monitor mitlesen was dein Master raussendet und eventuell etwas vom Slave hören.
  • und ob es in der Variante A/B getauscht und Fehlermeldung "0xE0" - tatsächlich etwas vom Slave war
    /**
    ModbusMaster invalid response slave ID exception.
    
    The slave ID in the response does not match that of the request.
    
    @ingroup constant
    */
    static const uint8_t ku8MBInvalidSlaveID             = 0xE0;

weiters hast du noch nicht geschrieben was passiert wenn du Slave 1 oder 2 addressierst.

Im Moment ca 3 Meter, ist auch gerade kein twisted Kabel ≥ könnte ich aber kürzen

Uff, ne hab ich nicht.

Ah, sorry. Also bezogen auf die "ersten Einstellungen" ≥ keine Änderungen... Fehler E2

Hätte ich und könnte ich machen.
Gibt es hierzu einen fertigen Sketch, nicht dass ich hier nor herumeiere ob dieser dann passt.. :face_with_peeking_eye: