How to read and parse UART HEX data?

@phillip1 makes it look easy and I know that it isn’t easy! Huge thanks!

Basic target location working for the K-LD7!!

A few questions for those experienced with custom devices in ESPHome - how can we avoid the pollingComponent?

Todo:

  • remove polling
  • add the numerous target customization parameters
  • add WLED target tracking
#include "esphome.h"

class kld7 : public PollingComponent, public UARTDevice {
 public:
  kld7(UARTComponent *parent) : PollingComponent(125), UARTDevice(parent) {}
  Sensor *distance_sensor = new Sensor();
  Sensor *speed_sensor = new Sensor();
  Sensor *angle_sensor = new Sensor();
  Sensor *db_sensor = new Sensor();
  
  void setup() override {

  }

  std::vector<int> bytes;

//  void loop() override {  
  void update() {
    while(available() > 0) {
      bytes.push_back(read());      

      //make sure at least 8 header bytes are available to check
      //ESP_LOGD("custom", "checking for RESP");
      if(bytes.size() < 8)       
      {
        continue;  
      }
      //ESP_LOGD("custom", "checking bytes");
      if(bytes[0] != 0x54 || bytes[1] != 0x44 || bytes[2] != 0x41 || bytes[3] != 0x54 || bytes[4] != 0x08 || bytes[5] != 0x00 || bytes[6] != 0x00 || bytes[7] != 0x00) {
      //if(bytes[9] != 0x54 || bytes[10] != 0x44 || bytes[11] != 0x41 || bytes[12] != 0x54 || bytes[13] != 0x08 || bytes[14] != 0x00 || bytes[15] != 0x00 || bytes[16] != 0x00) {
        bytes.erase(bytes.begin()); //remove first byte from buffer
        //buffer will never get above 8 until the header is correct
        continue;
      }      
      //ESP_LOGD("custom", "TDAT bytes");
      if(bytes.size() == 16) { //>=
	//ESP_LOGD("custom", "Found TDAT: %X", bytes);
        //ESP_LOGI("test", "data: 0:%d, 1:%d, 2:%d, 3:%d, 4:%d, 5:%d, 6:%d, 7:%d, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]);
        TwoByte distance;
        distance.Byte[0] = bytes[8];
        distance.Byte[1] = bytes[9];  
        distance_sensor->publish_state(distance.UInt16);
        //id(distance_sensor).publish_state(distance.UInt16);
	//ESP_LOGD("custom", "Parsed distance: %i", distance.UInt16);

        TwoByte speed;
        speed.Byte[0] = bytes[10];
        speed.Byte[1] = bytes[11];  
        speed_sensor->publish_state(speed.Int16/100);
        //id(speed_sensor).publish_state(speed.Int16/100);
	//ESP_LOGD("custom", "Parsed speed: %i", speed.Int16);

        TwoByte angle;
        angle.Byte[0] = bytes[12];
        angle.Byte[1] = bytes[13];  
        angle_sensor->publish_state(angle.Int16/100);
        //id(angle_sensor).publish_state(angle.Int16/100);
	//ESP_LOGD("custom", "Parsed angle: %i", angle.Int16);

        TwoByte db;
        db.Byte[0] = bytes[14];
        db.Byte[1] = bytes[15];  
        db_sensor->publish_state(db.UInt16/100);
        //id(db_sensor).publish_state(db.UInt16/100);
	//ESP_LOGD("custom", "Parsed db: %i", db.UInt16);

        bytes.clear();
      }
      else {
        //ESP_LOGD("custom", "no bytes");
      }    
    }    
  }

  typedef union
  {
    unsigned char Byte[2];
    int16_t Int16;
    uint16_t UInt16;
    unsigned char UChar;
    char Char;
  }TwoByte;};
1 Like