![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
library for controlling tv remote with gestures
Dependencies: HCSR04 SI1143 command mbed-rtos mbed
Diff: main.cpp
- Revision:
- 0:35878487eafe
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Dec 08 03:10:08 2015 +0000 @@ -0,0 +1,221 @@ +#define DIST_MAX 40 // Maximum distance in cm, anything above is ignored. +// Threshold for up/down commands. +// If higher, command is "up". If lower, "down". +#define DIST_THRES 20 + +#include "mbed.h" +#include "rtos.h" +#include "hcsr04.h" +#include "SI1143.h" +#include "command.h" + +Serial pc(USBTX, USBRX); // tx, rx +HCSR04 usensor(p7, p6); +SI1143 sensor(p28, p27); + +DigitalOut l1(LED1); +DigitalOut l2(LED2); +DigitalOut l3(LED3); +DigitalOut l4(LED4); + +int value; + +unsigned int dist; +int sense1, sense2, sense3; + +const float period = 1.0; +const float power_execute_count = 3.0 / period; +float power_count = 0; +Mutex led_mut; +Mutex ir_mut; + +bool flag = false; + +const int num_commands = 5; +enum COMMANDS { + POWER_COM, + CHANNEL_UP, + CHANNEL_DOWN, + VOLUME_UP, + VOLUME_DOWN, + NONE, +}; +const string com_names[num_commands] = {"power", "channel up", "channel down", + "volume up", "volume down"}; + +Command coms[num_commands]; + +Ticker power_ticker; +enum MODE { + NO_MODE = 0, + CHANNEL = 1, + POWER = 2, + VOLUME = 3, + +}; + +enum DIRECTION { + NO_DIR, + UP, + DOWN, +}; +DIRECTION dir = NO_DIR; +MODE mode = NO_MODE; + +void set_led(uint8_t led_vals) { + led_mut.lock(); + l1 = led_vals & 1; + led_vals = led_vals >> 1; + l2 = led_vals & 1; + led_vals = led_vals >> 1; + l3 = led_vals & 1; + led_vals = led_vals >> 1; + l4 = led_vals & 1; + led_mut.unlock(); +} + +void ExecutePowerCommand() { + ir_mut.lock(); + coms[POWER_COM].TransmitCommand(); + ir_mut.unlock(); + mode = NO_MODE; +} + +void CheckForPower() { + if (mode == POWER) { + if (power_count == power_execute_count) { + ExecutePowerCommand(); + } + ++power_count; + } else { + power_count = 0; + set_led(0); + } +} + +int handleDist(int dist) { + if (dist > DIST_THRES) { + return 1; + } else { + return -1; + } +} + +void parallax_thread(void const *args) { + int sen = 50; + while (true) { + sense1 = sensor.get_ps1(1); + sense2 = sensor.get_ps2(1); + sense3 = sensor.get_ps3(1); + + + if (sense1 > sen || sense2 > sen || sense3 > sen) { + if (sense1 > sense2 && sense1 > sense3) { + set_led(1); + mode = CHANNEL; + } + + else if (sense2 > sense1 && sense2 > sense3) { + mode = POWER; + set_led(3); + } + + else if (sense3 > sense1 && sense3 > sense2) { + set_led(2); + mode = VOLUME; + } + } else { + if( mode == POWER) { + mode = NO_MODE; + } + } + Thread::wait(300); + } +} + +void ultrasound_thread(void const *args) { + while (true) { + usensor.start(); + dist = usensor.get_dist_cm(); + if (dist < DIST_MAX) { + int d = 500; // first delay is longer for single volume change + + while (dist < DIST_MAX) { + value = handleDist(dist); // is up or down? + // doIR(CONTROL_VOL, value); // fire off IR signal + if (value == 1) { + set_led(8); + dir = UP; + Thread::wait(100); + set_led(0); + } else { + set_led(4); + dir = DOWN; + Thread::wait(100); + set_led(0); + } + usensor.start(); + Thread::wait(d); // wait + dist = usensor.get_dist_cm(); // check for hand again + d = 100; // delays are shorter for quick multiple volume adjustment + } + // this stops accidental channel change after volume adjustment + Thread::wait(500); + } else { + dir = NO_DIR; + } + Thread::wait(50); // Short enough to detect all swipes. + } +} + +void transmit_thread(const void* args) { + while(true) { + COMMANDS com = NONE; + if(mode == VOLUME && dir == UP) { + com = VOLUME_UP; + } else if(mode == VOLUME && dir == DOWN) { + com = VOLUME_DOWN; + } else if(mode == CHANNEL && dir == UP) { + com = CHANNEL_UP; + } else if(mode == CHANNEL && dir == DOWN) { + com = CHANNEL_DOWN; + } else { + com = NONE; + } + if(com != NONE) { + ir_mut.lock(); + coms[com].TransmitCommand(); + ir_mut.unlock(); + } + Thread::wait(10); + } +} + +void setup(void) { + // Serial.begin(9600); + // device.baud(2400); + pc.printf("Ready to decode IR!\r\n"); + + for( int i = 0; i < num_commands; ++i) { + coms[i] = Command(com_names[i]); + coms[i].LearnCommand(pc); + } + // Setup the baseline + sensor.bias(1, 5); + wait(1); +} + +int main() { + + setup(); + power_ticker.attach(&CheckForPower, period); + set_led(0); + + Thread mode_checker(parallax_thread); + Thread range_checker(ultrasound_thread); + Thread transmit_checker(transmit_thread); + + while (1) { + // spin. + } +}