Softwareserial binär daten lesen

zum einlesen in das Thema "Serielle Schnittstelle lesen" rate ich dir zu den "Serial Input Basics"
https://forum.arduino.cc/t/serial-input-basics-updated/382007

edit
hab mal rumgespielt *)

/*
   Atorch
   https://github.com/NiceLabs/atorch-console/blob/master/docs/protocol-design.md

   Serial Receive Example for two byte magic header, Message Type, Variable Payload, Checksum

   Valid telegram
   FF55010100090400000E0000040000000000006401F40085002F00000A093C0000000039
   FF55010200011A00003C0004D40000002000006400000000002600590D363C00000000F0
   FF55010200011A0000000004D40000002000006400000000002A00590E343C000000003F
   FF55010200011A00003C0004D40000002000006400000000002600590D363C00000000F0
   FF5501030001F3000000000638000003110007000A000000122E333C000000000000004E

   by noiasca
   2022-04-01
*/

class Atorch {
  protected:
    static const byte numChars = 36;   // receiver buffer size
    byte receivedChars[numChars];      // an array to store the received data
    byte ndx = 0;                      // length of received message
    boolean newData = false;           // flag to indicate when new data is complete
    Stream &stream;                    // a reference to the serial interface
    void (*cbOnNewData)();             // gets called after we received a full message

    void delBuffer()
    {
      memcpy(receivedChars, "", sizeof(receivedChars));
      ndx = 0;
    }

    void debugDataHex()
    {
      for (size_t i = 0; i < ndx; i++)
      {
        if (receivedChars[i] < 0x10) Serial.print('0');
        Serial.print(receivedChars[i], HEX);
        Serial.print(' ');
      }
      Serial.println();
    }

    void parseData()                   // parse data and store to internal variables
    {
      deviceType = receivedChars[3];
      if (deviceType == 1 || deviceType == 2 || deviceType == 3)
      {
        voltage = ((uint32_t)receivedChars[4] << 16 ) + (receivedChars[5] << 8) + receivedChars[6];
        amp = ((uint32_t)receivedChars[7] << 16 ) + (receivedChars[8] << 8) + receivedChars[9];
        wh = ((uint32_t)receivedChars[0x0D] << 24 ) + ((uint32_t)receivedChars[0x0E] << 16 ) + (receivedChars[0x0F] << 8) + receivedChars[0x10];
      }
      if (deviceType == 1)
      {
        price = ((uint32_t)receivedChars[0x11] << 16 ) + (receivedChars[0x12] << 8) + receivedChars[0x13];
        frequency = (receivedChars[0x14] << 8) + receivedChars[0x15];
      }
      if (deviceType == 1 || deviceType == 2)
      {
        watt = ((uint32_t)receivedChars[0x0A] << 16 ) + (receivedChars[0x0B] << 8) + receivedChars[0x0c];
        powerfactor = (receivedChars[0x16] << 8) + receivedChars[0x17];
        temperature = (receivedChars[0x18] << 8) + receivedChars[0x19];
        hour = (receivedChars[0x1A] << 8) + receivedChars[0x1B];
        minute = receivedChars[0x1C];
        second = receivedChars[0x1D];
        backlight = receivedChars[0x1E];
      }
      if (deviceType == 3)
      {
        ah = ((uint32_t)receivedChars[0x0A] << 16 ) + (receivedChars[0x0B] << 8) + receivedChars[0x0c];
        usbdminus = (receivedChars[0x11] << 8) + receivedChars[0x12];
        usbdplus =  (receivedChars[0x13] << 8) + receivedChars[0x14];
        //temperature = ((uint32_t)receivedChars[0x15] << 16 ) + (receivedChars[0x16] << 8) + receivedChars[0x17];
        temperature = (receivedChars[0x15] << 8) + receivedChars[0x16];
        hour = (receivedChars[0x17] << 8) + receivedChars[0x18];
        minute = receivedChars[0x19];
        second = receivedChars[0x1A];
        backlight = receivedChars[0x1B];
      }
    }

    bool validateChecksum()            // validate if checksum of telegram is correct
    {
      return true;                     // todo: implement validate
    }

    void parseLine()                   // process a telegram
    {
      //Serial.print(F("I64: This is just in:")); Serial.println(receivedChars);         // output all
      Serial.print(F("I65: This is just in:")); debugDataHex();                          // output all
      if (validateChecksum())
      {
        parseData();
        if (cbOnNewData) cbOnNewData();
      }
    }

  public:
    byte messageType = 0;
    // payload data
    byte deviceType = 0;
    uint32_t voltage = 0;
    uint32_t amp = 0;
    uint32_t ah = 0;          // deviceType 3
    uint32_t watt = 0;
    uint32_t wh = 0;
    uint32_t price = 0;
    uint16_t frequency = 0;   // deviceType 1
    uint16_t powerfactor = 0; // deviceType 1
    uint16_t usbdminus = 0;   // deviceType 3
    uint16_t usbdplus = 0;    // deviceType 3
    int16_t temperature = 0;
    uint16_t hour = 0;
    uint8_t minute = 0;
    uint8_t second = 0;
    uint8_t backlight = 0;

