library for controlling tv remote with gestures
Dependencies: HCSR04 SI1143 command mbed-rtos mbed
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 }
Generated on Thu Jul 21 2022 05:52:10 by 1.7.2