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

Compilation error: ‘first’ was not declared in this scope

поправил выше - bool

31 254 7 0 0 0

31 254 1 0 0 0

31 254 3 0 0 0

31 254 5 0 0 0

31 254 7 0 0 0

31 254 1 0 0 0

31 254 3 0 0 0

31 254 3 1 0 0

0 0 0 31 254 7

31 254 1 0 0 0

31 254 3 0 0 0

31 254 5 0 0 0

31 254 7 0 0 0

31 254 1 0 0 0

31 254 3 0 0 0

31 254 5 0 0 0

31 254 7 0 0 0

31 254 1 0 0 0

31 254 3 0 0 0

31 254 3 1 0 0

0 0 0 31 254 7

31 254 1 0 0 0

31 254 3 0 0 0

31 254 5 0 0 0

31 254 7 0 0 0

31 254 1 0 0 0

31 254 3 0 0 0

31 254 5 0 0 0

31 254 7 0 0 0

31 254 1 0 0 0

31 254 3 0 0 0

31 254 5 0 0 0

Первый бит НЕ убрали )))))

я так понимаю, то что прочиталось - прочиталось верно, почему пустые ща подумаю…

Данные правильно прочитались с учетом, что первый бит учитывается! А его нужно игнорировать, тогда данные будут правильные

это не для него было… но понял, надо на 1 правее сдвигать жеж, точно

#define BTNPIN 2

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

//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);  
}


/*
 4 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 1я часть, паузы между изменениями состояния (кратно tickwidth)
54 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 195    - 2я часть, паузы между изменениями состояния (кратно tickwidth)
   1   1   1   1   1   0   0   0   0   1   1   1   1   1   1   1   1   1   0   0   0   0   0   0   0        - биты данных

получается, если пауза > 2 то она для нас не несет битов, но свидетельствует о сбросе последовательности
информацию несет каждый четный элемент очереди (0, 2, 4, ...)
причем если этот элемент равен "2" то нужно поменять значение заполняемых бит на противоположное

*/


void loop() {

  
  if (ind > 3) if (micros() - microsArr[ind] > silence) {

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

      // тут будем хранить вытащенные из очереди биты
      uint32_t res1 = 0, res2 = 0;
      // какой из res1 res2 заполнять
      bool first = false;
      //String res = "";

      bool bit = true;
      uint16_t n = 0;

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

        // сколько времени между соседними сменами состояний
        uint32_t dt = microsArr[i + 1] - microsArr[i];
        // кол-во "тиков/импульсов" (с учетом погрешности)
        uint16_t cnt = dt / tickwidth + (((dt % tickwidth) > (tickwidth / 2)) ? 1 : 0);

        if (cnt < 3) {

          // если cnt == 1 или 2 - тут идут данные

          if (n % 2 == 0) {

            uint8_t pos = n / 2; // позиция бита в числе

            // сдвигаем бит на позицию, побитово складываем с заполняемым сейчас результатом
            if (first) res1 |= (uint32_t)bit << pos;
            else       res2 |= (uint32_t)bit << pos;

          }
          //if (n % 2 == 0) res += bit ? "1" : "0";

          // если это сдвоенный импульс, то следующие биты будут инвертированы
          if (cnt == 2) bit = !bit;
          
          // увеличиваем счетчик
          n += cnt;

        } else {

          // если cnt оказалось больше 2, то это в лучшем случае начало второй части "посылки"

          n = 0; // сбрасываем счетчик
          bit = true; // сбрасываем бит
          first = !first; // переключаемся между res1 и res2
          //res += " ";

        }

      }

      // вычленяем результаты
      uint8_t A =  (uint32_t)res1 >> 1 ;
      uint8_t B =  (uint32_t)res1 >> 9 ;
      uint8_t C =  (uint32_t)res1 >> 17;
      uint8_t A2 = (uint32_t)res2 >> 1 ;
      uint8_t B2 = (uint32_t)res2 >> 9 ;
      uint8_t C2 = (uint32_t)res2 >> 17;
      
      Serial.println(String(A) + " " + String(B) + " " + String(C) + " " + String(A2) + " " + String(B2) + " " + String(C2)); // выводим
      
      //Serial.println(res);

      ind = -1; // сбрасываем индекс
      
    }
    
   // 
    
}

