library for controlling tv remote with gestures

Dependencies:   HCSR04 SI1143 command mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #define DIST_MAX 40 // Maximum distance in cm, anything above is ignored.
00002 // Threshold for up/down commands.
00003 // If higher, command is "up". If lower, "down".
00004 #define DIST_THRES 20
00005 
00006 #include "mbed.h"
00007 #include "rtos.h"
00008 #include "hcsr04.h"
00009 #include "SI1143.h"
00010 #include "command.h"
00011 
00012 Serial pc(USBTX, USBRX); // tx, rx
00013 HCSR04 usensor(p7, p6);
00014 SI1143 sensor(p28, p27);
00015 
00016 DigitalOut l1(LED1);
00017 DigitalOut l2(LED2);
00018 DigitalOut l3(LED3);
00019 DigitalOut l4(LED4);
00020 
00021 int value;
00022 
00023 unsigned int dist;
00024 int sense1, sense2, sense3;
00025 
00026 const float period = 1.0;
00027 const float power_execute_count = 3.0 / period;
00028 float power_count = 0;
00029 Mutex led_mut;
00030 Mutex ir_mut;
00031 
00032 bool flag = false;
00033 
00034 const int num_commands = 5;
00035 enum COMMANDS {
00036   POWER_COM,
00037   CHANNEL_UP,
00038   CHANNEL_DOWN,
00039   VOLUME_UP,
00040   VOLUME_DOWN,
00041   NONE,
00042 };
00043 const string com_names[num_commands] = {"power", "channel up", "channel down",
00044                                         "volume up", "volume down"};
00045 
00046 Command coms[num_commands];
00047 
00048 Ticker power_ticker;
00049 enum MODE {
00050   NO_MODE = 0,
00051   CHANNEL = 1,
00052   POWER = 2,
00053   VOLUME = 3,
00054 
00055 };
00056 
00057 enum DIRECTION {
00058     NO_DIR,
00059     UP,
00060     DOWN,
00061 };
00062 DIRECTION dir = NO_DIR;
00063 MODE mode = NO_MODE;
00064 
00065 void set_led(uint8_t led_vals) {
00066   led_mut.lock();
00067   l1 = led_vals & 1;
00068   led_vals = led_vals >> 1;
00069   l2 = led_vals & 1;
00070   led_vals = led_vals >> 1;
00071   l3 = led_vals & 1;
00072   led_vals = led_vals >> 1;
00073   l4 = led_vals & 1;
00074   led_mut.unlock();
00075 }
00076 
00077 void ExecutePowerCommand() {
00078   ir_mut.lock();
00079   coms[POWER_COM].TransmitCommand();
00080   ir_mut.unlock();
00081   mode = NO_MODE;
00082 }
00083 
00084 void CheckForPower() {
00085   if (mode == POWER) {
00086     if (power_count == power_execute_count) {
00087       ExecutePowerCommand();
00088     }
00089     ++power_count;
00090   } else {
00091     power_count = 0;
00092     set_led(0);
00093   }
00094 }
00095 
00096 int handleDist(int dist) {
00097   if (dist > DIST_THRES) {
00098     return 1;
00099   } else {
00100     return -1;
00101   }
00102 }
00103 
00104 void parallax_thread(void const *args) {
00105   int sen = 50;
00106   while (true) {
00107     sense1 = sensor.get_ps1(1);
00108     sense2 = sensor.get_ps2(1);
00109     sense3 = sensor.get_ps3(1);
00110 
00111 
00112     if (sense1 > sen || sense2 > sen || sense3 > sen) {
00113       if (sense1 > sense2 && sense1 > sense3) {
00114         set_led(1);
00115         mode = CHANNEL;
00116       }
00117 
00118       else if (sense2 > sense1 && sense2 > sense3) {
00119         mode = POWER;
00120         set_led(3);
00121       }
00122 
00123       else if (sense3 > sense1 && sense3 > sense2) {
00124         set_led(2);
00125         mode = VOLUME;
00126       }
00127     } else {
00128         if( mode == POWER) {
00129             mode = NO_MODE;
00130         }
00131     }
00132     Thread::wait(300);
00133   }
00134 }
00135 
00136 void ultrasound_thread(void const *args) {
00137   while (true) {
00138     usensor.start();
00139     dist = usensor.get_dist_cm();
00140     if (dist < DIST_MAX) {
00141       int d = 500; // first delay is longer for single volume change
00142 
00143       while (dist < DIST_MAX) {
00144         value = handleDist(dist); // is up or down?
00145         // doIR(CONTROL_VOL, value); // fire off IR signal
00146         if (value == 1) {
00147           set_led(8);
00148           dir = UP;
00149           Thread::wait(100);
00150           set_led(0);
00151         } else {
00152           set_led(4);
00153           dir = DOWN;
00154           Thread::wait(100);
00155           set_led(0);
00156         }
00157         usensor.start();
00158         Thread::wait(d);              // wait
00159         dist = usensor.get_dist_cm(); // check for hand again
00160         d = 100; // delays are shorter for quick multiple volume adjustment
00161       }
00162       // this stops accidental channel change after volume adjustment
00163       Thread::wait(500);
00164     } else {
00165         dir = NO_DIR;
00166     }
00167     Thread::wait(50); // Short enough to detect all swipes.
00168   }
00169 }
00170 
00171 void transmit_thread(const void* args) {
00172     while(true) {
00173         COMMANDS com = NONE;
00174         if(mode == VOLUME && dir == UP) {
00175             com = VOLUME_UP;
00176         } else if(mode == VOLUME && dir == DOWN) {
00177             com = VOLUME_DOWN;
00178         } else if(mode == CHANNEL && dir == UP) {
00179             com = CHANNEL_UP;
00180         } else if(mode == CHANNEL && dir == DOWN) {
00181             com = CHANNEL_DOWN;
00182         } else {
00183             com = NONE;
00184         }
00185         if(com != NONE) {
00186             ir_mut.lock();
00187             coms[com].TransmitCommand();
00188             ir_mut.unlock();
00189         }
00190         Thread::wait(10);
00191     }
00192 }
00193 
00194 void setup(void) {
00195   // Serial.begin(9600);
00196   // device.baud(2400);
00197   pc.printf("Ready to decode IR!\r\n");
00198 
00199   for( int i = 0; i < num_commands; ++i) {
00200     coms[i] = Command(com_names[i]);
00201     coms[i].LearnCommand(pc);
00202   }
00203   // Setup the baseline
00204   sensor.bias(1, 5);
00205   wait(1);
00206 }
00207 
00208 int main() {
00209 
00210   setup();
00211   power_ticker.attach(&CheckForPower, period);
00212   set_led(0);
00213 
00214   Thread mode_checker(parallax_thread);
00215   Thread range_checker(ultrasound_thread);
00216   Thread transmit_checker(transmit_thread);
00217 
00218   while (1) {
00219     // spin.
00220   }
00221 }