SOLUCIONADO - KEELOQ muestra datos recibidos al revés

Hola chico.
Ya sé que para un novato, quizás esté picando demasiado alto, pero creo que lo conseguiré.
Estoy tratando de decodificar un código RF Keeloq enviado desde un mando de garaje a mi arduino.
Lo recibo a través de un modulo RF433 y un código de un ruso que había por la red.
El código hace mucho más de lo que yo necesito, pero quiero aprovechar una parte:
Leer en el serial (de momento) el código KEELOQ enviado desde el mando.
Dispongo de un dispositivo con LCD, comprado hace años para precisamente ver el citado código RF.
Lo muestra correctamente si embargo arduino me lo muestra del revés.
Todo se muestra en Hexadecimal.
El orden correcto de los datos es el siguiente:

X = Numero de boton pulsado (Siempre el mismo)
XXXXXXX = Numero de serie del mando. (Siempre el mismo)
XXXXXXXX = Datos encriptados que no viene al caso ahondar en ello, pero cambian en cada pulsación.

Total son 16 digitos en hexadecimal.
Para la explicación, hablaré solo del numero de serie, si consigo ponerlo al derecho, los otros los arreglaré de igual manera.

Mi LCD muestra 0F98958 y arduino muestra 1A919F

Si pasamos cada adigito del arduino a binario uno a uno y los leemos al reves y volvemos a convertir a HEX, coincide con los digitos del arduino pero al revés.

8 = 1000 bin, invierto = 0001, paso a hex = 1
5 = 101 bin, invierto = 1010, paso a hex = A
9 = 1001 bin, invierto queda igual, paso a hex = 9
8 = 1000 bin, invierto = 0001, paso a hex = 1
9 = 1001 bin, invierto = queda igual, paso a hex = 9
F = 1111 bin, invierto = queda igual, paso a hex = F

Veis que coinciden los dígitos pero los coloca al revés. He probado con otros mandos y hace lo mismo.
Este es el código culpable:

#include "math.h" 


#define txPin 8
#define rxPin 2
#define signalPin 6

int lastRxValue = 0;
int tempRxValue = 0;
unsigned long lastRxTime = 0;
unsigned long tempTime = 0;
unsigned long difTime = 0;
boolean bValidPacket = false;
int decodeMethod = 1; //0 real - as in manual, 1 inver as Oleg do


//Global vars end
void send_meander(int time){
  digitalWrite(txPin, HIGH);
  delayMicroseconds(time);
  digitalWrite(txPin, LOW);
  delayMicroseconds(time);
}
//keelog start
int keelog_state = 0;
int keelogCounter = 0;
byte keelog_code[9];

void keelog_vardump(){
  if(decodeMethod == 0){
    Serial.println(" - keelog origin - ");
  }
  else{
    Serial.println(" - keelog invert - ");
  }
  Serial.print(keelog_code[0], HEX);
  Serial.print(keelog_code[1], HEX);
  Serial.print(keelog_code[2], HEX);
  Serial.print(keelog_code[3], HEX);
  Serial.println("-hop");
  Serial.print(keelog_code[4], HEX);
  Serial.print(keelog_code[5], HEX);
  Serial.print(keelog_code[6], HEX);
  Serial.println("-fix");
  Serial.print(keelog_code[7], HEX);
  Serial.println("-btn");
  Serial.print(keelog_code[8], HEX);
  Serial.println("-dop");
  
  /*for(int i = 0; i<9; i++){
    Serial.print(keelog_code[i], HEX);
    Serial.print(" - ");
  }*/
  keelog_send(keelog_code);
  digitalWrite(signalPin, HIGH);
  delay(100);
  digitalWrite(signalPin, LOW);
  keelog_state = 0;
  for(int i = 0; i<9; i++){
    keelog_code[i]=0;
  }
}
void keelog_send(byte* keelog_code){
  Serial.println("- sending keelog -");
  for(int i = 0; i<9; i++){
    Serial.print(keelog_code[i], HEX);
    Serial.print(" - ");
  }
  for(int i = 0; i<11; i++){//посылаем преамблу
    send_meander(400);
  }
  digitalWrite(txPin, HIGH);
  delayMicroseconds(400);
  digitalWrite(txPin, LOW);
  delayMicroseconds(4000);//посылаем хедер
  
  for( int i = 0; i<9; i++){
    if(decodeMethod==1){
      for(int i2 = 7;i2>=0;i2--){
        if(bitRead(keelog_code[i], i2)){
          digitalWrite(txPin, HIGH);
          delayMicroseconds(400);
          digitalWrite(txPin, LOW);
          delayMicroseconds(2*400);
        }
        else{
          digitalWrite(txPin, HIGH);
          delayMicroseconds(2*400);
          digitalWrite(txPin, LOW);
          delayMicroseconds(400);
        }
      }
    }
    else{
        for(int i2 = 0;i2<8;i2++){
          if(!bitRead(keelog_code[i], i2)){
            digitalWrite(txPin, HIGH);
            delayMicroseconds(400);
            digitalWrite(txPin, LOW);
            delayMicroseconds(2*400);
          }
          else{
            digitalWrite(txPin, HIGH);
            delayMicroseconds(2*400);
            digitalWrite(txPin, LOW);
            delayMicroseconds(400);
          }
       } 
    }
    
  }
}
void keelog_get(){
    bValidPacket = false;
    if(keelog_state==0){//ждем преамбулу и хедер
      if(difTime > 280 && difTime < 620 && lastRxValue != tempRxValue){
        keelogCounter ++;
      }
      else{
        if(keelogCounter==23){
          if(difTime>2800 && difTime<6200 && lastRxValue == 0){
            keelog_state=1;
          }
        }
       keelogCounter = 0;
      }
    }
    else if(keelog_state==1){// получаем биты
      if(difTime > 560 && difTime < 1240 && lastRxValue == 1){// получили 1
        if(decodeMethod==0){
          keelog_code[round(keelogCounter/8)] = (keelog_code[round(keelogCounter/8)]>>1)|B10000000;
        }
        else{
          keelog_code[round(keelogCounter/8)] = (keelog_code[round(keelogCounter/8)]<<1)|B00000000;
        }
        bValidPacket = true;
      }
      else if(difTime > 280 && difTime < 620 && lastRxValue == 1){
        if(decodeMethod==0){
          keelog_code[round(keelogCounter/8)] = (keelog_code[round(keelogCounter/8)]>>1)|B00000000;
        }
        else{
          keelog_code[round(keelogCounter/8)] = (keelog_code[round(keelogCounter/8)]<<1)|B00000001;
        }
        bValidPacket = true;
      }
      else if(lastRxValue == 0){
      }
      else{
        keelog_state=1;
        keelogCounter = 0;
      }
      
      if(bValidPacket){
        keelogCounter++;
        if(keelogCounter==66){
          keelog_vardump();
          keelogCounter = 0;
          keelog_state = 0;
        }
      }
    }
}
//keelog end


void setup() {                
  pinMode(txPin, OUTPUT);
  pinMode(rxPin, INPUT);
  pinMode(signalPin, OUTPUT);
  //
  Serial.begin(9600);
  Serial.println("start");
  lastRxValue = digitalRead(rxPin);
  lastRxTime = micros();
  
  //attachInterrupt(0, grab, CHANGE);
}

void loop() {
  tempRxValue = digitalRead(rxPin);
  
  if(tempRxValue != lastRxValue){
    tempTime = micros();
    difTime = tempTime - lastRxTime;
    keelog_get();  
    lastRxTime = tempTime;
    lastRxValue = tempRxValue;
  }
}

El código hace más cosas pero de momento solo pretendo que lea los mandos al derecho.
Incluso en la linea 14

int decodeMethod = 1; //0 real - as in manual, 1 invert

Lo he puesto en 0, la mezcla de posiciones aún es peor.
Alguien sabría que cambios hacer en esa zona del código para que muestre los datos al derecho ???

Gracias

Y que tal si simplemente cambias esto

int decodeMethod = 1; //0 real - as in manual, 1 inver as Oleg do

por esto

int decodeMethod = 0; //0 real - as in manual, 1 inver as Oleg do

Gracias pero ya lo había probado antes de hacer la consulta.
Simplemente mezcla los datos mostrados de otra manera.
Mañana intentaré hallar qué logica sigue poniendo decodeMethod en 0.
Precisamente entiendo que ese comando hace invertir los datos o no, pero el resultado tampo lo muestra ordenado.
Mañana publicaré el resultado con 0.
Gracias

Bueno sino inverte bits usando ! o ~

Modifica esto asi

      void keelog_vardump(){
  if(decodeMethod == 0){
    Serial.println(" - keelog origin - ");
  }
  else{
    Serial.println(" - keelog invert - ");
  }
  for (int i =0; i<9; i++)
      keelog_code[i] = !keelog_code[i];

Gracias Surbyte.
Con tu sugerencia, sale todo a 0.

Tanto poniendo 0 como 1. A no ser que yo haya colocado tus lineas de forma errónea.

Pego las primeras lineas de código por si las he colocado mal.

#include "math.h" 


#define txPin 8
#define rxPin 2
#define signalPin 6

int lastRxValue = 0;
int tempRxValue = 0;
unsigned long lastRxTime = 0;
unsigned long tempTime = 0;
unsigned long difTime = 0;
boolean bValidPacket = false;
int decodeMethod = 1; //0 real - as in manual, 1 inver as Oleg do


//Global vars end
void send_meander(int time){
  digitalWrite(txPin, HIGH);
  delayMicroseconds(time);
  digitalWrite(txPin, LOW);
  delayMicroseconds(time);
}
//keelog start
int keelog_state = 0;
int keelogCounter = 0;
byte keelog_code[9];

void keelog_vardump(){
  if(decodeMethod == 0){
    Serial.println(" - keelog origin - ");
  }
  else{
    Serial.println(" - keelog invert - ");
  }
  for (int i =0; i<9; i++)
      keelog_code[i] = !keelog_code[i];
      
  Serial.print(keelog_code[0], HEX);
  Serial.print(keelog_code[1], HEX);
  Serial.print(keelog_code[2], HEX);
  Serial.print(keelog_code[3], HEX);
  Serial.println("-hop");
  Serial.print(keelog_code[4], HEX);
  Serial.print(keelog_code[5], HEX);
  Serial.print(keelog_code[6], HEX);
  Serial.println("-fix");
  Serial.print(keelog_code[7], HEX);
  Serial.println("-btn");
  Serial.print(keelog_code[8], HEX);
  Serial.println("-dop");
  
  /*for(int i = 0; i<9; i++){
    Serial.print(keelog_code[i], HEX);
    Serial.print(" - ");
  }*/

Hoy dispongo de otros mandos a mano y la forma de mostrar los datos sigue la misma pauta que el del primer post.

Su numero correcto es este:
257A18CA5C5F8F8A ----- 2 es el botón pulsado y 57A18CA es el numero de serie. El resto es cambiante a cada pulsación.

Si vemos el numero de serie 57A18CA en mi dispositivo, en el arduino lo muestra como 53185E.

Seguiré probando a ver si deshago esa inversión, que sinceramente no sé para qué la usa.

Tengo otro código de un sketch parecido también de un ruso, que tiene la misma función y además al derecho. Este lo muestra en decimal.

91887818 = 57A18CA

Pero no muestra el numero de botón transmitido. por si a alguien le interesa para comparar, lo pego aquí debajo.
Este no invierte, pero no muestra num. de botón:

#define LED_PIN        13
#define HCS_RECIEVER_PIN  2    // Pin al que está conectado el receptor para los mandos.


class HCS301 {
public:
  unsigned BattaryLow : 1;  // En el llavero estaba la batería.
  unsigned Repeat : 1; // повторная посылка
  unsigned BtnNoSound : 1;
  unsigned BtnOpen : 1; 
  unsigned BtnClose : 1; 
  unsigned BtnRing : 1;
  unsigned long SerialNum;
  unsigned long Encript;

  void print();
};

volatile boolean  HCS_Listening = true;   
byte        HCS_preamble_count = 0;
uint32_t      HCS_last_change = 0;
uint32_t      HCS_start_preamble = 0;
uint8_t       HCS_bit_counter;        // счетчик считанных бит данных
uint8_t       HCS_bit_array[66];        // массив считанных бит данных
#define       HCS_TE    400         // типичная длительность имульса Te
#define       HCS_Te2_3 600         // HCS_TE * 3 / 2

HCS301 hcs301;

#define HCS_DEBUG_

#ifdef HCS_DEBUG

uint16_t HCS_PulseDuration[12];
uint16_t HCS_BitDuration[66];
uint32_t HCS_msg_duration;

struct dta_ {
  uint16_t delay;
  byte f;
  byte st;
};

volatile dta_ arr[1000];
volatile int poz_a = 0,poz_b = 0;
#endif

void HCS301::print(){
  String btn;

  if (BtnRing == 1) btn += "Ring";
  if (BtnClose == 1) btn += "Close";
  if (BtnOpen == 1) btn += "Open";
  if (BtnNoSound == 1) btn += "NoSound";

  String it2;
  it2 += "Encript ";
  it2 += Encript;
  it2 += " Serial ";
  it2 += SerialNum;
  it2 += " ";
  it2 += btn;
  it2 += " BattaryLow=";
  it2 += BattaryLow;
  it2 += " Rep=";
  it2 += Repeat;

  Serial.println(it2);

}

void setup() {                
  
  Serial.begin(9600);  
  attachInterrupt(0, HCS_interrupt, CHANGE);

  pinMode(LED_PIN, OUTPUT);
  pinMode(HCS_RECIEVER_PIN, INPUT);
}

void loop() {
  
  if(HCS_Listening == false){
    
    HCS301 msg;
    memcpy(&msg,&hcs301,sizeof(HCS301));
  
    msg.print();
    #ifdef HCS_DEBUG
    if(msg.SerialNum != 639){

      Serial.println("Raw >>>>>>>>>>>>>>>>>>>>>>>");
      while(1){
        if(poz_b == poz_a) break;
        Serial.println(String(poz_b)+String("   ")+String(arr[poz_b].delay)+String("   ")+String(arr[poz_b].f == 0 ? "LOW":"HIGH")+String("   ")+String(arr[poz_b].st));
        poz_b++;
      }
      Serial.println("Data >>>>>>>>>>>>>>>>>>>>>>>");
      for(int i = 0;i<66;i++){  Serial.println(HCS_bit_array[i]);   }
    } else {
      
    }
    poz_a = 0,poz_b = 0;
    #endif

    HCS_Listening = true;
  }
}

// 

void HCS_interrupt(){

  if(HCS_Listening == false){
    return;
  }

  uint32_t cur_timestamp = micros();
  uint8_t  cur_status = digitalRead(HCS_RECIEVER_PIN);
  uint32_t pulse_duration = cur_timestamp - HCS_last_change;
  HCS_last_change     = cur_timestamp;

  #ifdef HCS_DEBUG
  if(poz_a < 999){
    arr[poz_a].delay = pulse_duration;
    arr[poz_a].f = cur_status == HIGH ? 0 : 1;
    poz_a++;
  }
  #endif

  // ловим преамбулу
  if(HCS_preamble_count < 12){
    if(cur_status == HIGH){
      if( ((pulse_duration > 200) && (pulse_duration < 400)) || HCS_preamble_count == 0){
        // начало импульса преамбулы
        if(HCS_preamble_count == 0){
          HCS_start_preamble = cur_timestamp; // Отметим время старта преамбулы
        }
      } else {
        // поймали какую то фигню, неправильная пауза между импульсами
        HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы
        goto exit; 

      }
    } else {
      // конец импульса преамбулы
      if((pulse_duration > 400) && (pulse_duration < 600)){
        #ifdef HCS_DEBUG
          HCS_PulseDuration[HCS_preamble_count] = pulse_duration;
        #endif
        // поймали импульс преамбулы
        HCS_preamble_count ++;
        #ifdef HCS_DEBUG
        arr[poz_a-1].st = HCS_preamble_count;
        #endif
        if(HCS_preamble_count == 12){
          // словили преамбулу
          //HCS_Te = (cur_timestamp - HCS_start_preamble) / 23;  // вычисляем длительность базового импульса Te
          //HCS_Te2_3 = HCS_Te * 3 / 2;
          HCS_bit_counter = 0;
          goto exit; 
        }
      } else {
        // поймали какую то фигню
        HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы
        goto exit; 
      }
    }
  }
  

  // ловим данные
  if(HCS_preamble_count == 12){
    if(cur_status == HIGH){
      if(((pulse_duration > 300) && (pulse_duration < 900)) || HCS_bit_counter == 0){
        // начало импульса данных
      } else {
        // неправильная пауза между импульсами
        HCS_preamble_count = 0;
        goto exit; 
      }
    } else {
      // конец импульса данных
      if((pulse_duration > 300) && (pulse_duration < 900)){
        HCS_bit_array[65 - HCS_bit_counter] = (pulse_duration > HCS_Te2_3) ? 0 : 1; // импульс больше, чем половина от Те * 3 поймали 0, иначе 1
        
        #ifdef HCS_DEBUG  
        HCS_BitDuration[HCS_bit_counter] = pulse_duration;
        #endif
        HCS_bit_counter++;  
        #ifdef HCS_DEBUG    
        arr[poz_a-1].st = HCS_bit_counter;
        #endif
        if(HCS_bit_counter == 66){
          // поймали все биты данных
        
          HCS_Listening = false;  // отключем прослушку приемника, отправляем пойманные данные на обработку
          HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы
          #ifdef HCS_DEBUG        
          HCS_msg_duration = cur_timestamp - HCS_start_preamble;
          #endif          

          hcs301.Repeat = HCS_bit_array[0];
          hcs301.BattaryLow = HCS_bit_array[1];
          hcs301.BtnNoSound = HCS_bit_array[2];
          hcs301.BtnOpen = HCS_bit_array[3];
          hcs301.BtnClose = HCS_bit_array[4];
          hcs301.BtnRing = HCS_bit_array[5];

          hcs301.SerialNum = 0;
          for(int i = 6; i < 34;i++){
            hcs301.SerialNum = (hcs301.SerialNum << 1) + HCS_bit_array[i];
          };

          uint32_t Encript = 0;
          for(int i = 34; i < 66;i++){
             Encript = (Encript << 1) + HCS_bit_array[i];
          };
          hcs301.Encript = Encript;
        }
      } else {
        // поймали хрень какую то, отключаемся
        HCS_preamble_count = 0;
        goto exit; 
      }
    }
  }
  
  exit:;

  //digitalWrite(LED_PIN,cur_status);
}

Agradecería ayuda que qué cambios realizar para que muestre todo sin invertir..

Muchas gracias de antemano.

Bueno casi conseguido.
Al final me he centrado en el segundo código ruso y he conseguido que me muestre el numero de serie y la parte encriptada al derecho y en HEX.

Solo me falta que muestre el numero de botón pulsado.

Será parte de un repetidor keeloq cuando termine. Oye la señal y la retransmite con un pulsador.
Pongo aquí el código por si a alguien le sirve.

#define LED_PIN        13
#define HCS_RECIEVER_PIN  2    // Pin al que está conectado el receptor para los mandos.


class HCS301 {
public:
  unsigned BattaryLow : 1;  // En el llavero estaba la batería.
  unsigned Repeat : 1; // повторная посылка
  unsigned BtnNoSound : 1;
  unsigned BtnOpen : 1; 
  unsigned BtnClose : 1; 
  unsigned BtnRing : 1;
  unsigned long SerialNum;
  unsigned long Encript;

  void print();
};

volatile boolean  HCS_Listening = true;   
byte        HCS_preamble_count = 0;
uint32_t      HCS_last_change = 0;
uint32_t      HCS_start_preamble = 0;
uint8_t       HCS_bit_counter;        // счетчик считанных бит данных
uint8_t       HCS_bit_array[66];        // массив считанных бит данных
#define       HCS_TE    400         // типичная длительность имульса Te
#define       HCS_Te2_3 600         // HCS_TE * 3 / 2

HCS301 hcs301;

#define HCS_DEBUG_

#ifdef HCS_DEBUG

uint16_t HCS_PulseDuration[12];
uint16_t HCS_BitDuration[66];
uint32_t HCS_msg_duration;

struct dta_ {
  uint16_t delay;
  byte f;
  byte st;
};

volatile dta_ arr[1000];
volatile int poz_a = 0,poz_b = 0;
#endif

void HCS301::print(){
  String btn;

  if (BtnRing == 1) btn += "Ring";
  if (BtnClose == 1) btn += "Close";
  if (BtnOpen == 1) btn += "Open";
  if (BtnNoSound == 1) btn += "NoSound";

  String it2;

  it2 += " Serie ";
  it2 += SerialNum;
  it2 += " ";
  
  it2 += "Rolling Code ";
  it2 += Encript;
  
  it2 += btn;
  it2 += " BattaryLow=";
  it2 += BattaryLow;
  it2 += " Rep=";
  it2 += Repeat;

  //Serial.println(it2);
  Serial.print("Serie ");
  Serial.print(SerialNum,HEX);
  Serial.print("\t");
  Serial.print("Rolling Code ");
  Serial.print(Encript,HEX);
  Serial.println("");
     

}

void setup() {                
  
  Serial.begin(9600);  
  attachInterrupt(0, HCS_interrupt, CHANGE);

  pinMode(LED_PIN, OUTPUT);
  pinMode(HCS_RECIEVER_PIN, INPUT);
}

void loop() {
  
  if(HCS_Listening == false){
    
    HCS301 msg;
    memcpy(&msg,&hcs301,sizeof(HCS301));
  
    msg.print();
    #ifdef HCS_DEBUG
    if(msg.SerialNum != 639){

      Serial.println("Raw >>>>>>>>>>>>>>>>>>>>>>>");
      while(1){
        if(poz_b == poz_a) break;
        Serial.println(String(poz_b)+String("   ")+String(arr[poz_b].delay)+String("   ")+String(arr[poz_b].f == 0 ? "LOW":"HIGH")+String("   ")+String(arr[poz_b].st));
        poz_b++;
      }
      Serial.println("Data >>>>>>>>>>>>>>>>>>>>>>>");
      for(int i = 0;i<66;i++){  Serial.println(HCS_bit_array[i]);   }
    } else {
      
    }
    poz_a = 0,poz_b = 0;
    #endif

    HCS_Listening = true;
  }
}

// 

void HCS_interrupt(){

  if(HCS_Listening == false){
    return;
  }

  uint32_t cur_timestamp = micros();
  uint8_t  cur_status = digitalRead(HCS_RECIEVER_PIN);
  uint32_t pulse_duration = cur_timestamp - HCS_last_change;
  HCS_last_change     = cur_timestamp;

  #ifdef HCS_DEBUG
  if(poz_a < 999){
    arr[poz_a].delay = pulse_duration;
    arr[poz_a].f = cur_status == HIGH ? 0 : 1;
    poz_a++;
  }
  #endif

  // ловим преамбулу
  if(HCS_preamble_count < 12){
    if(cur_status == HIGH){
      if( ((pulse_duration > 200) && (pulse_duration < 400)) || HCS_preamble_count == 0){
        // начало импульса преамбулы
        if(HCS_preamble_count == 0){
          HCS_start_preamble = cur_timestamp; // Отметим время старта преамбулы
        }
      } else {
        // поймали какую то фигню, неправильная пауза между импульсами
        HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы
        goto exit; 

      }
    } else {
      // конец импульса преамбулы
      if((pulse_duration > 400) && (pulse_duration < 600)){
        #ifdef HCS_DEBUG
          HCS_PulseDuration[HCS_preamble_count] = pulse_duration;
        #endif
        // поймали импульс преамбулы
        HCS_preamble_count ++;
        #ifdef HCS_DEBUG
        arr[poz_a-1].st = HCS_preamble_count;
        #endif
        if(HCS_preamble_count == 12){
          // словили преамбулу
          //HCS_Te = (cur_timestamp - HCS_start_preamble) / 23;  // вычисляем длительность базового импульса Te
          //HCS_Te2_3 = HCS_Te * 3 / 2;
          HCS_bit_counter = 0;
          goto exit; 
        }
      } else {
        // поймали какую то фигню
        HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы
        goto exit; 
      }
    }
  }
  

  // ловим данные
  if(HCS_preamble_count == 12){
    if(cur_status == HIGH){
      if(((pulse_duration > 300) && (pulse_duration < 900)) || HCS_bit_counter == 0){
        // начало импульса данных
      } else {
        // неправильная пауза между импульсами
        HCS_preamble_count = 0;
        goto exit; 
      }
    } else {
      // конец импульса данных
      if((pulse_duration > 300) && (pulse_duration < 900)){
        HCS_bit_array[65 - HCS_bit_counter] = (pulse_duration > HCS_Te2_3) ? 0 : 1; // импульс больше, чем половина от Те * 3 поймали 0, иначе 1
        
        #ifdef HCS_DEBUG  
        HCS_BitDuration[HCS_bit_counter] = pulse_duration;
        #endif
        HCS_bit_counter++;  
        #ifdef HCS_DEBUG    
        arr[poz_a-1].st = HCS_bit_counter;
        #endif
        if(HCS_bit_counter == 66){
          // поймали все биты данных
        
          HCS_Listening = false;  // отключем прослушку приемника, отправляем пойманные данные на обработку
          HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы
          #ifdef HCS_DEBUG        
          HCS_msg_duration = cur_timestamp - HCS_start_preamble;
          #endif          

          hcs301.Repeat = HCS_bit_array[0];
          hcs301.BattaryLow = HCS_bit_array[1];
          hcs301.BtnNoSound = HCS_bit_array[2];
          hcs301.BtnOpen = HCS_bit_array[3];
          hcs301.BtnClose = HCS_bit_array[4];
          hcs301.BtnRing = HCS_bit_array[5];

          hcs301.SerialNum = 0;
          for(int i = 6; i < 34;i++){
            hcs301.SerialNum = (hcs301.SerialNum << 1) + HCS_bit_array[i];
          };

          uint32_t Encript = 0;
          for(int i = 34; i < 66;i++){
             Encript = (Encript << 1) + HCS_bit_array[i];
          };
          hcs301.Encript = Encript;
        }
      } else {
        // поймали хрень какую то, отключаемся
        HCS_preamble_count = 0;
        goto exit; 
      }
    }
  }
  
  exit:;

  //digitalWrite(LED_PIN,cur_status);
}

Saludos

Bueno, esta fase está conseguida...Solo un detallito casi sin importancia...

Ahora muestra lo correcto:

Estos códigos recibidos pertenecen a dos mandos diferentes, de dos botones cada uno.

Abajo pegaré el codigo por si a alguien le sirve.

Ahora tengo que conseguir que cuando el numero de serie empiece por 0, como es el caso de los dos primeros, aunque arduino no muestre los ceros, precisamente que los muestre y que el serie siempre sea de 7 dígitos.
El numero de serie de la primera y segunda linea debería mostrarse así: 0F98958

Código para el receptor:

#define LED_PIN        13
#define HCS_RECIEVER_PIN  2    // Pin al que está conectado el receptor para los mandos.
 byte Canal;

class HCS301 {
public:
   unsigned BattaryLow : 1;  // En el llavero estaba la batería.
   unsigned Repeat : 1; // повторная посылка
   unsigned BtnNoSound : 1;
   unsigned BtnOpen : 1;
   unsigned BtnClose : 1;
   unsigned BtnRing : 1;
   unsigned long SerialNum;
   unsigned long Encript;
   

   void print();
};

volatile boolean  HCS_Listening = true;
byte        HCS_preamble_count = 0;
uint32_t      HCS_last_change = 0;
uint32_t      HCS_start_preamble = 0;
uint8_t       HCS_bit_counter;        // счетчик считанных бит данных
uint8_t       HCS_bit_array[66];        // массив считанных бит данных
#define       HCS_TE    400         // типичная длительность имульса Te
#define       HCS_Te2_3 600         // HCS_TE * 3 / 2

HCS301 hcs301;

#define HCS_DEBUG_

#ifdef HCS_DEBUG

uint16_t HCS_PulseDuration[12];
uint16_t HCS_BitDuration[66];
uint32_t HCS_msg_duration;

struct dta_ {
   uint16_t delay;
   byte f;
   byte st;
};

volatile dta_ arr[1000];
volatile int poz_a = 0,poz_b = 0;
#endif

void HCS301::print(){
   String btn;

   if (BtnRing == 1) btn += "Ring";
   if (BtnClose == 1) btn += "Close";
   if (BtnOpen == 1) btn += "Open";
   if (BtnNoSound == 1) btn += "NoSound";

   String it2;

   it2 += " Serie ";
   it2 += SerialNum;
   it2 += " ";

   it2 += "Rolling Code ";
   it2 += Encript;

   it2 += btn;
   it2 += " BattaryLow=";
   it2 += BattaryLow;
   it2 += " Rep=";
   it2 += Repeat;

   //Serial.println(it2);
   Serial.print("Canal ");
   Serial.print(Canal,HEX);
   Serial.print("\t");
   Serial.print("Serie ");
   Serial.print(SerialNum,HEX);
   Serial.print("\t");
   Serial.print("Rolling Code ");
   Serial.print(Encript,HEX);
   Serial.println("");


}

void setup() {
   
   Serial.begin(9600);
   attachInterrupt(0, HCS_interrupt, CHANGE);

   pinMode(LED_PIN, OUTPUT);
   pinMode(HCS_RECIEVER_PIN, INPUT);
}

void loop() {

   if(HCS_Listening == false){

     HCS301 msg;
     memcpy(&msg,&hcs301,sizeof(HCS301));

     msg.print();
     #ifdef HCS_DEBUG
     if(msg.SerialNum != 639){

       Serial.println("Raw >>>>>>>>>>>>>>>>>>>>>>>");
       while(1){
         if(poz_b == poz_a) break;
         Serial.println(String(poz_b)+String("   
")+String(arr[poz_b].delay)+String("   ")+String(arr[poz_b].f == 0 ? 
"LOW":"HIGH")+String("   ")+String(arr[poz_b].st));
         poz_b++;
       }
       Serial.println("Data >>>>>>>>>>>>>>>>>>>>>>>");
       for(int i = 0;i<66;i++){  Serial.println(HCS_bit_array[i]);   }
     } else {

     }
     poz_a = 0,poz_b = 0;
     #endif

     HCS_Listening = true;
   }
}

//

void HCS_interrupt(){

   if(HCS_Listening == false){
     return;
   }

   uint32_t cur_timestamp = micros();
   uint8_t  cur_status = digitalRead(HCS_RECIEVER_PIN);
   uint32_t pulse_duration = cur_timestamp - HCS_last_change;
   HCS_last_change     = cur_timestamp;

   #ifdef HCS_DEBUG
   if(poz_a < 999){
     arr[poz_a].delay = pulse_duration;
     arr[poz_a].f = cur_status == HIGH ? 0 : 1;
     poz_a++;
   }
   #endif

   // ловим преамбулу
   if(HCS_preamble_count < 12){
     if(cur_status == HIGH){
       if( ((pulse_duration > 200) && (pulse_duration < 400)) || HCS_preamble_count == 0){
         // начало импульса преамбулы
         if(HCS_preamble_count == 0){
           HCS_start_preamble = cur_timestamp; // Отметим время старта преамбулы
         }
       } else {
         // поймали какую то фигню, неправильная пауза между импульсами
         HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы
         goto exit;

       }
     } else {
       // конец импульса преамбулы
       if((pulse_duration > 400) && (pulse_duration < 600)){
         #ifdef HCS_DEBUG
           HCS_PulseDuration[HCS_preamble_count] = pulse_duration;
         #endif
         // поймали импульс преамбулы
         HCS_preamble_count ++;
         #ifdef HCS_DEBUG
         arr[poz_a-1].st = HCS_preamble_count;
         #endif
         if(HCS_preamble_count == 12){
           // словили преамбулу
           //HCS_Te = (cur_timestamp - HCS_start_preamble) / 23;  // вычисляем длительность базового импульса Te
           //HCS_Te2_3 = HCS_Te * 3 / 2;
           HCS_bit_counter = 0;
           goto exit;
         }
       } else {
         // поймали какую то фигню
         HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы
         goto exit;
       }
     }
   }


   // ловим данные
   if(HCS_preamble_count == 12){
     if(cur_status == HIGH){
       if(((pulse_duration > 300) && (pulse_duration < 900)) || HCS_bit_counter == 0){
         // начало импульса данных
       } else {
         // неправильная пауза между импульсами
         HCS_preamble_count = 0;
         goto exit;
       }
     } else {
       // конец импульса данных
       if((pulse_duration > 300) && (pulse_duration < 900)){
         HCS_bit_array[65 - HCS_bit_counter] = (pulse_duration >
HCS_Te2_3) ? 0 : 1; // импульс больше, чем половина от Те * 3 поймали 0, иначе 1

         #ifdef HCS_DEBUG
         HCS_BitDuration[HCS_bit_counter] = pulse_duration;
         #endif
         HCS_bit_counter++;
         #ifdef HCS_DEBUG
         arr[poz_a-1].st = HCS_bit_counter;
         #endif
         if(HCS_bit_counter == 66){
           // поймали все биты данных

           HCS_Listening = false;  // отключем прослушку приемника, отправляем пойманные данные на обработку
           HCS_preamble_count = 0; // сбрасываем счетчик пойманных импульсов преамбулы
           #ifdef HCS_DEBUG
           HCS_msg_duration = cur_timestamp - HCS_start_preamble;
           #endif

           hcs301.Repeat = HCS_bit_array[0];
           hcs301.BattaryLow = HCS_bit_array[1];
           hcs301.BtnNoSound = HCS_bit_array[2];
           hcs301.BtnOpen = HCS_bit_array[3];
           hcs301.BtnClose = HCS_bit_array[4];
           hcs301.BtnRing = HCS_bit_array[5];

           Canal=HCS_bit_array[5]+2*HCS_bit_array[4]+4*HCS_bit_array[3]+8*HCS_bit_array[2];

           hcs301.SerialNum = 0;
           for(int i = 6; i < 34;i++){
             hcs301.SerialNum = (hcs301.SerialNum << 1) + HCS_bit_array[i];
           };

           uint32_t Encript = 0;
           for(int i = 34; i < 66;i++){
              Encript = (Encript << 1) + HCS_bit_array[i];
           };
           hcs301.Encript = Encript;
         }
       } else {
         // поймали хрень какую то, отключаемся
         HCS_preamble_count = 0;
         goto exit;
       }
     }
   }

   exit:;

   //digitalWrite(LED_PIN,cur_status);
}

Gracias

Pues me he confundido, en lugar de ! debes usar ~

 for (int i =0; i<9; i++)
      keelog_code[i] = ~keelog_code[i];

lo mas lindo es que te lo puse

Bueno sino inverte bits usando ! o ~

y poco te hubiera costado probar.

! invierte un bit
~ invierte bits de un byte.

Surbyte,
Agradezco enormemente tus consejos y sugerencias, pero probé lo que me dijiste y salí todo a 0. Así te lo hice saber.
Como en paralelo yo seguía buscando, encontré ese código y lo vi más fácil. De hecho he copiado una parte y hace al 90% lo que yo buscaba.
Insisto, te agradezco tu ayuda.

Me queda conseguir que complete el numero de serie a 7 dígitos cuando solo tenga 6, añadiendo un 0 a la izquierda. El resultado final tiene que ser siempre X XXXXXXX XXXXXXXX.

Gracias y saludos

Pero esto

keelog_code[i] = ~keelog_code[i]; // ESTO SI FUNCIONA

es distinto de lo que probaste que fue esto

keelog_code[i] = !keelog_code[i]; // ESTO NO FUNCIONA, me equivoqué

Hola surbyte

Lo acabo de probar de nuevo, sigue sin mostrarlo en el orden correcto.

El numero de serie correcto es FFA08CB y muestra esto:


No vale la pena seguir queriondolo arreglar si ya tengo el otro código.

Ahora ya lo consigo con el segundo código publicado anteriormente en el post #5.

Insisto, muchas gracias

Mira lo que hace el codigo del post #5:

Numeros correctos del mando:

2FFA08CBBC96441E

Este es el camino por donde voy a seguir.

Gracias

1 Like

podrias indicar el modelo o algun dato del receptor? muchas gracias

Hola
Para el receptor te sirve cualquier modulo receptor de la misma frecuencia que los mandos que quieras leer. Europa 433 MHz, USA 315 MHz.

Estos me llegaron ayer

Suelen vender la pareja TX + RX. Hay decenas de modelos que te sirven. Solo tener cuidado de comprar de la frecuencia del mando.

Saludos.