пока это глянуть, но я попутно думаю, как эффективнее чистить массив, наверное в перрывании

почти. Вторая часть куда-то делась

Сейчас данные правильные, но с мусорком )

15 255 2 1 0 0

0 0 0 15 255 0

15 255 1 0 0 0

15 255 2 0 0 0

15 255 3 0 0 0

15 255 3 0 0 0

0 0 0 15 255 1

15 255 2 0 0 0

15 255 3 0 0 0

15 255 0 0 0 0

15 255 1 0 0 0

15 255 2 0 0 0

15 255 3 0 0 0

15 255 0 0 0 0

15 255 0 0 0 0

0 0 0 15 255 2

15 255 3 0 0 0

15 255 0 0 0 0

15 255 1 0 0 0

15 255 2 0 0 0

15 255 3 0 0 0

15 255 0 0 0 0

15 255 1 0 0 0

15 255 1 0 0 0

0 0 0 15 255 3

15 255 0 0 0 0

#define BTNPIN 2

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

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

  uint32_t ms = micros();

  if (ind == -1) {
    ind = 0;
    microsArr[ind] = ms;
  } else if (ms - microsArr[ind] > silence) {
    ind = 0;
    microsArr[ind] = ms;
  } else {
    ind++;
    microsArr[ind] = ms;
  }
  

  
}

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

  attachInterrupt(0, chng, CHANGE);  
}


/*
 4 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 1я часть, паузы между изменениями состояния (кратно tickwidth)
54 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 2я часть, паузы между изменениями состояния (кратно tickwidth)
   1   1   1   1   1   0   0   0   0   1   1   1   1   1   1   1   1   1   0   0   0   0   0   0   0        - биты данных

получается, если пауза > 2 то она для нас не несет битов, но свидетельствует о сбросе последовательности
информацию несет каждый четный элемент очереди (0, 2, 4, ...)
причем если этот элемент равен "2" то нужно поменять значение заполняемых бит на противоположное

*/


void loop() {

  
  if (ind > 3) if (micros() - microsArr[ind] > silence) {

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

      // тут будем хранить вытащенные из очереди биты
      uint32_t res1 = 0, res2 = 0;
      // какой из res1 res2 заполнять
      bool first = false;
      //String res = "";

      bool bit = true;
      uint16_t n = 0;

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

        // сколько времени между соседними сменами состояний
        uint32_t dt = microsArr[i + 1] - microsArr[i];
        // кол-во "тиков/импульсов" (с учетом погрешности)
        uint16_t cnt = dt / tickwidth + (((dt % tickwidth) > (tickwidth / 2)) ? 1 : 0);

        if (cnt < 3) {

          // если cnt == 1 или 2 - тут идут данные

          if (n % 2 == 0) {

            uint8_t pos = n / 2; // позиция бита в числе

            // сдвигаем бит на позицию, побитово складываем с заполняемым сейчас результатом
            if (first) res1 |= (uint32_t)bit << pos;
            else       res2 |= (uint32_t)bit << pos;

          }
          //if (n % 2 == 0) res += bit ? "1" : "0";

          // если это сдвоенный импульс, то следующие биты будут инвертированы
          if (cnt == 2) bit = !bit;
          
          // увеличиваем счетчик
          n += cnt;

        } else {

          // если cnt оказалось > 2, то это в лучшем случае начало второй части "посылки"

          n = 0; // сбрасываем счетчик
          bit = true; // сбрасываем бит
          first = !first; // переключаемся между res1 и res2
          //res += " ";

        }

      }

      // вычленяем результаты
      uint8_t A =  (uint32_t)res1 >> 1 ;
      uint8_t B =  (uint32_t)res1 >> 9 ;
      uint8_t C =  (uint32_t)res1 >> 17;
      uint8_t A2 = (uint32_t)res2 >> 1 ;
      uint8_t B2 = (uint32_t)res2 >> 9 ;
      uint8_t C2 = (uint32_t)res2 >> 17;
      
      Serial.println(String(A) + " " + String(B) + " " + String(C) + " " + String(A2) + " " + String(B2) + " " + String(C2)); // выводим
      
      //Serial.println(res);

      ind = -1; // сбрасываем индекс
      
    }
    
   // 
    
}

есть вероятность что прерывание будет само чистить мусор. Ну или ниче работать вообще не будет))

Красиво выглядит уже

15 255 3 0 0 0

15 255 0 0 0 0

15 255 1 0 0 0

15 255 2 0 0 0

15 255 3 0 0 0

15 255 0 0 0 0

15 255 1 0 0 0

15 255 2 0 0 0

15 255 3 0 0 0

15 255 0 0 0 0

15 255 1 0 0 0

15 255 1 0 0 0

15 255 2 1 0 0

15 255 3 0 0 0

15 255 0 0 0 0

15 255 1 0 0 0

15 255 2 0 0 0

15 255 3 0 0 0

15 255 0 0 0 0

15 255 1 0 0 0

15 255 2 0 0 0

15 255 2 1 0 0

15 255 0 0 0 0

15 255 0 0 0 0

я понял куда 2е числа делись. там же 2 импульса > 2 идут подряд!!! (first инвертится дважды и по итогу становится как было)

#define BTNPIN 2

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

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

  uint32_t ms = micros();

  if (ind == -1) {
    ind = 0;
    microsArr[ind] = ms;
  } else if (ms - microsArr[ind] > silence) {
    ind = 0;
    microsArr[ind] = ms;
  } else {
    ind++;
    microsArr[ind] = ms;
  }
  
}

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

  attachInterrupt(0, chng, CHANGE);  
}


/*
 4 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 1я часть, паузы между изменениями состояния (кратно tickwidth)
54 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 2я часть, паузы между изменениями состояния (кратно tickwidth)
   1   1   1   1   1   0   0   0   0   1   1   1   1   1   1   1   1   1   0   0   0   0   0   0   0        - биты данных

получается, если пауза > 2 то она для нас не несет битов, но свидетельствует о сбросе последовательности
информацию несет каждый четный элемент очереди (0, 2, 4, ...)
причем если этот элемент равен "2" то нужно поменять значение заполняемых бит на противоположное

*/


void loop() {

  
  if (ind > 3) if (micros() - microsArr[ind] > silence) {

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

      // тут будем хранить вытащенные из очереди биты
      uint32_t res1 = 0, res2 = 0;
      // какой из res1 res2 заполнять
      bool first = false;
      //String res = "";

      bool bit = true;
      uint16_t n = 0;

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

        // сколько времени между соседними сменами состояний
        uint32_t dt = microsArr[i + 1] - microsArr[i];
        // кол-во "тиков/импульсов" (с учетом погрешности)
        uint16_t cnt = dt / tickwidth + (((dt % tickwidth) > (tickwidth / 2)) ? 1 : 0);

        if (cnt < 3) {

          // если cnt == 1 или 2 - тут идут данные

          if (n % 2 == 0) {

            uint8_t pos = n / 2; // позиция бита в числе

            // сдвигаем бит на позицию, побитово складываем с заполняемым сейчас результатом
            if (first) res1 |= (uint32_t)bit << pos;
            else       res2 |= (uint32_t)bit << pos;

          }
          //if (n % 2 == 0) res += bit ? "1" : "0";

          // если это сдвоенный импульс, то следующие биты будут инвертированы
          if (cnt == 2) bit = !bit;
          
          // увеличиваем счетчик
          n += cnt;

        } else {

          // если cnt оказалось > 2, то это в лучшем случае начало второй части "посылки"

          n = 0; // сбрасываем счетчик
          bit = true; // сбрасываем бит
          first = false; // переключаемся между res1 и res2
          //res += " ";

        }

      }

      // вычленяем результаты
      uint8_t A =  (uint32_t)res1 >> 1 ;
      uint8_t B =  (uint32_t)res1 >> 9 ;
      uint8_t C =  (uint32_t)res1 >> 17;
      uint8_t A2 = (uint32_t)res2 >> 1 ;
      uint8_t B2 = (uint32_t)res2 >> 9 ;
      uint8_t C2 = (uint32_t)res2 >> 17;
      
      Serial.println(String(A) + " " + String(B) + " " + String(C) + " " + String(A2) + " " + String(B2) + " " + String(C2)); // выводим
      
      //Serial.println(res);

      ind = -1; // сбрасываем индекс
      
    }
    
   // 
    
}

