Прошу помощи в декодирование протокола

Я могу прикрепить файлы под Logic 2 или PulseView если поможет.

А вот отсюда ничего не подойдёт?

да вот понять не могу, или я уже гоню ночью, или что… но если взять один из кусков, вами выше приведенных, и поставить переносы на каждой смене, а также через каждые 100 символов, то получится:

Спойлер

000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

словно 0001110100011101110001011100010001110111000

как будто временные константы следует на 100 домножить, но я не понимаю, почему

н овсе равно, если не против, давайте как попробуем:

#define BTNPIN 2

// максимально возможное кол-во смен состояния входа за прием одного пакета (включая следом идущую копию)
const uint16_t maxc = 255;  // представить себе, что там будет 1010101010101010101010... короче количество бит + 1
int16_t ind = -1;
uint32_t microsArr[maxc];
const uint32_t bitc = 200 * 100;              // количество микросекунд, соотв. длительности импульса одного бита в пакете
const uint32_t cycle_half = 40000 * 100 / 2;  // половина цикла (периода) отправки пакетов

//void ISR (void* para) { // повесить на GPIO_INTR_ANYEDGE
void chng() {

  ind++;
  if (ind == maxc) ind = 0;
  microsArr[ind] = micros();
}

void setup() {
  pinMode(BTNPIN, INPUT_PULLUP);
  Serial.begin(115200);

  attachInterrupt(0, chng, CHANGE);  
}


void loop() {

  if (ind > 0) if (micros() - microsArr[ind] > cycle_half) {

      // в массиве шото есть, и последнее шото добавилось достаточно давно

      for (uint16_t i = 0; i < ind; i++) {

        uint32_t dt = microsArr[ind + 1] - microsArr[ind];  // сколько времени между соседними сменами состояний
        
        uint16_t cnt = dt / bitc;  // сколько бит вмещается в это время
        if (dt % bitc > bitc / 2) cnt++; // если dt получилось чуть меньше числа, кратного bitc 
        bool sym = i % 2; // какой символ приняли

        for (uint16_t j = 0; j < cnt; j++) Serial.print(sym ? "1" : "0");  // выводим символ(ы)


      }
      
      Serial.println();  // завершаем строку
      ind = -1;          // сбрасываем индекс
      
    }
    
   // 
    
}

Пример RX я как раз и пробовал, прям так в лоб не пошло. Там же много чего в файле .h можно настроить, скорость преамбулу, инверсию. Вот там, может конечно что-то и не настроил под реальную задачу.

да, я как минимум проперся с типами данных для времени, исправил выше (27 сообщение) на uint32_t…

Я готов пробовать что угодно )))))
Вывод

18:42:15.781 →

18:42:15.781 →

18:42:15.781 →

18:42:15.781 → 000

18:42:15.781 → 000

18:42:15.781 →

18:42:15.781 → 000

18:42:15.781 →

18:42:15.781 → 000

18:42:15.781 → 000

18:42:15.781 → 000

18:42:15.781 →

18:42:15.781 → 000

18:42:15.781 → 000

Там еще варнинг при компиляции был

warning: large integer implicitly truncated to unsigned type [-Woverflow]
const uint16_t cycle_half = 40000 * 100 / 2; // половина цикла (периода) отправки пакетов
~~~~~~~~~~^

вот да, говорю, с uint32 проперся, там переполнение случалось быстрее конца 1 пакета наверное))

#define BTNPIN 2

// максимально возможное кол-во смен состояния входа за прием одного пакета (включая следом идущую копию)
const uint16_t maxc = 255;  // представить себе, что там будет 1010101010101010101010... короче количество бит + 1
int16_t ind = -1;
uint32_t microsArr[maxc];
const uint32_t bitc = 200 * 100;              // количество микросекунд, соотв. длительности импульса одного бита в пакете
const uint32_t cycle_half = 40000 * 100 / 2;  // половина цикла (периода) отправки пакетов

//void ISR (void* para) { // повесить на GPIO_INTR_ANYEDGE
void chng() {

  ind++;
  if (ind == maxc) ind = 0;
  microsArr[ind] = micros();
}

