A simple IR NEC decodifier...

Dependencies:   Pulse1 mbed

main.cpp

Committer:
PabloViana
Date:
2015-11-07
Revision:
0:3176800d0f26

File content as of revision 0:3176800d0f26:

/*The IR transmiter uses NEC infrared protocol, the following information is taken from http://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol and is the basis for the development of the software below:


The NEC IR transmission protocol uses pulse distance encoding of the message bits. Each pulse burst (mark – RC transmitter ON) is 562.5µs in length, at a carrier frequency of 38kHz (26.3µs). Logical bits are transmitted as follows:

    Logical '0' – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms

    Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms

When a key is pressed on the remote controller, the message transmitted consists of the following, in order:

    a 9ms leading pulse burst (16 times the pulse burst length used for a logical data bit)

    a 4.5ms space

    the 8-bit address for the receiving device

    the 8-bit logical inverse of the address

    the 8-bit command

    the 8-bit logical inverse of the command

    a final 562.5µs pulse burst to signify the end of message transmission.
*/
#include "mbed.h"
#include <Pulse1.h> //Library developed by Gustavo Ramirez;

PulseInOut irda(PTD5);// IR sensor input port;
Serial pc(USBTX, USBRX); //Serial USB;
PwmOut Led(LED1);
PwmOut Pwm1(PTA13);

int header =0; //Variable to store the header length
const int head_H = 9000*1.2; //+20% header length
const int head_L = 9000*0.8;//-20%  header length
int i=0;
int n=0;

float PeriodoPWM1=0.001;
float PeriodoLed=1.0;
float DC1=0.5;

const int pulso=562.5;//NEC uses 562.5µs pulse bursts;
const int num_bits = 32;//8 bits address - 8 bits address logical inverse -  8 bits data - 8 bits data logical inverse;
int num[num_bits];//Array to store logical 1 length;
int data_bin[num_bits]; //Array to store binary code transmited;
int address1; //variable to store the device address;
int address0; //variable to store the device address (inverse);
int data1; //variable to store the transmited data;
int data0; //variable to store the transmited data (inverse);

/****Las teclas del control****/
const int b_ok =64;
const int b_up=70;
const int b_down=21;
const int b_left =68;
const int b_rigth=67;

int main()
{
    /************Confugurar PWM****************/


    pc.printf("Handbook: There are two PWM configured , one is set at green led and the other one at PTA13 pin, the initial periods are 1 seconds and 1 miliseconds ; the duty cicle is 0.5 for both of them. \n\rYou can modify the period by pressing the up  and down keys, by doing so the value will be increased or decreased by steps of 0.1 seconds for green led and 0.1 miliseconds for  PTA13 pin...\n\r");
    pc.printf("The duty cicle can be modified as well, in order to do so press left or rigth key, the value will be modified by steps of 0.1 (10%)\n\r");
    pc.printf("Disclaimer: NEC Repeat Code is not  considered, keeping a key held down can result in bad data, please press and release...\n\r");

    Led.period(PeriodoLed);
    Led.write(DC1);
    Pwm1.period(PeriodoPWM1);
    Pwm1.write(DC1);

    while(1) {



        /********************Header detection************************/
ini1:
        header=0;
        pc.printf("\nPress a key\n\r");
        header = irda.read_low_us();

        if (header > head_L && header < head_H) goto seguir;//verificar que este en la tolerancia +-20%
        else goto ini1;
        /*Once the header is detected the program stores the length of every high state*/
seguir:
        //leo los datos de la trama y se meten a un arreglo

        wait_us(4500/2);
        for(i=0; i<(num_bits); ++i) {
            num[i]=irda.read_high_us(); //Times for ever high state is store in microseconds
            wait_us(400);  //wait a portion of the low state (562.5µs)
        }
        /*Imprimir en pantalla lo que obtengo*/
        for(i=0; i<(num_bits); ++i) {
            if(num[i]>pulso*1.2) {
                data_bin[i]=1;   //if length is greater than a burst it represents a 1
            } else {
                data_bin[i]=0;   //if length is shorter than a burst it represents a 0
            }

        }

        pc.printf("\n\r");
        /*************Convert binary into Decimal (less significant bit first)*****************/
        address1=0;
        pc.printf("Device  address:\n\rBinary:");
        for(i=0; i<8; i++) {
            address1=address1 + data_bin[i]*pow(2.0,i*1.0);
            pc.printf("%d",data_bin[i]);
        }
        pc.printf("\n\rDecimal:%d\n\r", address1);


        address0=0;
        pc.printf("Device inverse address:\n\rBinary:");
        for(i=8; i<16; i++) {
            address0=address0 + data_bin[i]*pow(2.0,(i-8)*1.0);
            pc.printf("%d",data_bin[i]);
        }
        pc.printf("\n\rDecimal:%d\n\r", address0);


        data1=0;
        pc.printf("Device data:\n\rBinary:");
        for(i=16; i<24; i++) {
            data1=data1 + data_bin[i]*pow(2.0,(i-16.0)*1.0);
            pc.printf("%d",data_bin[i]);
        }
        pc.printf("\n\rDecimal:%d\n\r", data1);


        data0=0;
        pc.printf("Device inverse data:\n\rBinary:");
        for(i=24; i<32; i++) {
            data0=data0 + data_bin[i]*pow(2.0,(i-24)*1.0);
            pc.printf("%d",data_bin[i]);
        }
        pc.printf("\n\rDecimal:%d\n\r", data0);

        /*PWM parameters*/
        if (data1==b_up) {
            PeriodoPWM1=PeriodoPWM1+0.0001;
            PeriodoLed=PeriodoLed+0.1;
            pc.printf("\n\n\rPeriod:\n\rLed:%.2f sec\n\rPWM1:%.2f ms\n\r", PeriodoLed, PeriodoPWM1*1000);
        }
        if (data1==b_down) {
            PeriodoPWM1=PeriodoPWM1-0.0001;
            PeriodoLed=PeriodoLed-0.1;
            pc.printf("\n\n\rPeriod:\n\rLed:%.2f sec\n\rPWM1:%.2f ms\n\r", PeriodoLed, PeriodoPWM1*1000);
        }
        if (data1==b_left) {

            DC1=DC1-0.1;
            if(DC1<0.0) {
                DC1=0;
            }
            pc.printf("\n\nDuty Cicle:%f\n\r", DC1);
        }
        if (data1==b_rigth) {
            DC1=DC1+0.1;
            if(DC1>1.0) {
                DC1=1.0;
            }
            pc.printf("\n\nDuty Cicle:%f\n\r", DC1);
        }
        if (data1==b_ok) {
            pc.printf("Ok\n\r");
        }

        Led.period(PeriodoLed);
        Led.write(DC1);
        Pwm1.period(PeriodoPWM1);
        Pwm1.write(DC1);
    }//while
}//main