A simple IR NEC decodifier...

Dependencies:   Pulse1 mbed

Revision:
0:3176800d0f26
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Nov 07 22:08:43 2015 +0000
@@ -0,0 +1,177 @@
+/*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
\ No newline at end of file