void setup() {
  pinMode(BTNPIN, INPUT_PULLUP);
  Serial.begin(115200);

  attachInterrupt(0, chng, CHANGE);  
}


void loop() {

  if (ind > 0) if (micros() - microsArr[ind] > cycle_half) {

      // в массиве шото есть, и последнее шото добавилось достаточно давно

      for (uint16_t i = 0; i < ind; i++) {

        uint32_t dt = microsArr[ind + 1] - microsArr[ind];  // сколько времени между соседними сменами состояний
        
        uint16_t cnt = dt / bitc;  // сколько бит вмещается в это время
        if (dt % bitc > bitc / 2) cnt++; // если dt получилось чуть меньше числа, кратного bitc 
        bool sym = i % 2; // какой символ приняли

        for (uint16_t j = 0; j < cnt; j++) Serial.print(sym ? "1" : "0");  // выводим символ(ы)


      }
      
      Serial.println();  // завершаем строку
      ind = -1;          // сбрасываем индекс
      
    }
    
   // 
    
}

либо

#define BTNPIN 2

// максимально возможное кол-во смен состояния входа за прием одного пакета (включая следом идущую копию)
const uint16_t maxc = 255;  // представить себе, что там будет 1010101010101010101010... короче количество бит + 1
int16_t ind = -1;
uint32_t microsArr[maxc];
const uint32_t bitc = 200;              // количество микросекунд, соотв. длительности импульса одного бита в пакете
const uint32_t cycle_half = 40000 / 2;  // половина цикла (периода) отправки пакетов

//void ISR (void* para) { // повесить на GPIO_INTR_ANYEDGE
void chng() {

  ind++;
  if (ind == maxc) ind = 0;
  microsArr[ind] = micros();
}

void setup() {
  pinMode(BTNPIN, INPUT_PULLUP);
  Serial.begin(115200);

  attachInterrupt(0, chng, CHANGE);  
}


void loop() {

  if (ind > 0) if (micros() - microsArr[ind] > cycle_half) {

      // в массиве шото есть, и последнее шото добавилось достаточно давно

      for (uint16_t i = 0; i < ind; i++) {

        uint32_t dt = microsArr[ind + 1] - microsArr[ind];  // сколько времени между соседними сменами состояний
        
        uint16_t cnt = dt / bitc;  // сколько бит вмещается в это время
        if (dt % bitc > bitc / 2) cnt++; // если dt получилось чуть меньше числа, кратного bitc 
        bool sym = i % 2; // какой символ приняли

        for (uint16_t j = 0; j < cnt; j++) Serial.print(sym ? "1" : "0");  // выводим символ(ы)


      }
      
      Serial.println();  // завершаем строку
      ind = -1;          // сбрасываем индекс
      
    }
    
   // 
    
}

еще для теста можно сами задержки вывести попробовать:

#define BTNPIN 2

// максимально возможное кол-во смен состояния входа за прием одного пакета (включая следом идущую копию)
const uint16_t maxc = 255;  // представить себе, что там будет 1010101010101010101010... короче количество бит + 1
int16_t ind = -1;
uint32_t microsArr[maxc];
const uint32_t bitc = 200;              // количество микросекунд, соотв. длительности импульса одного бита в пакете
const uint32_t cycle_half = 40000 / 2;  // половина цикла (периода) отправки пакетов

//void ISR (void* para) { // повесить на GPIO_INTR_ANYEDGE
void chng() {

  ind++;
  if (ind == maxc) ind = 0;
  microsArr[ind] = micros();
}

void setup() {
  pinMode(BTNPIN, INPUT_PULLUP);
  Serial.begin(115200);

  attachInterrupt(0, chng, CHANGE);  
}


