Skip to content

Instantly share code, notes, and snippets.

@acturcato
Created January 14, 2014 18:32
Show Gist options
  • Select an option

  • Save acturcato/8423241 to your computer and use it in GitHub Desktop.

Select an option

Save acturcato/8423241 to your computer and use it in GitHub Desktop.

Revisions

  1. acturcato created this gist Jan 14, 2014.
    281 changes: 281 additions & 0 deletions ACT_HT6P20B_CODEGRABBER.ino
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,281 @@
    /*
    TITLE: CODE GRABBER FOR HT6P20B ENCODER
    CREATED BY: AFONSO CELSO TURCATO
    DATE: 14/JAN/2014
    E-MAIL: acturcato (at) gmail.com
    LICENSE: GPL
    REV.: 00
    DESCRIÇÃO:
    http://acturcato.wordpress.com/2014/01/14/clonagem-de-controle-remoto-rf-learning-code-ht6p20b-com-arduino/
    */

    struct rfControl //Struct for RF Remote Controls
    {
    unsigned long addr; //ADDRESS CODE
    boolean btn1; //BUTTON 1
    boolean btn2; //BUTTON 2
    };

    struct rfControl rfControl_RX; //Set variable rfControl_RX as rfControl type.
    struct rfControl rfControl_TX; //Set variable rfControl_TX as rfControl type.

    const byte pinRF_RX = 52; //Pin where RF Receiver Module is connected. If necessary, change this for your project
    const byte pinRF_TX = 53; //Pin where RF Transmitter Module is connected. If necessary, change this for your project
    const byte pinButton_TX = 2; //Pin where "Enable transmission button" is connected. Change this field as pin used in your project
    const byte pinLearnButton = 3; //Pin where "Learn button" is connected. Change this field as pin used in your project
    const byte pinLearnLED = 4; //Pin where "Learning Led" is connected
    const byte pinReceiveLED = 13; //On board Led

    volatile unsigned int lambda; // desired value for Pulse Clock Width on Transmissions cases

    void myDelay(unsigned int t)
    {
    delayMicroseconds(t);
    }

    void sendData(char data)
    {
    int pulse = (int)lambda;

    if(data == '0')
    {
    digitalWrite(pinRF_TX, LOW);
    myDelay(pulse);

    digitalWrite(pinRF_TX, HIGH);
    myDelay(2 * pulse);
    }

    if(data == '1')
    {
    digitalWrite(pinRF_TX, LOW);
    myDelay(2 * pulse);

    digitalWrite(pinRF_TX, HIGH);
    myDelay(pulse);
    }
    }

    void sendPilotCode()
    {
    //Keep pinRF on HIGH for little time
    digitalWrite(pinRF_TX, HIGH);
    delayMicroseconds(500);

    //Set pinRF on LOW for 23 Lambdas
    digitalWrite(pinRF_TX, LOW);
    myDelay(23 * lambda);

    //Set pinRF on HIGH for one Lambda
    digitalWrite(pinRF_TX, HIGH);
    myDelay(lambda);
    }

    void sendAddressCode(unsigned long addressCodeHEX)
    {
    String addressCodeBIN = "0000000000000000000000" + String(addressCodeHEX, BIN);

    addressCodeBIN = addressCodeBIN.substring(addressCodeBIN.length()-22, addressCodeBIN.length());

    //Send all bits for Address Code
    for(int i=0; i<22; i++)
    {
    char data = addressCodeBIN[i];
    sendData(data);
    }
    }

    void sendDataCode(boolean btn1, boolean btn2)
    {
    //Send BTN2 values
    if(btn2)
    sendData('1');
    else
    sendData('0');

    //Send BTN1 values
    if(btn1)
    sendData('1');
    else
    sendData('0');
    }

    void sendAntiCode()
    {
    sendData('0');
    sendData('1');
    sendData('0');
    sendData('1');
    }

    void sendAllCodes()
    {
    //Check if there is already a valid value stored
    if(!rfControl_TX.addr == NULL)
    {
    //Send PILOTE CODE (details: http://acturcato.wordpress.com/2014/01/04/decoder-for-ht6p20b-encoder-on-arduino-board-english/)
    sendPilotCode();

    //Send stored ADDRESS CODE
    sendAddressCode(rfControl_TX.addr);

    //Send stored DATA CODE of buttons
    sendDataCode(rfControl_TX.btn1, rfControl_TX.btn2);

    //Send a valid ANTI-CODE
    sendAntiCode();
    }
    }

    boolean receiveAllCodes(struct rfControl &_rfControl)
    {
    static boolean startbit; //checks if start bit was identified
    static int counter; //received bits counter: 22 of Address + 2 of Data + 4 of EndCode (Anti-Code)
    static unsigned long buffer; //buffer for received data storage

    int lambda; // on pulse clock width (if fosc = 2KHz than lambda = 500 us)
    int dur0, dur1; // pulses durations (auxiliary)

    if (!startbit)
    {// Check the PILOT CODE until START BIT;
    dur0 = pulseIn(pinRF_RX, LOW); //Check how long DOUT was "0" (ZERO) (refers to PILOT CODE)

    //If time at "0" is between 9200 us (23 cycles of 400us) and 13800 us (23 cycles of 600 us).
    if((dur0 > 9200) && (dur0 < 13800) && !startbit)
    {
    //calculate wave length - lambda
    lambda = dur0 / 23;

    //Reset variables
    dur0 = 0;
    buffer = 0;
    counter = 0;

    startbit = true;
    }
    }

    //If Start Bit is OK, then starts measure os how long the signal is level "1" and check is value is into acceptable range.
    if (startbit && counter < 28)
    {
    ++counter;

    dur1 = pulseIn(pinRF_RX, HIGH);

    if((dur1 > 0.5 * lambda) && (dur1 < (1.5 * lambda))) //If pulse width at "1" is between "0.5 and 1.5 lambda", means that pulse is only one lambda, so the data é "1".
    {
    buffer = (buffer << 1) + 1; // add "1" on data buffer
    }
    else if((dur1 > 1.5 * lambda) && (dur1 < (2.5 * lambda))) //If pulse width at "1" is between "1.5 and 2.5 lambda", means that pulse is two lambdas, so the data é "0".
    {
    buffer = (buffer << 1); // add "0" on data buffer
    }
    else
    {
    //Reset the loop
    startbit = false;
    }
    }

    //Check if all 28 bits were received (22 of Address + 2 of Data + 4 of Anti-Code)
    if (counter==28)
    {
    // Check if Anti-Code is OK (last 4 bits of buffer equal "0101")
    if ((bitRead(buffer, 0) == 1) && (bitRead(buffer, 1) == 0) && (bitRead(buffer, 2) == 1) && (bitRead(buffer, 3) == 0))
    {
    counter = 0;
    startbit = false;

    //Get ADDRESS CODE from Buffer
    _rfControl.addr = buffer >> 6;

    //Get Buttons from Buffer
    _rfControl.btn1 = bitRead(buffer,4);
    _rfControl.btn2 = bitRead(buffer,5);

    //If a valid data is received, return OK
    return true;
    }
    else
    {
    //Reset the loop
    startbit = false;
    }
    }

    //If none valid data is received, return NULL and FALSE values
    _rfControl.addr = NULL;
    _rfControl.btn1 = NULL;
    _rfControl.btn2 = NULL;

    return false;
    }

    void setup()
    {
    //Change this value according to the values ​​accepted by your RH receiver. In my tests, the values ​​between 320 and 420 were OK!
    lambda = 350;

    pinMode(pinButton_TX, INPUT);
    pinMode(pinRF_RX, INPUT);
    pinMode(pinRF_TX, OUTPUT);

    pinMode(pinLearnButton, INPUT);
    pinMode(pinLearnLED, OUTPUT);

    pinMode(pinReceiveLED, OUTPUT);

    //Set de interrupt mode (See: http://arduino.cc/en/Reference/attachInterrupt for more details)
    attachInterrupt(pinButton_TX - 2, sendAllCodes, LOW);

    //Initialize serial communications at 9600 bps:
    Serial.begin(9600);

    //Start pinRF_TX on LOW (disable transmissions)
    digitalWrite(pinRF_TX, LOW);

    //Wait a second for RF modules startup
    delay(1000);
    }

    void loop()
    {
    //Disables transmissions
    digitalWrite(pinRF_TX, LOW);

    //Blink Received LED when receive something
    digitalWrite(pinReceiveLED, digitalRead(pinRF_RX));

    //Check if Learn Button was pressed
    if(!digitalRead(pinLearnButton) && !digitalRead(pinLearnLED))
    {
    digitalWrite(pinLearnLED, HIGH);
    Serial.println("#Learning Mode ENABLED! Reset the board to cancel...\n");
    }

    if(receiveAllCodes(rfControl_RX))
    {
    //If a valid data is received, print ADDRESS CODE and Buttons values
    Serial.println("#Received data:");
    Serial.print("\tAddress: "); Serial.println(rfControl_RX.addr, HEX);
    Serial.print("\tButton1: "); Serial.println(rfControl_RX.btn1, BIN);
    Serial.print("\tButton2: "); Serial.println(rfControl_RX.btn2, BIN);
    Serial.println();

    //If Learning Mode is enabled, store data.
    if(digitalRead(pinLearnLED))
    {
    //Set values to "clone"
    rfControl_TX.addr = rfControl_RX.addr;
    rfControl_TX.btn1 = rfControl_RX.btn1;
    rfControl_TX.btn2 = rfControl_RX.btn2;

    Serial.print("#The address "); Serial.print(rfControl_RX.addr, HEX); Serial.println(" has been grabbed!\n");

    digitalWrite(pinLearnLED, LOW);

    Serial.println("#Learning Mode DISABLED!\n");
    }
    }
    }