Тогда поищите первые ))))))))))))))))

0 0 0 15 255 3

0 0 0 15 255 0

0 0 0 15 255 0

0 0 0 15 255 2

0 0 0 15 255 3

0 0 0 15 255 0

0 0 0 15 255 1

0 0 0 15 255 2

0 0 0 15 255 3

0 0 0 15 255 0

0 0 0 15 255 1

0 0 0 15 255 2

0 0 0 15 255 3

0 0 0 15 255 0

0 0 0 15 255 1

0 0 0 15 255 1

0 0 0 15 255 2

0 0 0 15 255 3

0 0 0 15 255 3

0 0 0 15 255 1

0 0 0 15 255 2

0 0 0 15 255 3

0 0 0 15 255 0

0 0 0 15 255 1

0 0 0 15 255 2

0 0 0 15 255 3

0 0 0 15 255 0

0 0 0 15 255 1

0 0 0 15 255 2

0 0 0 15 255 3

0 0 0 15 255 3

н-да )) ща подумаю

#define BTNPIN 2

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

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

  uint32_t ms = micros();

  if (ind == -1) {
    ind = 0;
    microsArr[ind] = ms;
  } else if (ms - microsArr[ind] > silence) {
    ind = 0;
    microsArr[ind] = ms;
  } else {
    ind++;
    microsArr[ind] = ms;
  }
  
}

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

  attachInterrupt(0, chng, CHANGE);  
}


/*
 4 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 1я часть, паузы между изменениями состояния (кратно tickwidth)
54 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 2я часть, паузы между изменениями состояния (кратно tickwidth)
   1   1   1   1   1   0   0   0   0   1   1   1   1   1   1   1   1   1   0   0   0   0   0   0   0        - биты данных

получается, если пауза > 2 то она для нас не несет битов, но свидетельствует о сбросе последовательности
информацию несет каждый четный элемент очереди (0, 2, 4, ...)
причем если этот элемент равен "2" то нужно поменять значение заполняемых бит на противоположное

*/


void loop() {

  
  if (ind > 3) if (micros() - microsArr[ind] > silence) {

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

      // тут будем хранить вытащенные из очереди биты
      uint32_t res1 = 0, res2 = 0;
      //String res = "";

      bool bit = true;
      uint16_t n = 0;

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

        // сколько времени между соседними сменами состояний
        uint32_t dt = microsArr[i + 1] - microsArr[i];
        // кол-во "тиков/импульсов" (с учетом погрешности)
        uint16_t cnt = dt / tickwidth + (((dt % tickwidth) > (tickwidth / 2)) ? 1 : 0);

        if (cnt < 3) {

          // если cnt == 1 или 2 - тут идут данные

          if (n % 2 == 0) {

            uint8_t pos = n / 2; // позиция бита в числе

            if (pos == 24) bit = true; // если первая часть пакета закончилась - сброс на стартовое

            // сдвигаем бит на позицию, побитово складываем с заполняемым сейчас результатом
            if (pos > 23) res2 |= (uint32_t)bit << (pos - 24);
            else          res1 |= (uint32_t)bit << pos;


          }
          //if (n % 2 == 0) res += bit ? "1" : "0";

          // если это сдвоенный импульс, то следующие биты будут инвертированы
          if (cnt == 2) bit = !bit;
          
          // увеличиваем счетчик
          n += cnt;

        }

      }

      // вычленяем результаты
      uint8_t A =  (uint32_t)res1 >> 1 ;
      uint8_t B =  (uint32_t)res1 >> 9 ;
      uint8_t C =  (uint32_t)res1 >> 17;
      uint8_t A2 = (uint32_t)res2 >> 1 ;
      uint8_t B2 = (uint32_t)res2 >> 9 ;
      uint8_t C2 = (uint32_t)res2 >> 17;
      
      Serial.println(String(A) + " " + String(B) + " " + String(C) + " " + String(A2) + " " + String(B2) + " " + String(C2)); // выводим
      
      //Serial.println(res);

      ind = -1; // сбрасываем индекс
      
    }
    
   // 
    
}