void loop() {

  if (ind > 0) if (micros() - microsArr[ind] > cycle_half) {

      // в массиве шото есть, и последнее шото добавилось достаточно давно

      for (uint16_t i = 0; i < ind; i++) {

        uint32_t dt = microsArr[ind + 1] - microsArr[ind];  // сколько времени между соседними сменами состояний
        
        Serial.print(String(dt) + " ");
        /*uint16_t cnt = dt / bitc;  // сколько бит вмещается в это время
        if (dt % bitc > bitc / 2) cnt++; // если dt получилось чуть меньше числа, кратного bitc 
        bool sym = i % 2; // какой символ приняли

        for (uint16_t j = 0; j < cnt; j++) Serial.print(sym ? "1" : "0");  // выводим символ(ы)*/


      }
      
      Serial.println();  // завершаем строку
      ind = -1;          // сбрасываем индекс
      
    }
    
   // 
    
}

В одну строку фигачит кучу 0, потом кучу 1. Даже скопировать не получается )

тогда это

блин ну естессно (facepalm)

#define BTNPIN 2

// максимально возможное кол-во смен состояния входа за прием одного пакета (включая следом идущую копию)
const uint16_t maxc = 255;  // представить себе, что там будет 1010101010101010101010... короче количество бит + 1
int16_t ind = -1;
uint32_t microsArr[maxc];
const uint32_t bitc = 200;              // количество микросекунд, соотв. длительности импульса одного бита в пакете
const uint32_t cycle_half = 40000 / 2;  // половина цикла (периода) отправки пакетов

//void ISR (void* para) { // повесить на GPIO_INTR_ANYEDGE
void chng() {

  ind++;
  if (ind == maxc) ind = 0;
  microsArr[ind] = micros();
}

void setup() {
  pinMode(BTNPIN, INPUT_PULLUP);
  Serial.begin(115200);

  attachInterrupt(0, chng, CHANGE);  
}


void loop() {

  if (ind > 0) if (micros() - microsArr[ind] > cycle_half) {

      // в массиве шото есть, и последнее шото добавилось достаточно давно

      for (uint16_t i = 0; i < ind; i++) {

        uint32_t dt = microsArr[i + 1] - microsArr[i];  // сколько времени между соседними сменами состояний
        
        Serial.print(String(dt) + " ");
        /*uint16_t cnt = dt / bitc;  // сколько бит вмещается в это время
        if (dt % bitc > bitc / 2) cnt++; // если dt получилось чуть меньше числа, кратного bitc 
        bool sym = i % 2; // какой символ приняли

        for (uint16_t j = 0; j < cnt; j++) Serial.print(sym ? "1" : "0");  // выводим символ(ы)*/


      }
      
      Serial.println();  // завершаем строку
      ind = -1;          // сбрасываем индекс
      
    }
    
   // 
    
}

индекс в цикле i а не ind нужен…

Я это всё до дыр засмотрел )))) Там как раз варианты где шириной импульса определяется 0 или 1. Счастливые люди, решили вопрос )))

Во, другое дело!

это называется в 2 ночи спать надо, а не скетчи вслепую писать))) ссоре

#define BTNPIN 2

// максимально возможное кол-во смен состояния входа за прием одного пакета (включая следом идущую копию)
const uint16_t maxc = 255;  // представить себе, что там будет 1010101010101010101010... короче количество бит + 1
int16_t ind = -1;
uint32_t microsArr[maxc];
const uint32_t bitc = 200;              // количество микросекунд, соотв. длительности импульса одного бита в пакете
const uint32_t cycle_half = 40000 / 2;  // половина цикла (периода) отправки пакетов

//void ISR (void* para) { // повесить на GPIO_INTR_ANYEDGE
void chng() {

  ind++;
  if (ind == maxc) ind = 0;
  microsArr[ind] = micros();
}

void setup() {
  pinMode(BTNPIN, INPUT_PULLUP);
  Serial.begin(115200);

  attachInterrupt(0, chng, CHANGE);  
}


