Задать вопрос
@Tiamon

Arduino ESP32 UART Serial разбор и сравнение byte, как правильно?

Пытаюсь сделать датчик движения и присутствия на ESP32 с LD1115H, знаю, что есть готовое для ESPhome но не подходит.
Документашка https://drive.google.com/drive/folders/146DzpWDM8A...
Готового варианта под Arduino не нашел, и опыта большого по работе с "С" нет.
Датчик подключается по хардверному serial, данные поступают типа
mov, 12 1234(конец строки)
или
occ, 3 45678(конец строки)
или если нет никто
null(конец строки)
Данные не строкой, проще говоря Serial2.readString() не работает, можно получить побайтово и преобразовать в символ, по одному символу за проход
Ещё вариант с Serial2.readBytes(buf, rlen) попробовал

Вопрос, как вообще правильно с этим работать? Как получить данные из serial и на пример выделить "mov" или "occ" сравнить с заданными параметрами и понять состояние датчика. Там ещё проблема с типами данных, не все можно в лоб сравнить с byte или char, тем более string.
На сколько понял ещё накладываются особенности работы с ESP32 и более строгое отношение к типам, часто ошибка "что то там с сравнением холодного с мягким, нельзя, [-fpermissive]".

Датчик ещё и управляется через команды, туда даже смотреть страшно )
И вопросы:
Нужно ли преобразовывать данные или правильно работать с байтами, как есть? Данные набирать в массив или собирать в одно "строку"?
Короче мозг закипел, два дня кипит, нужна помощь знающих людей, направьте неофита в правильное русло )

Не знаю нужны ли примеры того, что я уже пробовал, это скорее куски кода, чисто понять, что приходит и что я могу с этим сделать, на пример, пробовал, что ни будь с байтами, пробовал преобразовывать и т.д.:
const int BUFFER_SIZE = 8;
char buf[BUFFER_SIZE];
#define RXp2 16
#define TXp2 17
char myStr[30];


void setup() {
Serial.begin(115200);
Serial2.begin(115200);
}

void loop() {
//   // check if data is available
//   if (Serial2.available() > 0) {
//     // read the incoming bytes:
//     int rlen = Serial2.readBytes(buf, BUFFER_SIZE);

//     // prints the received data
// //    Serial.print("I received: ");
//     for(int i = 0; i < rlen; i++)
//       Serial.println(buf[i]);
//   }

  // check if data is available
  int rxlen = Serial2.available(); // number of bytes available in Serial buffer
  if (rxlen > 0) {
    int rlen; // number of bytes to read
    if (rxlen > BUFFER_SIZE) // check if the data exceeds the buffer size
      rlen = BUFFER_SIZE;    // if yes, read BUFFER_SIZE bytes. The remaining will be read in the next time
    else
      rlen = rxlen;

    // read the incoming bytes:
    rlen = Serial2.readBytes(buf, rlen);

//    Serial.print("I received: ");
    for(int i = 0; i < rlen; i++){
      String endMarker = '\0';
      Serial.print(buf[i]);
      char rc = buf[i];
      String rc1 = String(rc);
      if (rc1 == endMarker){
        Serial.println("----------------------");
      }
    }
}


Это не работает, пример от куда-то из сети

enum names {
  occ1,   // 0
  mov1,   // 1
};

#define RXp2 16
#define TXp2 17
// строки текстовых команд
const char *headers[]  = {
  "occ",   // 0
  "mov",   // 1

};
// соответствующие им названия для commandsTick

int prsValue = 0;
boolean recievedFlag;
names thisName;
int thisName1;
byte comm_amount = sizeof(headers) / 2;
void setup() {
Serial.begin(115200); // Обычная скорость передачи данных аппаратного UART порта (используем для проверки получения данных от другого контроллера)
Serial2.begin(115200, SERIAL_8N1, RXp2, TXp2);
//  Serial.setTimeout(100);   // установка таймаута для readString (мс) (по умолчанию слишком длинный)
}
void loop() {
  serialTick();     // обработка команд из порта
  commandsTick();   // отработка полученных команд
  while (Serial2.available()) Serial.write(Serial2.read());
}
void commandsTick() {
  if (recievedFlag) {
    recievedFlag = false;
    switch (thisName1) {
      case occ1:
        Serial.print("occ1 ");
        Serial.println(prsValue);
        break;
      case mov1:
        Serial.print("mov1 ");
        Serial.println(prsValue);
        break;
    }
  }
}
// опросчик и парсер сериал
void serialTick() {
  if (Serial2.available()) {                 // проверка данных на вход
    String buf = Serial2.read();           // читаем как string
    for (int i = 0; i < comm_amount; i++) {    // пробегаемся по всем именам
      if (buf.startsWith(headers[i])) {         // если совпадаем по названию
        String thisHeader = headers[i];         // костыль
        prsValue = buf.substring(thisHeader.length()).toInt();  // перевод в int
        recievedFlag = true;                    // флаг
        thisName1 = i;                           // запоминаем номер команды
        // if (i == 1){
        //   thisName1 = 1;
        // }
      }
    }
  }
}
  • Вопрос задан
  • 829 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 2
milssky
@milssky
Координатор племени фиолетовых обезьянок
Раз это байты, а хочется работать со строками, то алгоритм на части делится:
1. Получение всей посылки в виде строки побайтово
2. Парсинг строки
3. Дальнейшая обработка поступивших данных.
Ответ написан
@Tiamon Автор вопроса
В общем проект готов, кому интересно https://github.com/stiamon77/AQST-MS/
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@EgorGoose
Такая же проблема, никак не могу корректно с него данные получить)
Вы уже добились эффекта?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы