Hi: I made a code to receive RF data from a generic RF ASK 433 MHz remote control. Usually these RC have Holtek HT6P20x chip inside with 2 or 4 channels. (http://www.holtek.com/pdf/consumer/6p20v170.pdf)
The concept is simple, I programmed an external pin interrupt. The interrupt occurs with every pin change. I register de pin value and the pin time (micros() function) with every interrupt, in 2 circular buffers. Then in the loop program, if new data is available it is analyzed to recognize the Holtek encoding frame.
A lot of noise is received constantly by the RF receiver. This is normal in ASK receivers, I mus live with it. But Holtek chip send a pilot signal with every transmission and transmissions are repeated many times while you keep the RC button pressed, each one last few milliseconds, so to avoid noise receptions I check 2 consecutive pilot signals and then read and analice the data.
Still some noise data is recognized like a RC address and code and don't know how to avoid. Never the less, my car alarm works!
The code worked fine but I'd like to exhibit this code to the community to be criticized and improved.
Please, any kind of feedback is accepted an appreciated!
Thanks for your time and regards. ![]()
///////////////////////////////////////////////////////////////////////////////////////////////////
// DEFINE
///////////////////////////////////////////////////////////////////////////////////////////////////
#define top_unsigned_long 4294967295
///////////////////////////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
///////////////////////////////////////////////////////////////////////////////////////////////////
volatile static int pe=0,pl=0, rc_index;
volatile static long unsigned int buftime[100];
volatile static boolean bufdata[100];
static byte rc_code=0;
static long unsigned int rc_address=0;
static long unsigned int rc_habilitados[10];
static unsigned long x,address,code;
static boolean modo_aprendizaje=false;
///////////////////////////////////////////////////////////////////////////////////////////////////
// SETUP
///////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
pinMode(2,INPUT);
digitalWrite(2, HIGH);
pinMode(13,OUTPUT);
Serial.begin(115200);
attachInterrupt(0,Holtek_rx_pinchange,CHANGE);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// LOOP
///////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
int n;
long unsigned int rc_aprendido;
static boolean led=false;
static unsigned long auxaddress;
static int pasoapre=0;
// RC Read ////////////////////////////////////////////////////////////////////////////
x=Holtek_decoder();
if (x!=0ul)
{
address=x>>4;
code=x & 0x000F;
Serial.print(address);Serial.print(" "); Serial.println(code);
}
address=0;
code=0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// SUBPROGRAM
/////////////////////////////////////////////////////////////////////////////////////////////////////////*/
unsigned long Holtek_decoder()
{
static long unsigned int dift,resultado,tbase1=450ul,tbase0=650ul;
static int pasotrama=0,bit_no,byte_no=0,shift,countpiloto=0,countchanges=0;
resultado=0ul;
// Controls every received new bit
if (pl!=pe)
{
dift=0;
if (pl>0)
{
dift=buftime[pl]-buftime[pl-1];
buftime[pl-1]=0ul;
}
if(countchanges++>58) countchanges=countpiloto=pasotrama=0;
switch (pasotrama)
{
case 0: //1st PILOT 23 clocks Zero & 58 pin changes.
if (dift>11000ul && dift<11500ul && !bufdata[pl])
{
countpiloto++;
countchanges=0;
pasotrama=3;
}
rc_address=rc_code=0;
break; //waits for next bit
case 1: //2nd PILOT 23 clocks Zero & 58 pin changes.
if (dift>11000ul && dift<11500ul && !bufdata[pl] && countchanges==58)
{
countpiloto++;
countchanges=0;
pasotrama=3;
}
rc_address=rc_code=0;
break; //waits for next bit
case 3: // 1/3 bit clock synchro
if (dift<=450ul && bufdata[pl] && countchanges==1 && countpiloto==1)
{
pasotrama=4;
}
else pasotrama=0;
rc_address=rc_code=0;
break; //waits for next bit
// Receive RC ADDRESS
case 4: //receive 20 address bits (60 clocks) & 4 code bits (12 clocks) (even if RC uses an 8 pinn chip, 24 bits are always sent) (read Holtek datasheet)
if (bufdata[pl] && dift>=tbase0) //Coded "0"
{
shift++;
}
else if (bufdata[pl] && dift<=tbase1) //Coded "1"
{
bitSet(rc_address,shift);
shift++;
}
if (shift==20)
{
shift=0;
pasotrama=5;
}
break; //waits for next bit
// Receive CODE
case 5: //receive 20 address bits (60 clocks) & 4 code bits (12 clocks) (even if RC uses an 8 pinn chip, 24 bits are always sent) (read Holtek datasheet)
if (bufdata[pl] && dift>=tbase0)
{
shift++;
}
else if (bufdata[pl] && dift<=tbase1)
{
bitSet(rc_code,shift);
shift++;
}
if (shift==4)
{
shift=0;
pasotrama=6;
}
break; //waits for next bit
case 6:
pasotrama=0;
resultado=rc_address<<4|rc_code;
break;
}
if( (pl++) >= 100) pl=0;
}
return (resultado);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// INTERRUPTS
/////////////////////////////////////////////////////////////////////////////////////////////////////////*/
void Holtek_rx_pinchange()
{
buftime[pe]=micros();
bufdata[pe]=!digitalRead(2); //Inverted so the registered time corresponds to the registeres bit level
if ( (pe++) >= 100) pe=0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////