    Atorch (Stream &stream) : stream(stream)
    {
      delBuffer();
    }

    void setOnNewData(void (*cbOnNewData)())     // set a callback function. Gets called when new data was received
    {
      (*this).cbOnNewData = cbOnNewData;
    }

    void update()                                // run this member function in loop()
    {
      constexpr byte startMarker = 0xFF;         // start flag
      constexpr byte secondMarker = 0x55;
      if (stream.available() > 0) {
        char rc = stream.read();
        // restart on FF 55
        if (ndx > 0 && receivedChars[ndx - 1] == startMarker && rc == secondMarker)
        {
          delBuffer();
          receivedChars[0] = startMarker;
          receivedChars[1] = rc;
          ndx = 2;
        }
        else
        {
          receivedChars[ndx] = rc;
          if (ndx == 2) messageType = rc;
          ndx++;
        }

        // parse data on reached packet length
        if (messageType == 1 && ndx == (2 + 1 + 32 + 1)) parseLine();

        // sanity check
        if (ndx >= numChars) delBuffer();
      }
    }
};

// create the sensor object and hand over the Serial interface to use:
HardwareSerial &mySerial = Serial;
Atorch device(mySerial);                  // use Hardware Serial (for example for testing with the PC)

//#include <SoftwareSerial.h>             // on an Uno you can use SoftSerial
//SoftwareSerial mySerial(2, 3);          // RX, TX
//Atorch device(mySerial);                // on an UNO you will need SoftSerial to connect to the device

// On a Mega you can simply use
// a Reference to an existing HW Serial:
//HardwareSerial &mySerial = Serial1;
//Atorch device(mySerial);

void output()                           // simple output of data
{
  Serial.print(F("deviceType= ")); Serial.print(device.deviceType); Serial.println();
  if (device.deviceType == 1 || device.deviceType == 2)
  {
    Serial.print(F("voltage=    ")); Serial.print(device.voltage / 10.0); Serial.println('V');
    Serial.print(F("amp=        ")); Serial.print(device.amp / 1000.0); Serial.println('A');
    Serial.print(F("watt=       ")); Serial.print(device.watt / 10.0); Serial.println('W');
    Serial.print(F("wh=         ")); Serial.print(device.wh / 100.0); Serial.println(F("Wh"));
    Serial.print(F("price=      ")); Serial.print(device.price / 100.0); Serial.println(F("/KWh"));
  }
  if (device.deviceType == 1)
  {
    Serial.print(F("powerfactor=")); Serial.print(device.powerfactor / 1000.0); Serial.println();
    Serial.print(F("frequency=  ")); Serial.print(device.frequency / 10.0); Serial.println(F("Hz"));
  }
  if (device.deviceType == 3)
  {
    Serial.print(F("voltage=    ")); Serial.print(device.voltage / 100.0); Serial.println('V');
    Serial.print(F("amp=        ")); Serial.print(device.amp / 100.0); Serial.println('A');
    Serial.print(F("ah=         ")); Serial.print(device.ah / 1000.0); Serial.println(F("Ah"));
    Serial.print(F("wh=         ")); Serial.print(device.wh / 100.0); Serial.println(F("Wh"));
    Serial.print(F("usbdminus=  ")); Serial.print(device.usbdminus / 100.0); Serial.println();
    Serial.print(F("usbdplus=   ")); Serial.print(device.usbdplus / 100.0); Serial.println();
  }
  Serial.print(F("temperature=")); Serial.print(device.temperature); Serial.println('C');
  Serial.print(F("durance=    ")); Serial.print(device.hour); Serial.print(':'); Serial.print(device.minute); Serial.print(':'); Serial.println(device.second);
  Serial.print(F("backlight=  ")); Serial.print(device.backlight); Serial.println();

}

void timerOutput()                     // a timer to output data to serial
{
  static uint32_t previousMillis = 0;  // time management
  const uint16_t interval = 3000;      // interval to display data
  if (millis() - previousMillis >= interval)
  {
    previousMillis = millis();
    output();
  }
}

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  //device.setOnNewData(output);  // register a callback function which gets called when a new telegram was received
}

void loop() {
  device.update();                // you must call the .update() method in your loop()
  timerOutput();
}

ergibt für
FF55010200011A00003C0004D40000002000006400000000002600590D363C00000000F0

voltage=    28.20V
amp=        0.06A
watt=       98.00W
wh=         0.32Wh
price=      1.00/KWh
temperature=38C
durance=    89:13:54

*) vieles noch zu tun!(!!!)
kein copy/paste sketch!
Ausgangsbasis war mein Sketch von https://werner.rothschopf.net/microcontroller/202201_a02yyuw_ultrasonic_sensor_en.htm

edit 20220401 15:26 noch mal kleines update. Sollte jetzt für alle 3 deviceType funktionieren.