A simple IR NEC decodifier...

Dependencies:   Pulse1 mbed

Committer:
PabloViana
Date:
Sat Nov 07 22:08:43 2015 +0000
Revision:
0:3176800d0f26
v1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
PabloViana 0:3176800d0f26 1 /*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:
PabloViana 0:3176800d0f26 2
PabloViana 0:3176800d0f26 3
PabloViana 0:3176800d0f26 4 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:
PabloViana 0:3176800d0f26 5
PabloViana 0:3176800d0f26 6 Logical '0' – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms
PabloViana 0:3176800d0f26 7
PabloViana 0:3176800d0f26 8 Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms
PabloViana 0:3176800d0f26 9
PabloViana 0:3176800d0f26 10 When a key is pressed on the remote controller, the message transmitted consists of the following, in order:
PabloViana 0:3176800d0f26 11
PabloViana 0:3176800d0f26 12 a 9ms leading pulse burst (16 times the pulse burst length used for a logical data bit)
PabloViana 0:3176800d0f26 13
PabloViana 0:3176800d0f26 14 a 4.5ms space
PabloViana 0:3176800d0f26 15
PabloViana 0:3176800d0f26 16 the 8-bit address for the receiving device
PabloViana 0:3176800d0f26 17
PabloViana 0:3176800d0f26 18 the 8-bit logical inverse of the address
PabloViana 0:3176800d0f26 19
PabloViana 0:3176800d0f26 20 the 8-bit command
PabloViana 0:3176800d0f26 21
PabloViana 0:3176800d0f26 22 the 8-bit logical inverse of the command
PabloViana 0:3176800d0f26 23
PabloViana 0:3176800d0f26 24 a final 562.5µs pulse burst to signify the end of message transmission.
PabloViana 0:3176800d0f26 25 */
PabloViana 0:3176800d0f26 26 #include "mbed.h"
PabloViana 0:3176800d0f26 27 #include <Pulse1.h> //Library developed by Gustavo Ramirez;
PabloViana 0:3176800d0f26 28
PabloViana 0:3176800d0f26 29 PulseInOut irda(PTD5);// IR sensor input port;
PabloViana 0:3176800d0f26 30 Serial pc(USBTX, USBRX); //Serial USB;
PabloViana 0:3176800d0f26 31 PwmOut Led(LED1);
PabloViana 0:3176800d0f26 32 PwmOut Pwm1(PTA13);
PabloViana 0:3176800d0f26 33
PabloViana 0:3176800d0f26 34 int header =0; //Variable to store the header length
PabloViana 0:3176800d0f26 35 const int head_H = 9000*1.2; //+20% header length
PabloViana 0:3176800d0f26 36 const int head_L = 9000*0.8;//-20% header length
PabloViana 0:3176800d0f26 37 int i=0;
PabloViana 0:3176800d0f26 38 int n=0;
PabloViana 0:3176800d0f26 39
PabloViana 0:3176800d0f26 40 float PeriodoPWM1=0.001;
PabloViana 0:3176800d0f26 41 float PeriodoLed=1.0;
PabloViana 0:3176800d0f26 42 float DC1=0.5;
PabloViana 0:3176800d0f26 43
PabloViana 0:3176800d0f26 44 const int pulso=562.5;//NEC uses 562.5µs pulse bursts;
PabloViana 0:3176800d0f26 45 const int num_bits = 32;//8 bits address - 8 bits address logical inverse - 8 bits data - 8 bits data logical inverse;
PabloViana 0:3176800d0f26 46 int num[num_bits];//Array to store logical 1 length;
PabloViana 0:3176800d0f26 47 int data_bin[num_bits]; //Array to store binary code transmited;
PabloViana 0:3176800d0f26 48 int address1; //variable to store the device address;
PabloViana 0:3176800d0f26 49 int address0; //variable to store the device address (inverse);
PabloViana 0:3176800d0f26 50 int data1; //variable to store the transmited data;
PabloViana 0:3176800d0f26 51 int data0; //variable to store the transmited data (inverse);
PabloViana 0:3176800d0f26 52
PabloViana 0:3176800d0f26 53 /****Las teclas del control****/
PabloViana 0:3176800d0f26 54 const int b_ok =64;
PabloViana 0:3176800d0f26 55 const int b_up=70;
PabloViana 0:3176800d0f26 56 const int b_down=21;
PabloViana 0:3176800d0f26 57 const int b_left =68;
PabloViana 0:3176800d0f26 58 const int b_rigth=67;
PabloViana 0:3176800d0f26 59
PabloViana 0:3176800d0f26 60 int main()
PabloViana 0:3176800d0f26 61 {
PabloViana 0:3176800d0f26 62 /************Confugurar PWM****************/
PabloViana 0:3176800d0f26 63
PabloViana 0:3176800d0f26 64
PabloViana 0:3176800d0f26 65 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");
PabloViana 0:3176800d0f26 66 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");
PabloViana 0:3176800d0f26 67 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");
PabloViana 0:3176800d0f26 68
PabloViana 0:3176800d0f26 69 Led.period(PeriodoLed);
PabloViana 0:3176800d0f26 70 Led.write(DC1);
PabloViana 0:3176800d0f26 71 Pwm1.period(PeriodoPWM1);
PabloViana 0:3176800d0f26 72 Pwm1.write(DC1);
PabloViana 0:3176800d0f26 73
PabloViana 0:3176800d0f26 74 while(1) {
PabloViana 0:3176800d0f26 75
PabloViana 0:3176800d0f26 76
PabloViana 0:3176800d0f26 77
PabloViana 0:3176800d0f26 78 /********************Header detection************************/
PabloViana 0:3176800d0f26 79 ini1:
PabloViana 0:3176800d0f26 80 header=0;
PabloViana 0:3176800d0f26 81 pc.printf("\nPress a key\n\r");
PabloViana 0:3176800d0f26 82 header = irda.read_low_us();
PabloViana 0:3176800d0f26 83
PabloViana 0:3176800d0f26 84 if (header > head_L && header < head_H) goto seguir;//verificar que este en la tolerancia +-20%
PabloViana 0:3176800d0f26 85 else goto ini1;
PabloViana 0:3176800d0f26 86 /*Once the header is detected the program stores the length of every high state*/
PabloViana 0:3176800d0f26 87 seguir:
PabloViana 0:3176800d0f26 88 //leo los datos de la trama y se meten a un arreglo
PabloViana 0:3176800d0f26 89
PabloViana 0:3176800d0f26 90 wait_us(4500/2);
PabloViana 0:3176800d0f26 91 for(i=0; i<(num_bits); ++i) {
PabloViana 0:3176800d0f26 92 num[i]=irda.read_high_us(); //Times for ever high state is store in microseconds
PabloViana 0:3176800d0f26 93 wait_us(400); //wait a portion of the low state (562.5µs)
PabloViana 0:3176800d0f26 94 }
PabloViana 0:3176800d0f26 95 /*Imprimir en pantalla lo que obtengo*/
PabloViana 0:3176800d0f26 96 for(i=0; i<(num_bits); ++i) {
PabloViana 0:3176800d0f26 97 if(num[i]>pulso*1.2) {
PabloViana 0:3176800d0f26 98 data_bin[i]=1; //if length is greater than a burst it represents a 1
PabloViana 0:3176800d0f26 99 } else {
PabloViana 0:3176800d0f26 100 data_bin[i]=0; //if length is shorter than a burst it represents a 0
PabloViana 0:3176800d0f26 101 }
PabloViana 0:3176800d0f26 102
PabloViana 0:3176800d0f26 103 }
PabloViana 0:3176800d0f26 104
PabloViana 0:3176800d0f26 105 pc.printf("\n\r");
PabloViana 0:3176800d0f26 106 /*************Convert binary into Decimal (less significant bit first)*****************/
PabloViana 0:3176800d0f26 107 address1=0;
PabloViana 0:3176800d0f26 108 pc.printf("Device address:\n\rBinary:");
PabloViana 0:3176800d0f26 109 for(i=0; i<8; i++) {
PabloViana 0:3176800d0f26 110 address1=address1 + data_bin[i]*pow(2.0,i*1.0);
PabloViana 0:3176800d0f26 111 pc.printf("%d",data_bin[i]);
PabloViana 0:3176800d0f26 112 }
PabloViana 0:3176800d0f26 113 pc.printf("\n\rDecimal:%d\n\r", address1);
PabloViana 0:3176800d0f26 114
PabloViana 0:3176800d0f26 115
PabloViana 0:3176800d0f26 116 address0=0;
PabloViana 0:3176800d0f26 117 pc.printf("Device inverse address:\n\rBinary:");
PabloViana 0:3176800d0f26 118 for(i=8; i<16; i++) {
PabloViana 0:3176800d0f26 119 address0=address0 + data_bin[i]*pow(2.0,(i-8)*1.0);
PabloViana 0:3176800d0f26 120 pc.printf("%d",data_bin[i]);
PabloViana 0:3176800d0f26 121 }
PabloViana 0:3176800d0f26 122 pc.printf("\n\rDecimal:%d\n\r", address0);
PabloViana 0:3176800d0f26 123
PabloViana 0:3176800d0f26 124
PabloViana 0:3176800d0f26 125 data1=0;
PabloViana 0:3176800d0f26 126 pc.printf("Device data:\n\rBinary:");
PabloViana 0:3176800d0f26 127 for(i=16; i<24; i++) {
PabloViana 0:3176800d0f26 128 data1=data1 + data_bin[i]*pow(2.0,(i-16.0)*1.0);
PabloViana 0:3176800d0f26 129 pc.printf("%d",data_bin[i]);
PabloViana 0:3176800d0f26 130 }
PabloViana 0:3176800d0f26 131 pc.printf("\n\rDecimal:%d\n\r", data1);
PabloViana 0:3176800d0f26 132
PabloViana 0:3176800d0f26 133
PabloViana 0:3176800d0f26 134 data0=0;
PabloViana 0:3176800d0f26 135 pc.printf("Device inverse data:\n\rBinary:");
PabloViana 0:3176800d0f26 136 for(i=24; i<32; i++) {
PabloViana 0:3176800d0f26 137 data0=data0 + data_bin[i]*pow(2.0,(i-24)*1.0);
PabloViana 0:3176800d0f26 138 pc.printf("%d",data_bin[i]);
PabloViana 0:3176800d0f26 139 }
PabloViana 0:3176800d0f26 140 pc.printf("\n\rDecimal:%d\n\r", data0);
PabloViana 0:3176800d0f26 141
PabloViana 0:3176800d0f26 142 /*PWM parameters*/
PabloViana 0:3176800d0f26 143 if (data1==b_up) {
PabloViana 0:3176800d0f26 144 PeriodoPWM1=PeriodoPWM1+0.0001;
PabloViana 0:3176800d0f26 145 PeriodoLed=PeriodoLed+0.1;
PabloViana 0:3176800d0f26 146 pc.printf("\n\n\rPeriod:\n\rLed:%.2f sec\n\rPWM1:%.2f ms\n\r", PeriodoLed, PeriodoPWM1*1000);
PabloViana 0:3176800d0f26 147 }
PabloViana 0:3176800d0f26 148 if (data1==b_down) {
PabloViana 0:3176800d0f26 149 PeriodoPWM1=PeriodoPWM1-0.0001;
PabloViana 0:3176800d0f26 150 PeriodoLed=PeriodoLed-0.1;
PabloViana 0:3176800d0f26 151 pc.printf("\n\n\rPeriod:\n\rLed:%.2f sec\n\rPWM1:%.2f ms\n\r", PeriodoLed, PeriodoPWM1*1000);
PabloViana 0:3176800d0f26 152 }
PabloViana 0:3176800d0f26 153 if (data1==b_left) {
PabloViana 0:3176800d0f26 154
PabloViana 0:3176800d0f26 155 DC1=DC1-0.1;
PabloViana 0:3176800d0f26 156 if(DC1<0.0) {
PabloViana 0:3176800d0f26 157 DC1=0;
PabloViana 0:3176800d0f26 158 }
PabloViana 0:3176800d0f26 159 pc.printf("\n\nDuty Cicle:%f\n\r", DC1);
PabloViana 0:3176800d0f26 160 }
PabloViana 0:3176800d0f26 161 if (data1==b_rigth) {
PabloViana 0:3176800d0f26 162 DC1=DC1+0.1;
PabloViana 0:3176800d0f26 163 if(DC1>1.0) {
PabloViana 0:3176800d0f26 164 DC1=1.0;
PabloViana 0:3176800d0f26 165 }
PabloViana 0:3176800d0f26 166 pc.printf("\n\nDuty Cicle:%f\n\r", DC1);
PabloViana 0:3176800d0f26 167 }
PabloViana 0:3176800d0f26 168 if (data1==b_ok) {
PabloViana 0:3176800d0f26 169 pc.printf("Ok\n\r");
PabloViana 0:3176800d0f26 170 }
PabloViana 0:3176800d0f26 171
PabloViana 0:3176800d0f26 172 Led.period(PeriodoLed);
PabloViana 0:3176800d0f26 173 Led.write(DC1);
PabloViana 0:3176800d0f26 174 Pwm1.period(PeriodoPWM1);
PabloViana 0:3176800d0f26 175 Pwm1.write(DC1);
PabloViana 0:3176800d0f26 176 }//while
PabloViana 0:3176800d0f26 177 }//main