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.
main.cpp
- Committer:
- vin_jm
- Date:
- 2013-03-09
- Revision:
- 0:dc689f01feb2
File content as of revision 0:dc689f01feb2:
/*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
}