пробуем-с

Так, тут все красиво на первый взгляд, но правый байт не всегда совпадает в левой и правой части.
И он там идет по кругу 0 - 1 - 2 -3, а тут как-то не по порядку

15 255 2 15 254 0

15 255 2 15 254 0

15 255 0 15 254 0

15 255 1 15 254 1

15 255 2 15 254 0

15 255 3 15 254 3

15 255 0 15 254 0

15 255 1 15 254 1

15 255 1 15 254 1

15 255 2 15 254 0

15 255 0 15 254 0

15 255 0 15 254 0

15 255 2 15 254 0

15 255 3 15 254 3

15 255 3 15 254 3

15 255 1 15 254 1

15 255 2 15 254 0

15 255 2 15 254 0

15 255 0 15 254 0

15 255 1 15 254 1

15 255 2 15 254 0

15 255 3 15 254 3

15 255 0 15 254 0

15 255 1 15 254 1

15 255 2 15 254 0

15 255 3 15 254 3

15 255 0 15 254 0

15 255 1 15 254 1

15 255 2 15 254 0

15 255 3 15 254 3

еще просьба то же самое, но чуть другое условие

#define BTNPIN 2

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

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

  uint32_t ms = micros();

  if (ind == -1) {
    ind = 0;
    microsArr[ind] = ms;
  } else if (ms - microsArr[ind] > silence) {
    ind = 0;
    microsArr[ind] = ms;
  } else {
    ind++;
    microsArr[ind] = ms;
  }
  
}

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

  attachInterrupt(0, chng, CHANGE);  
}


/*
 4 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 1я часть, паузы между изменениями состояния (кратно tickwidth)
54 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 2я часть, паузы между изменениями состояния (кратно tickwidth)
   1   1   1   1   1   0   0   0   0   1   1   1   1   1   1   1   1   1   0   0   0   0   0   0   0        - биты данных

получается, если пауза > 2 то она для нас не несет битов, но свидетельствует о сбросе последовательности
информацию несет каждый четный элемент очереди (0, 2, 4, ...)
причем если этот элемент равен "2" то нужно поменять значение заполняемых бит на противоположное

*/


void loop() {

  
  if (ind > 3) if (micros() - microsArr[ind] > silence) {

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

      // тут будем хранить вытащенные из очереди биты
      uint32_t res1 = 0, res2 = 0;

      bool bit = true;
      uint16_t n = 0;

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

        // сколько времени между соседними сменами состояний
        uint32_t dt = microsArr[i + 1] - microsArr[i];
        // кол-во "тиков/импульсов" (с учетом погрешности)
        uint16_t cnt = dt / tickwidth + (((dt % tickwidth) > (tickwidth / 2)) ? 1 : 0);

        if (cnt < 3) {

          // если cnt == 1 или 2 - тут идут данные

          if (n % 2 == 0) {

            uint8_t pos = n / 2; // позиция бита в числе

            if (pos == 24) bit = true; // если первая часть пакета закончилась - сброс на стартовое

            // сдвигаем бит на позицию, побитово складываем с заполняемым сейчас результатом
            if (pos < 24) res1 |= (uint32_t)bit << pos;
            else          res2 |= (uint32_t)bit << (pos - 24);


          }

          // если это сдвоенный импульс, то следующие биты будут инвертированы
          if (cnt == 2) bit = !bit;
          
          // увеличиваем счетчик
          n += cnt;

        }

      }

      // вычленяем результаты
      uint8_t A =  (uint32_t)res1 >> 1 ;
      uint8_t B =  (uint32_t)res1 >> 9 ;
      uint8_t C =  (uint32_t)res1 >> 17;
      uint8_t A2 = (uint32_t)res2 >> 1 ;
      uint8_t B2 = (uint32_t)res2 >> 9 ;
      uint8_t C2 = (uint32_t)res2 >> 17;
      
      Serial.println(String(A) + " " + String(B) + " " + String(C) + " " + String(A2) + " " + String(B2) + " " + String(C2)); // выводим

      ind = -1; // сбрасываем индекс
      
    }
    
   // 
    
}

