Serial Kommunikation Autoterm Heizung

Moin

Ich würde gerne mit einem Arduino über Serial mit einer Autoterm Air 2D Heizung kommunizieren.
Allerding ist mein Wissen was den Aufbau von Serieller Kommunikation angeht gleich null.
Daher wäre ich sehr dankbar um jede Hilfe.

Die Schnittstelle wurde hier schonmal dokumentiert.
GitHub - schroeder-robert/autoterm-air-2d-serial-control: Serial protocol to control an autoterm diesel heater and gain information from it.

Vielen Dank!

Gruß Schlaubi
(der im diesem Falle nicht so schlau ist. :sweat_smile:)

Frage: Die Hardware - incl. USB/Serial-Adapter hast Du?

Das Protokoll ist recht einfach gestrickt.
Was willst Du machen?
Auf einem Display anzeigen und mit ein paar Buttons ein/aus schalten?
Was noch?
Schreib mal drei Worte zu Deinem Vorhaben...

Mit serieller Kommunikation alleine ist es nicht getan.

Wie sieht es denn mit Programmierwissen in der Sprache C++ im allgemeinen aus?

  • auch null wissen
  • Anfänger
  • ein bisschen fortgeschritten
  • fortgeschritten

vgs

Moin ihr beiden

Also...

... zum Ziel:
Langfristig soll der Arduino als als Brücke zwischen einem CAN-Bus System, und der Heizung dienen. Und dabei die Befehle aus dem CAN an die Heizung weiterleiten. Sowie die Temperatur und den Fehlercode auslesen.
Kurzfristig werde ich erstmal Taster für EIN und AUS anschließen und die Temperatur nur auf dem SerialMonitor ausgeben.

... zur Hardware:
Als Hardware soll ein Arduino Micro etc. zum Einsatz kommen der mit der Heizung kommuniziert. Dabei soll die Serielle Schnittstelle bzw. Softserial des Arduinos genutzt werden.

... zur Software:
Mir geht es in erster Linie darum wie ich das Eingelesene so zerlege um die nötigen Infos daraus zu ziehen. Bzw wie ich die die Befehle passend Verpacke.

Vielen Dank!

arbeite das Tutorial durch:

es ist imho die erste Anlaufadresse für "Serielle Kommunikation".

Wenn du die Beispiele durchgemacht hast, bist du wieder ein @schlaubi in Serial Themen.

Irgendwie fehlt mir noch...
Wenn man Dir was an die Hand gibt, bekommst Du das aufgespiekt und kannst dazu live Kommunikation aufbauen?

Ich würde Dir zum Verständnis wie man mit dem Ding kommuniziert Schritt für Schritt was schreiben, bin aber drauf angewiesen dass Du das auch nutzen kannst und mir erzählst was das Ergebnis ist.

Ich denke das sollte ich hinbekommen.

Die Serial Basics die noiasca repostet hat, haben mir schon etwas geholfen.
Einfache serielle Kommunikation wie im Beispiel 1&2 habe ich auch schon mal gemacht.
Nur bei aufeinander folgende Hex-Werten hörte dann mein Wissen auf.
Dank dem Beispiel 6 habe ich schon mal einen Überblick.

Wenn du (my_xy_projekt) bereit wärst mir etwas vorzubereiten, was ich dann weiter ausbauen kann, wäre ich sehr dankbar.

Die Vorbereitung kannst du zum größten Teil selbst machen:
Vergleiche bei den Header-Bytes welche Bytes haben immer den gleichen Wert
welche Bytes haben unterschiedliche Werte.

Die Header-Bytes die immer den gleichen Wert haben kann man als Startbyte nehmen

Das ist dann das Serial Inputbeispiel mit Anfangserkennung
Du kannst dir die hexadezimalen Werte mit tausenden onlinetools auf dezimal umrechnen
oder du schreibst die hexadezimalen Werte mit einem vorangestellten " 0x "

Beispiel: Hexadzimal 0F ist in C++

0x0F

vgs

Ich bau Dir zu morgen was zusammen.
Was für einen Controller hast Du jetzt zur Verfügung?
Im ersten Schritt würde ich nur Zustände auslesen lassen und auf dem Seriellen Monitor ausgeben.
Da sind dann so basics drin wie crc berechnen, message senden und einlesen auf der Seriellen. Das reicht dann für alles andere.

Der Start Marker in meinem Falle ist dann ja x0AA .
byte startMarker = 0xAA;

Wie wäre in meinem Falle der Endmarker? Gibt es in dem Falle überhaupt einen?
Theoretisch bildet ja die Checksum immer das Ende.

Die Anzahl der zu erwartenden Bytes müsste dann ja 8 sein, richtig?
const byte numBytes = 8;

Versuche mal, wenn ich wieder an der Hardware bin mit den Werten und dem Beispiel zu testen.

@my_xy_projekt Am liebsten würde ich das ganze mit einem Micro lösen. Der ist von der Baugröße nicht so groß. Sollte es ein anderes Board besser geeignet sein bin ich dafür auch offen.

Da gibt es keinen.
Die Länge ergibt sich auf Startsequenz, payloadlength + 2

Nein.

Ich will wissen, was Du jetzt hast.

