Added new mode: Scheduler -- clock based switching of lights

This commit is contained in:
2017-12-09 22:10:59 +01:00
parent 626fe42a90
commit 4aeebe1b33
12 changed files with 290 additions and 50 deletions

View File

@@ -9,7 +9,6 @@
static LEDStateEngine theLEDStateEngine;
static int ticks = 0;
static int brightness = 50;
int getTicks(void) { return ticks; }
@@ -27,7 +26,6 @@ void LEDStateEngine_setNumberOfLeds(int numberOfLeds) {
void LEDStateEngine_init(int ledPin, int numberOfLeds) {
theLEDStateEngine.comment = "";
theLEDStateEngine.pin = ledPin;
brightness = mgos_sys_config_get_led_brightness();
LEDStateEngine_setNumberOfLeds(numberOfLeds);
for (int i=0; i<numberOfLeds; ++i) {
LEDState_init(i, LEDDefinition_get(i));
@@ -61,24 +59,11 @@ void LEDStateEngine_tick() {
double LEDStateEngine_getMinTickTime() { return 1000 * minTickTime; }
double LEDStateEngine_getMaxTickTime() { return 1000 * maxTickTime; }
static uint8_t adjustBrightness(uint8_t value) {
return (value * brightness)/100;
}
int LEDStateEngine_getBrightness() { return brightness; }
void LEDStateEngine_setBrightness(int newBrightness) {
if (newBrightness > 0 && newBrightness <= 100) {
brightness = newBrightness;
} else {
LOG(LL_ERROR, ("invalid brightness value %d", newBrightness));
}
}
static void updateLedDisplay(LEDState *state) {
NeoPixel_set(state->index,
adjustBrightness(state->currentColor.red),
adjustBrightness(state->currentColor.green),
adjustBrightness(state->currentColor.blue));
state->currentColor.red,
state->currentColor.green,
state->currentColor.blue);
}
void LEDState_tick(int ledNum) {

View File

@@ -3,12 +3,28 @@
#include "mgos_bitbang.h"
#include "mgos_gpio.h"
#include "mgos_system.h"
#include "mgos_sys_config.h"
#include "NeoPixel.h"
static int NeoPixel_pin = 0;
static int NeoPixel_numPixels = 0;
static uint8_t *NeoPixel_leds = NULL; // pointer to allocated memory
static enum NeoPixel_ColorOrder NeoPixel_colorOrder = NeoPixel_colorOrder_RGB;
static enum NeoPixel_ColorOrder NeoPixel_colorOrder = NeoPixel_colorOrder_GRB;
static int brightness = 50;
static uint8_t adjustBrightness(uint8_t value) {
return (value * brightness)/100;
}
int NeoPixel_getBrightness() { return brightness; }
void NeoPixel_setBrightness(int newBrightness) {
if (newBrightness > 0 && newBrightness <= 100) {
brightness = newBrightness;
} else {
LOG(LL_ERROR, ("invalid brightness value %d", newBrightness));
}
}
// ## **`NeoPixel_clear()`**
// Clear in-memory values of the pixels.
@@ -44,7 +60,8 @@ void NeoPixel_create(uint8_t pin, uint8_t numPixels, enum NeoPixel_ColorOrder or
mgos_gpio_set_mode(pin, MGOS_GPIO_MODE_OUTPUT);
// GPIO.write(pin, 0); // Keep in reset.
mgos_gpio_write(pin, false);
LOG(LL_INFO, ("pin=%d, numPixels=%d, colorOrder=%d", pin, numPixels, order));
brightness = mgos_sys_config_get_led_brightness();
LOG(LL_INFO, ("pin=%d, numPixels=%d, colorOrder=%d, brightness=%d", pin, numPixels, order, brightness));
NeoPixel_clear();
}
@@ -78,9 +95,9 @@ void NeoPixel_set(int pixel, int red, int green, int blue) {
} else if (NeoPixel_colorOrder == NeoPixel_colorOrder_BGR) {
v0 = blue; v1 = green; v2 = red;
} else return;
NeoPixel_leds[3*pixel] = v0;
NeoPixel_leds[3*pixel+1] = v1;
NeoPixel_leds[3*pixel+2] = v2;
NeoPixel_leds[3*pixel] = adjustBrightness(v0);
NeoPixel_leds[3*pixel+1] = adjustBrightness(v1);
NeoPixel_leds[3*pixel+2] = adjustBrightness(v2);
}
// ## **`NeoPixel_show()`**

View File

@@ -11,5 +11,7 @@ extern void NeoPixel_release();
extern void NeoPixel_create(uint8_t pin, uint8_t numPixels, enum NeoPixel_ColorOrder order);
extern void NeoPixel_set(int pixel, int red, int green, int blue);
extern void NeoPixel_show();
extern int NeoPixel_getBrightness();
extern void NeoPixel_setBrightness(int newBrightness);
#endif

105
src/Scheduler.c Normal file
View File

@@ -0,0 +1,105 @@
#include "Scheduler.h"
#include "LEDDefinition.h"
#include "NeoPixel.h"
#include "mgos_timers.h"
enum ScheduleItemMode {
ScheduleItemMode_OnOff,
ScheduleItemMode_NeonOn,
ScheduleItemMode_tv_bw,
ScheduleItemMode_tv_color
};
static enum ScheduleItemMode modeFromName(char *name) {
if (strcmp(name, "OnOff") == 0) return ScheduleItemMode_OnOff;
if (strcmp(name, "NeonOn") == 0) return ScheduleItemMode_NeonOn;
if (strcmp(name, "TV_BW") == 0) return ScheduleItemMode_tv_bw;
if (strcmp(name, "TV_Color") == 0) return ScheduleItemMode_tv_color;
LOG(LL_ERROR, ("Invalid mode name: %s", name));
return ScheduleItemMode_OnOff;
}
typedef struct Schedule_t {
uint8_t h;
uint8_t m;
uint8_t led;
enum ScheduleItemMode mode;
LEDColor *color;
} Schedule;
static Schedule *schedule = NULL;
static int numScheduleItems = 0;
static int loadedScheduleItems = 0;
static int numberOfLeds = 0;
static int currentHour = 0;
static int currentMinute = 0;
static int clockSpeed = 1; // # seconds for every real time minute
static bool clockRunning = false;
static mgos_timer_id clockTimer = 0;
static void executeScheduleItem(Schedule *s) {
LOG(LL_INFO, ("%d:%d LED #%d / mode=%d / color=%s", s->h, s->m, s->led, s->mode, s->color->name));
if (s->mode == ScheduleItemMode_OnOff) {
NeoPixel_set(s->led, s->color->red, s->color->green, s->color->blue);
}
}
static void LEDScheduler_timerTick() {
bool ledsNeedUpdate = false;
if (clockRunning) {
currentMinute++;
if (currentMinute >= 60) {
currentMinute = 0;
currentHour++;
if (currentHour >= 24) {
currentHour = 0;
}
}
}
for (int i=0; i<loadedScheduleItems; ++i) {
if (schedule[i].h == currentHour && schedule[i].m == currentMinute) {
// ACTION!
executeScheduleItem(&schedule[i]);
ledsNeedUpdate = true;
}
}
if (ledsNeedUpdate) {
NeoPixel_show();
}
}
void LEDScheduler_init(int setNumScheduleItems, int setNumberOfLeds, int ledPin) {
if (schedule != NULL) free(schedule);
numScheduleItems = setNumScheduleItems;
loadedScheduleItems = 0;
numberOfLeds = setNumberOfLeds;
schedule = malloc(numScheduleItems * sizeof(Schedule));
NeoPixel_release();
NeoPixel_create(ledPin, numberOfLeds, NeoPixel_colorOrder_GRB);
clockRunning = false;
clockTimer = mgos_set_timer(1000, true, LEDScheduler_timerTick, NULL);
}
void LEDScheduler_addItem(int h, int m, int led, char *mode, char *colorName) {
if (loadedScheduleItems >= numScheduleItems) {
LOG(LL_ERROR, ("Cannot load schedule item as storage is already full, %d:%d LED #%d", h, m, led));
return;
}
schedule[loadedScheduleItems].h = h;
schedule[loadedScheduleItems].m = m;
schedule[loadedScheduleItems].led = led;
schedule[loadedScheduleItems].mode = modeFromName(mode);
schedule[loadedScheduleItems].color = LEDColor_get(colorName);;
schedule[loadedScheduleItems].h = h;
++loadedScheduleItems;
}
void LEDScheduler_run() { clockRunning = true; }
void LEDScheduler_pause() { clockRunning = false; }
void LEDScheduler_setWatch(int h, int m, int speed) {
currentHour = h;
currentMinute = m;
clockSpeed = speed;
LOG(LL_INFO, ("set time %d:%d and speed to %d real-time seconds for a model minute", h, m, speed));
}

5
src/Scheduler.h Normal file
View File

@@ -0,0 +1,5 @@
extern void LEDScheduler_init(int, int, int);
extern void LEDScheduler_run();
extern void LEDScheduler_pause();
extern void LEDScheduler_addItem(int h, int m, int led, char *mode, char *colorName);
extern void LEDScheduler_setWatch(int h, int m, int speed);

View File

@@ -52,6 +52,7 @@ static void stateEngineTickTimer() {
}
}
static void delayed_boot() {
LOG(LL_INFO, ("*** Start timer for LED state engine ticks"));
mgos_set_timer(mgos_sys_config_get_led_tickDuration(), true, stateEngineTickTimer, NULL);