void loop() {

  if (ind > 0) if (micros() - microsArr[ind] > cycle_half) {

      // в массиве шото есть, и последнее шото добавилось достаточно давно

      for (uint16_t i = 0; i < ind; i++) {

        uint32_t dt = microsArr[i + 1] - microsArr[i];  // сколько времени между соседними сменами состояний
        
        //Serial.print(String(dt) + " ");/*
        uint16_t cnt = dt / bitc;  // сколько бит вмещается в это время
        if (dt % bitc > bitc / 2) cnt++; // если dt получилось чуть меньше числа, кратного bitc 
        bool sym = i % 2; // какой символ приняли

        for (uint16_t j = 0; j < cnt; j++) Serial.print(sym ? "1" : "0");  // выводим символ(ы)/**/


      }
      
      Serial.println();  // завершаем строку
      ind = -1;          // сбрасываем индекс
      
    }
    
   // 
    
}

теперь так

вот это меня смущает, скорее всего не успел сериал в консоль нагадить, а уже 2й пакет начался. Но ничего, исправим, если сейчас покатят биты правильные (а они должны)

да, и именно на ней должно срабатывать условие if (micros() - microsArr[ind] > cycle_half), то есть это должно быть между выводами в Serial, но не внутри одного вывода.

Теперь так:

#define BTNPIN 2

// максимально возможное кол-во смен состояния входа за прием одного пакета (включая следом идущую копию)
const uint16_t maxc = 255;  // представить себе, что там будет 1010101010101010101010... короче количество бит + 1
int16_t ind = -1;
uint32_t microsArr[maxc];
const uint32_t bitc = 200;              // количество микросекунд, соотв. длительности импульса одного бита в пакете
const uint32_t cycle_half = 40000 / 2;  // половина цикла (периода) отправки пакетов

//void ISR (void* para) { // повесить на GPIO_INTR_ANYEDGE
void chng() {

  ind++;
  if (ind == maxc) ind = 0;
  microsArr[ind] = micros();
}

void setup() {
  pinMode(BTNPIN, INPUT_PULLUP);
  Serial.begin(115200);

  attachInterrupt(0, chng, CHANGE);  
}


void loop() {

  if (ind > 0) if (micros() - microsArr[ind] > cycle_half) {

      // в массиве шото есть, и последнее шото добавилось достаточно давно

      String res = "";

      for (uint16_t i = 0; i < ind; i++) {

        uint32_t dt = microsArr[i + 1] - microsArr[i];  // сколько времени между соседними сменами состояний
        
        //Serial.print(String(dt) + " ");/*
        uint16_t cnt = dt / bitc;  // сколько бит вмещается в это время
        if (dt % bitc > bitc / 2) cnt++; // если dt получилось чуть меньше числа, кратного bitc, то мы ен должны потерять этот бит, который чуть короче, чем надо
        bool sym = i % 2; // какой символ приняли

        for (uint16_t j = 0; j < cnt; j++) res += sym ? "1" : "0";  // набиваем символами /**/


      }
      
      Serial.println(res); // выводим
      ind = -1; // сбрасываем индекс
      
    }
    
   // 
    
}

И сообщите, бьется ли это с ожидаемыми данными? 1 строка = 1 пакет (включая повтор)

блин строка 43 “res +=” надо (поправил)

Нет. Не бьется. Всегда новая строка чаще хаотичная ((((
Наверно в этот раз вот так покажу для наглядности.

которые ровные выглядят вроде как нормально. Т.е. каждая 0 или 1 соответствует продолжительности импульса 200мкс с графиков из 1 сообщения. Вот откуда длинная с нулями берется - не совсем понятно

присмотритесь вначале 0000 это первый нулевой импульс в 800мкс, потом данные, потом 1000мкс “+” (11111) потом 0000, потом снова данные

причем данные первой и второй половины идентичны, т.о. читает корректно.
Вот теперь если объясните, как из этого число получается, можно и число сообразить

получается импульс 4х длины (0000) потом 49 бит, потом импульс 5х лины (11111) потом опять импульс 4х длины (0000) потом снова те же 49 бит, и всё, пакет закончился

с этим графиком бьется вполне

Да, похоже на то…

Получается так. Только как из этого сложить вот это.
5_2
Надо же как-то получить эти 3 байта в одном куске. Или как ?