nicht immer
Das variiert dann doch ziemlich stark. Abhängig vom fünften Headerbyte

Für 0x01 turn heater on sind es mit checksum 8 bytes
für 0x06 getversion sind es mit checkusm 7 bytes
für 0x0F get status sind es mit checksum 21 bytes

im dritten byte des headers steht die Anzahl der payload-bytes.
Daraus ergibt sich dann die Position der Checksum-bytes.
Ob man eine gültige Message empfangen hat wird dann anhand der Checksumme geprüft.

Die Bytes vor der checksum werden mit dem checksum algorithmus miteinander verwurstet.
Message ist gültig wenn die errechnete checksum mit der empfangenen checksum übereinstimmt.

vgs

Da ich noch immer nicht weiss, was Du hast, hier das Grundgerüst.
Mach was draus.

// Forensketch Send & receive -> Heater
// https://forum.arduino.cc/t/serial-kommunikation-autoterm-heizung/1179098

#include <Streaming.h>     // https://github.com/janelia-arduino/Streaming

#include "SoftwareSerial.h"
SoftwareSerial TermSerial(10, 11); // RX, TX


// #define DEBUG              // Wenn aktiviert, werden Zwischenwerte ausgegeben

#ifdef DEBUG
  #define DBG_PRINTLN(...) Serial << __VA_ARGS__ << endl
#else
  #define DBG_PRINTLN(...)
#endif


constexpr byte maxLen {255};

byte sendBuf[maxLen + 7] = {'\0'};

void setup()
{
  Serial.begin(115200);
  TermSerial.begin(9600);
  while (TermSerial.available())
  { TermSerial.read(); }
  TermSerial.flush();
#if (defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2650)) // https://github.com/arduino/Arduino/issues/10764
  delay(300);
#endif
  Serial << (F("\r\nStart...\r\n")) << endl;
  DBG_PRINTLN(__FILE__);
  DBG_PRINTLN( __TIMESTAMP__);
}

void  loop()

{
  readTerm();
  pingTerm();
}

void readTerm()
{
  static byte buf[maxLen + 7] = {'\0'};           //
  static byte idx = 0;                            //
  byte count = TermSerial.available();            // Daten vorhanden?
  while (count--)                                 // Solange Daten
  {
    { buf[idx++] = TermSerial.read(); }           // auslesen
    if (buf[0] != 0xAA)                           // kein Start erkannt?
    { clearBuf(buf, idx, sizeof(buf)); }          // Clear
    if (idx >= buf[2] + 7)                        // Nachricht vollständig
    {
      if ((buf[1] == 0x03) && validate(buf))      // und zulässig
      {
        splitMessage(buf);                        // dann mach was
      }
      clearBuf(buf, idx, sizeof(buf));            // Alles auf Anfang
    }
  }
}
//
bool validate(const byte *buf)
{
  uint16_t msgCrc = buf[buf[2] + 5] << 8 | buf[buf[2] + 6];
  DBG_PRINTLN("validate CRC: " << _HEX(msgCrc));
  return msgCrc == makeCrc(buf, buf[2] + 5);
}
//
void splitMessage(const byte *buf)
{
  // Hier wird später weiter gemacht
  Serial << "empfangene Nachricht: ";
  for (byte b = 0; b < buf[2] + 7; b++)
  { Serial << "0x" << _HEX(buf[b]) << ", "; }
  Serial << endl;
}
//
void pingTerm()
{
  constexpr uint32_t interval {2000};
  static uint32_t lastmillis = 0;
  if (millis() - lastmillis > interval)
  {
    lastmillis = millis();
    const byte sendBuf[] = {0xAA, 0x03, 0x00, 0x00, 0x04,};
    sendMessage(sendBuf);
  }
}
//
uint16_t makeCrc(const byte *buf, const byte &len)
{
  uint16_t crc = 0xFFFF;
  for (byte b = 0; b < len; b++)
  {
    crc = crc ^ buf[b];
    for (byte i = 0; i < 8; i++)
    {
      bool c = crc & 0x0001;
      crc >>= 1;
      if (c)
      { crc ^= 0xA001; }
    }
  }
  DBG_PRINTLN("CRC errechnet: " << _HEX(crc));
  return crc;
}
//
void sendMessage(const byte *buf)
{
  uint16_t msgLen = buf[2] + 5;
  uint16_t crc = makeCrc(buf, msgLen);
  for (byte b = 0; b < msgLen; b++)
  {
    TermSerial.write(buf[b]);
    // Serial << "0x" << _HEX(buf[b]) << ' ';
  }
  TermSerial.write(crc);
  // Serial << _HEX(crc) << endl;
}
//
void clearBuf(byte *buf, byte &idx, uint16_t bufLen)
{
  memset(buf, '\0', bufLen);
  idx = 0;
}

das Beispiel 6 ist esentiell.
F1: Hast du das soweit mal durchgemacht und für deine Heizung mal probiert?

F2: Was genau möchtest du eigentlich mit deiner Heizung "kommunizieren"? nur ein/ausschalten?

F3: Welche Werte möchtest du Abfragen, welche Parameter möchtest du ändern können?

F4: Es scheint ja viel möglich zu sein, aber was willst du konkret machen?

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