Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- 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
+}