насчет порядка вопрос занятный конечно…

Я заколебался ваши 0 и 1 пролистывать. Прячте под спойлер что ли)

2 лайка

Учтём ) А я не найду никак где тут спойлер.

15 255 2 15 254 0

15 255 0 15 254 0

15 255 1 15 254 1

15 255 2 15 254 0

15 255 3 15 254 3

15 255 0 15 254 0

15 255 1 15 254 1

15 255 2 15 254 0

15 255 3 15 254 3

15 255 0 15 254 0

15 255 1 15 254 1

15 255 1 15 254 1

15 255 3 15 254 3

15 255 0 15 254 0

15 255 1 15 254 1

15 255 2 15 254 0

на шестеренке в редакторе (самая правая кнопка). Есть у меня ощущение, что в строках 76, 79 и 80 должно быть вместо 24 либо 25, либо 23. Потому что если внимательно смотреть то первые и вторые наборы не равны, хоть и похожи! Но чет бошка не варит уже считать))

Пробуйте 25:

#define BTNPIN 2

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

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

  uint32_t ms = micros();

  if (ind == -1) {
    ind = 0;
    microsArr[ind] = ms;
  } else if (ms - microsArr[ind] > silence) {
    ind = 0;
    microsArr[ind] = ms;
  } else {
    ind++;
    microsArr[ind] = ms;
  }
  
}

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

  attachInterrupt(0, chng, CHANGE);  
}


/*
 4 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 1я часть, паузы между изменениями состояния (кратно tickwidth)
54 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2   1 1 1 1 1 1 1 1 1 1 1 1 1        - 2я часть, паузы между изменениями состояния (кратно tickwidth)
   1   1   1   1   1   0   0   0   0   1   1   1   1   1   1   1   1   1   0   0   0   0   0   0   0        - биты данных

получается, если пауза > 2 то она для нас не несет битов, но свидетельствует о сбросе последовательности
информацию несет каждый четный элемент очереди (0, 2, 4, ...)
причем если этот элемент равен "2" то нужно поменять значение заполняемых бит на противоположное

*/


void loop() {

  
  if (ind > 3) if (micros() - microsArr[ind] > silence) {

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

      // тут будем хранить вытащенные из очереди биты
      uint32_t res1 = 0, res2 = 0;

      bool bit = true;
      uint16_t n = 0;

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

        // сколько времени между соседними сменами состояний
        uint32_t dt = microsArr[i + 1] - microsArr[i];
        // кол-во "тиков/импульсов" (с учетом погрешности)
        uint16_t cnt = dt / tickwidth + (((dt % tickwidth) > (tickwidth / 2)) ? 1 : 0);

        if (cnt < 3) {

          // если cnt == 1 или 2 - тут идут данные

          if (n % 2 == 0) {

            uint8_t pos = n / 2; // позиция бита в числе

            if (pos == 25) bit = true; // если первая часть пакета закончилась - сброс на стартовое

            // сдвигаем бит на позицию, побитово складываем с заполняемым сейчас результатом
            if (pos < 25) res1 |= (uint32_t)bit << pos;
            else          res2 |= (uint32_t)bit << (pos - 25);


          }

          // если это сдвоенный импульс, то следующие биты будут инвертированы
          if (cnt == 2) bit = !bit;
          
          // увеличиваем счетчик
          n += cnt;

        }

      }

      // вычленяем результаты
      uint8_t A =  (uint32_t)res1 >> 1 ;
      uint8_t B =  (uint32_t)res1 >> 9 ;
      uint8_t C =  (uint32_t)res1 >> 17;
      uint8_t A2 = (uint32_t)res2 >> 1 ;
      uint8_t B2 = (uint32_t)res2 >> 9 ;
      uint8_t C2 = (uint32_t)res2 >> 17;
      
      Serial.println(String(A) + " " + String(B) + " " + String(C) + " " + String(A2) + " " + String(B2) + " " + String(C2)); // выводим

      ind = -1; // сбрасываем индекс
      
    }
    
   // 
    
}