Vinod Modhe / Mbed 2 deprecated IR_Remote

Dependencies:   mbed

Revision:
0:dc689f01feb2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Mar 09 00:51:21 2013 +0000
@@ -0,0 +1,398 @@
+/*Vinod Modhe*/
+/* 4180 Lab3 */
+
+#include "mbed.h"
+#include "IR_Def.h"
+#include "NokiaLCD.h"
+
+Ticker  system_clock;                                               //This will be used to increment a counter every msec inside it's ISR
+Timer T;                                                            //Timer used for measuring time interval between successive edges of IR input signal
+InterruptIn IR(p30);                                                //Pin to which IR receiver is connected
+void IR_ISR();                                                      //ISR for decoding the IR signal
+void dummy_ISR();                                                   //Required so that 'IR_ISR' is not called on both rising and falling edges of IR signal at the same time
+void sys_tick();                                                    //ISR for 1 msec. system clock
+void RGB_LED(int red, int green, int blue);                         //For writing to ShiftBrite
+LocalFileSystem local("local");                                     // Create the local filesystem under the name "local"
+
+//On board LEDs
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+//Pin for entering config mode
+DigitalIn config_pin(p21);
+
+//Power Switch Tail
+DigitalOut switch_tail(p20);
+
+//ShiftBrite
+DigitalOut latch(p15);
+DigitalOut enable(p16);
+SPI spi(p11, p12, p13);
+
+//Nokia LCD
+NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6100); // mosi, sclk, cs, rst, type
+
+//Global IR variables
+uint8_t state = 0;                       //State variable for IR state machine
+uint8_t Rx_count = 0;                                //Counter to count no. of bits received
+uint32_t Rx_buf = 0;                 //To store recevied IR data
+char Rx_flag = 0;                    //Flag which indicates that a valid IR command was received
+uint32_t Rx_rep_count = 0;           //To keep track of how many repeat pulses are received
+uint32_t Rx_rep_timeout_count = 0;   //Timer which clears the previously received IR command, once it reaches the set limit
+uint32_t T_buf = 0;                  //Buffer to hold value of timer T
+char Rx_ignore_rep_flag = 0;         //0 => Do not ignore repeat pulses
+
+typedef struct IR_Key_Codes {
+    uint32_t red_p,red_m;                   //Key codes for Red+ and Red-
+    uint32_t green_p,green_m;               //Key codes for Green+ and Green-
+    uint32_t blue_p,blue_m;                 //Key codes for Blue+ and Blue-
+    uint32_t switch_tail;                   //Key code for power switch tail
+} IR_t;
+
+int main()
+{
+    switch_tail = 0;                                //Turn OFF the power switch tail
+
+    led1 = led2 = led3 = led4 = 1;                  //Turn ON all LEDs to indicate initialization
+
+    //Nokia LCD Init
+    lcd.background(0x000000);                       //Set background to white
+    lcd.cls();                                      //Clear Screen
+    lcd.locate(0,1);                                //Go to line 1
+    lcd.printf(" R   G   B  FAN");                  //Display this text
+    lcd.locate(0,2);                                //Go to line 2
+    lcd.printf(" 0   0   0  OFF");                  //Display this text
+    lcd.locate(0,15);                               //Go to line 15
+    lcd.printf("100 100 100");                      //Display this text
+
+    config_pin.mode(PullUp);                            //Enable internal pullup
+
+    wait(0.5);
+
+    if(config_pin == 0) {                               //If config pin is pulled low, enter config mode, in which key codes are to be saved in the "IRCodes.txt" file
+        led1 = led4 = 0;
+        led2 = led3 = 1;
+        wait(0.5);
+        Rx_ignore_rep_flag = 1;                   //Ignore repeat pulses while in config mode
+
+        IR_t temp;                                      //Temporary variable to hold the received key codes
+
+        //IR Init
+        IR.mode(PullNone);                              //Disable internal pullup
+        system_clock.attach_us(&sys_tick, 1000);        //This will call the function 'sys_tick' every 1 msec.
+        IR.fall(&IR_ISR);                               //Set IR interrupt to occur on falling edge
+        IR.rise(&dummy_ISR);
+
+        //Store the received IR codes into temp, while ignoring repeat pulses
+        led1 = led2 = led3 = 0;
+        led4 = 1;
+        while(Rx_flag == 0);                                             //Wait for a valid command
+        temp.red_p = Rx_buf;                                              //Copy it into the temp variable
+        Rx_flag = 0;                                                     //Reset the flag
+
+        led1 = led2 = led4 = 0;
+        led3 = 1;
+        while(Rx_flag == 0);
+        temp.red_m = Rx_buf;
+        Rx_flag = 0;
+
+        led1 = led2 = 0;
+        led3 = led4 = 1;
+        while(Rx_flag == 0);
+        temp.green_p = Rx_buf;
+        Rx_flag = 0;
+
+        led1 = led3 = led4 = 0;
+        led2 = 1;
+        while(Rx_flag == 0);
+        temp.green_m = Rx_buf;
+        Rx_flag = 0;
+
+        led1 = led3 = 0;
+        led2 = led4 = 1;
+        while(Rx_flag == 0);
+        temp.blue_p = Rx_buf;
+        Rx_flag = 0;
+
+        led1 = led4 = 0;
+        led2 = led3 = 1;
+        while(Rx_flag == 0);
+        temp.blue_m = Rx_buf;
+        Rx_flag = 0;
+
+        led1 = 0;
+        led2 = led3 = led4 = 1;
+        while(Rx_flag == 0);
+        temp.switch_tail = Rx_buf;
+        Rx_flag = 0;
+
+        FILE *fp = fopen("/local/IRCodes.txt", "w");  // Open "IRCodes.txt" on the local file system for writing
+
+        if(fp != NULL) {                                                            //File was opened successfully
+            //Write the key codes into the file one by one in the correct order
+            fprintf(fp, "%x ", temp.red_p);
+            fprintf(fp, "%x ", temp.red_m);
+            fprintf(fp, "%x ", temp.green_p);
+            fprintf(fp, "%x ", temp.green_m);
+            fprintf(fp, "%x ", temp.blue_p);
+            fprintf(fp, "%x ", temp.blue_m);
+            fprintf(fp, "%x ", temp.switch_tail);
+
+            fclose(fp);
+
+            led1 = led2 = led3 = led4 = 1;
+        } else {                                                                                //File could not be opened
+            led1 = 1;
+            led2 = 0;
+            led3 = 1;
+            led4 = 0;
+
+            while(1) {                                                                      //Stop executing further code and display error lights
+                led1 = !led1;
+                led2 = !led2;
+                led3 = !led3;
+                led4 = !led4;
+
+                wait(0.5);
+            }
+        }
+        Rx_ignore_rep_flag = 0;                         //Disable this flag to not ignore repeat pulses while in normal mode
+    }
+
+    IR_t key_code;                                                                  //Struct variable holding all key codes
+
+    //File System Init
+    FILE *fp = fopen("/local/IRCodes.txt", "r");    // Open "IRCodes.txt" on the local file system for reading
+
+    if(fp != NULL) {                                                                //File was opened successfully
+        fscanf(fp, "%8x", &(key_code.red_p));                   //Read the key codes from the file into the respective struct members
+        fscanf(fp, "%8x", &(key_code.red_m));
+        fscanf(fp, "%8x", &(key_code.green_p));
+        fscanf(fp, "%8x", &(key_code.green_m));
+        fscanf(fp, "%8x", &(key_code.blue_p));
+        fscanf(fp, "%8x", &(key_code.blue_m));
+        fscanf(fp, "%8x", &(key_code.switch_tail));
+        fclose(fp);
+    } else {                                                                                //File could not be opened
+        led1 = 1;
+        led2 = 0;
+        led3 = 1;
+        led4 = 0;
+
+        while(1) {                                                                      //Stop executing further code and display error lights
+            led1 = !led1;
+            led2 = !led2;
+            led3 = !led3;
+            led4 = !led4;
+
+            wait(0.5);
+        }
+    }
+
+    //Shiftbrite Init
+    int red=0;
+    int green=0;
+    int blue=0;
+    spi.format(16,0);
+    spi.frequency(500000);
+    enable=0;
+    latch=0;
+    wait(2);
+
+    RGB_LED( red, green, blue);
+    wait(.1);
+
+    //IR Init
+    IR.mode(PullNone);                        //Disable internal pullup
+    system_clock.attach_us(&sys_tick, 1000);  //This will call the function 'sys_tick' every 1 msec.
+    IR.fall(&IR_ISR);                         //Set IR interrupt to occur on falling edge
+    IR.rise(&dummy_ISR);
+
+    led1 = led2 = led3 = led4 = 0;            //Turn OFF all LEDs to indicate initialization is done
+
+    while(1) {
+        if(Rx_flag == 1) {
+            Rx_flag = 0;
+
+            if(Rx_buf == key_code.red_p) {
+                if((red += 10) > 100) {
+                    red = 100;
+                }
+
+                //Display the scaled rectangle
+                lcd.fill(5,  28, 20, 90, 0x000000);                 //Erase original rectangle
+                lcd.fill(5,  28, 20, (red/10 * 9), 0x0000FF);       //Draw red rectangle
+            } else if(Rx_buf == key_code.red_m) {
+                if((red -= 10) < 0) {
+                    red = 0;
+                }
+
+                //Display the scaled rectangle
+                lcd.fill(5,  28, 20, 90, 0x000000);                 //Erase original rectangle
+                lcd.fill(5,  28, 20, (red/10 *9), 0x0000FF);        //Draw red rectangle
+            } else if(Rx_buf == key_code.green_p) {
+                if((green += 10) > 100) {
+                    green = 100;
+                }
+
+                //Display the scaled rectangle
+                lcd.fill(36,  28, 20, 90, 0x000000);                 //Erase original rectangle
+                lcd.fill(36,  28, 20, (green/10 * 9), 0x00FF00);     //Draw green rectangle
+            } else if(Rx_buf == key_code.green_m) {
+                if((green -= 10) < 0) {
+                    green = 0;
+                }
+
+                //Display the scaled rectangle
+                lcd.fill(36,  28, 20, 90, 0x000000);                 //Erase original rectangle
+                lcd.fill(36,  28, 20, (green/10 * 9), 0x00FF00);     //Draw green rectangle
+            } else if(Rx_buf == key_code.blue_p) {
+                if((blue += 10) > 100) {
+                    blue = 100;
+                }
+
+                //Display the scaled rectangle
+                lcd.fill(67,  28, 20, 90, 0x000000);                 //Erase original rectangle
+                lcd.fill(67,  28, 20, (blue/10 * 9), 0xFF0000);      //Draw blue rectangle
+            } else if(Rx_buf == key_code.blue_m) {
+                if((blue -= 10) < 0) {
+                    blue = 0;
+                }
+
+                //Display the scaled rectangle
+                lcd.fill(67,  28, 20, 90, 0x000000);                 //Erase original rectangle
+                lcd.fill(67,  28, 20, (blue/10* 9), 0xFF0000);          //Draw blue rectangle
+            } else if((Rx_buf == key_code.switch_tail) && (Rx_rep_count == 0)) { //Do not consider repeat pulses for switch tail to avoid rapid switching
+                switch_tail = !switch_tail;
+
+                if(switch_tail == 0) {                              //Fan OFF
+                    lcd.locate(0,2);                                //Go to line 2
+                    lcd.printf(" 0   0   0  OFF");                  //Display this text
+                } else if(switch_tail == 1) {                       //Fan ON
+                    lcd.locate(0,2);                                //Go to line 2
+                    lcd.printf(" 0   0   0  ON ");                  //Display this text
+                }
+
+            }
+
+            RGB_LED( red, green, blue);                       //Write to ShiftBrite after receiving a valid command
+            wait(.1);
+        }
+
+        wait_us(100);                                                     //Wait for 0.1ms
+    }
+}
+
+void RGB_LED(int red, int green, int blue)
+{
+    unsigned int low_color=0;
+    unsigned int high_color=0;
+    high_color=(blue<<4)|((red&0x3C0)>>6);
+    low_color=(((red&0x3F)<<10)|(green));
+    spi.write(high_color);
+    spi.write(low_color);
+    latch=1;
+    latch=0;
+}
+
+void sys_tick()
+{
+    if(Rx_rep_timeout_count < 0xFFFF) { //Do not increment counter beyond 0xFFFF to prevent roll-over
+        ++Rx_rep_timeout_count;       //Increment this counter every 1msec.
+    }
+}
+
+void IR_ISR()
+{
+    if(state == 0) {
+        T.stop();               //Stop timer
+        T.reset();              //Reset timer
+        T.start();              //Start timer
+        IR.rise(&IR_ISR);       //Set IR interrupt to occur on rising edge
+        IR.fall(&dummy_ISR);
+        state = 1;              //Go to next state
+        Rx_count = 0;           //Clear the received bits counter
+    } else if(state == 1) {
+        T.stop();                          //Stop timer
+        T_buf = (uint32_t)T.read_us();     //Read timer
+        T.reset();                         //Reset timer
+        T.start();                         //Start timer
+        IR.fall(&IR_ISR);                  //Set IR interrupt to occur on falling edge
+        IR.rise(&dummy_ISR);
+
+        if(T_buf <= IR_9000us_UL && T_buf >= IR_9000us_LL) { //Check for preamble start pulse(9ms)
+            state = 2;  //Go to next state
+        } else {
+            state = 0; //Reset the state machine
+        }
+    } else if(state == 2) {
+        T.stop();                          //Stop timer
+        T_buf = (uint32_t)T.read_us();     //Read the value in timer
+        T.reset();                         //Reset timer
+        T.start();                         //Start timer
+        IR.fall(&IR_ISR);                  //Set IR interrupt to occur on falling edge
+        IR.rise(&dummy_ISR);
+
+        if(T_buf <= IR_4500us_UL && T_buf >= IR_4500us_LL) { //Check for preamble space(4.5ms)
+            state = 3;                  //Go to next state
+            Rx_rep_timeout_count = 0;   //Reset counter
+            Rx_rep_count = 0;           //Reset the repeat pulse counter
+        } else if(T_buf <= IR_2250us_UL && T_buf >= IR_2250us_LL) { //Check for repeat pulse(2.25ms)
+            state = 0;                      //Reset the state machine
+
+            if(Rx_rep_count < 0xFFFF) {
+                if(Rx_rep_timeout_count < IR_rep_timeout_ms) {  //Only increment the repeat pulse counter if the delay between two successive repeat pulses is less than 135msec.
+                    Rx_rep_timeout_count = 0;                   //Reset the counter everytime a valid repeat pulse is received
+                    ++Rx_rep_count;
+                } else {                                         //Invald repeat pulse received
+                    Rx_rep_count = 0;                            //Reset counter
+                    Rx_flag = 0;                                 //Clear the flag to indicate that an IR command was not received
+                    Rx_buf = 0;                                  //Clear the previously received command
+                }
+            }
+            goto ahead;                    //Repeat the previous command
+        } else { //Wrong pulse
+            Rx_rep_count = 0;     //Reset counter
+            state = 0;                       //Reset the state machine
+        }
+    } else if(state == 3) {
+        T.stop();                      //Stop timer
+        T_buf = T.read_us();          //Read the value in timer
+        T.reset();                     //Reset timer
+        T.start();                     //Start timer
+        IR.fall(&IR_ISR);              //Set IR interrupt to occur on falling edge
+        IR.rise(&dummy_ISR);
+
+        if(T_buf <= IR_1_UL_us && T_buf >= IR_1_LL_us) { //Check if bit is '1'(2.25ms)
+            ++Rx_count;              //Increment the bit counter
+            Rx_buf >>= 1;
+            Rx_buf |= 0x80000000;     //Shift in a '1' from the left side
+            state = 3;               //Remain in current state
+        } else if(T_buf <= IR_0_UL_us && T_buf >= IR_0_LL_us) { //Check if bit is '0'(1.12ms)
+            ++Rx_count;         //Increment the bit counter
+            Rx_buf >>= 1;        //Shift in a '0' from the left side
+            state = 3;          //Remain in current state
+        } else { //Invalid data received
+            Rx_count = 0;//Reset the bit counter
+            state = 0;   //Reset state m/c
+        }
+
+        if(Rx_count == 32) { //Check if all 32 bits have been received
+            state = 0;       //Reset state m/c
+
+ahead:
+
+            if(!((Rx_rep_count > 0) && (Rx_ignore_rep_flag == 1))) {
+                Rx_flag = 1;                             //Set this flag for repeat pulses only if repeat pulses are to be considered
+            }
+            Rx_rep_timeout_count = 0;         //Reset the counter everytime a valid command is received
+        }
+    }
+}
+
+void dummy_ISR()
+{
+    //Do nothing
+}