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.
Dependencies: HCSR04 SI1143 command mbed-rtos mbed
main.cpp
- Committer:
- cardenb
- Date:
- 2015-12-08
- Revision:
- 0:35878487eafe
File content as of revision 0:35878487eafe:
#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.
}
}