Instantly share code, notes, and snippets.

@msloth msloth/lighting-switch.c
Last active Dec 6, 2018

Embed
What would you like to do?
#include "thsq.h"
#include "ti-lib.h"
/*---------------------------------------------------------------------------*/
/*
* Thingsquare lighting switch with slider.
*
* This client uses a linear potentiometer to set the dim level of the lights
* in the network. To save power, we only power the potentiometer when we will
* sample it, and we only send light control if it has moved enough.
*
* Usage:
* connect the potentiometer like this:
* potmeter Launchpad
* GND GND
* Vref DIO28
* output DIO29
* compile this client and flash the Launchpad device with the potentiometer
* invite it to the gateway in the network with the lights/lamps
* move the slider to control the lights
*/
/*---------------------------------------------------------------------------*/
PROCESS(slider_process, "Slider Process");
void thsq_lighting_trigger_switch(int r, int g, int b);
void thsq_default_services_set_stats_interval(int seconds);
void thsq_default_services_set_period_interval(int seconds);
/*---------------------------------------------------------------------------*/
static int
get_slider(void)
{
int ret;
thsq_gpio_set_gpio(1);
ret = thsq_gpio_get_adc();
thsq_gpio_set_gpio(0);
return ret;
}
/*---------------------------------------------------------------------------*/
static uint8_t
map_adc_to_percent(int adc)
{
int i;
/* ADC range [0,3000] ca, these are the steps we break at */
static const uint16_t p_settings[] = {
272, 544, 816, 1088, 1360, 1632, 1904, 2176, 2448,
2850, // for linear scale 2720, but bumped up to make 100% "end of the slide"
};
#define NUM_ELEMENTS 10 /* above array has 10 elements */
for(i = 0; i < NUM_ELEMENTS; i++) {
if(adc <= p_settings[i]) {
return i * 10;
}
}
return 100;
}
/*---------------------------------------------------------------------------*/
#define SLIDER_SAMPLE_PERIOD (CLOCK_SECOND)
#define SLIDER_CHANGE_THRESHOLD 20 /* filter out noise */
PROCESS_THREAD(slider_process, ev, data)
{
PROCESS_BEGIN();
static int last_value;
static int last_p_setting = -1;
static struct etimer et;
unsigned int diff;
int value;
/* take a first reading to avoid a trigger when starting */
last_value = get_slider();
/* periodically sample the slider */
while(1) {
value = get_slider();
if(value > last_value) {
diff = value - last_value;
} else {
diff = last_value - value;
}
if(diff >= SLIDER_CHANGE_THRESHOLD) {
/* only act on large enough changes */
unsigned int p = map_adc_to_percent(value);
if(p != last_p_setting) {
last_p_setting = p;
thsq_lighting_trigger_switch(p, p, p);
/* notify backend on change */
thsq_sset_printf("slider", "%d", value);
thsq_push();
}
}
last_value = value;
etimer_set(&et, SLIDER_SAMPLE_PERIOD);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
/* default power mode and settings */
thsq_set_default_mode("deadleaf");
thsq_default_services_set_stats_interval(2*60*60); /* 2 h */
thsq_default_services_set_period_interval(2*60*60); /* 2 h */
thsq_dset("deadleaf", 30*60); /* 30 min poll interval */
/* Initialize the lighting module */
thsq_lighting_init();
/* Initialize GPIO module */
thsq_gpio_init();
thsq_gpio_set_default("2829----N"); /* power pin out 28, adc in 29 */
thsq_gpio_push_adc_periodically(0); /* don't send the ADC value to server */
process_start(&slider_process, NULL);
}
/*---------------------------------------------------------------------------*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment