Refactoring completed: NeoPixel implementation in C instead of js

This commit is contained in:
Dirk Jahnke
2017-12-07 10:33:14 +01:00
parent b79d6dfd48
commit 94e5dce045
9 changed files with 228 additions and 125 deletions

View File

@@ -60,12 +60,12 @@ LEDDefinition *LEDDefinition_get(int ledNum) {
return &ledDefinition[ledNum];
}
void LEDDefinition_add(char *level, char *room, char *id, uint8_t red, uint8_t green, uint8_t blue) {
void LEDDefinition_add(char *level, char *room, char *id, char *onColorName, uint8_t red, uint8_t green, uint8_t blue) {
if (numberOfLEDDefinitions < MAX_LEDS) {
ledDefinition[numberOfLEDDefinitions].level = strdup(level);
ledDefinition[numberOfLEDDefinitions].room = strdup(room);
ledDefinition[numberOfLEDDefinitions].id = strdup(id);
ledDefinition[numberOfLEDDefinitions].onColor.name = strdup("autoColor");
ledDefinition[numberOfLEDDefinitions].onColor.name = strdup(onColorName);
ledDefinition[numberOfLEDDefinitions].onColor.red = red;
ledDefinition[numberOfLEDDefinitions].onColor.green = green;
ledDefinition[numberOfLEDDefinitions].onColor.blue = blue;
@@ -75,25 +75,30 @@ void LEDDefinition_add(char *level, char *room, char *id, uint8_t red, uint8_t g
}
}
void LEDDefinition_addByName(char *level, char *room, char *id, char *onColorName) {
LEDColor *c = LEDColor_get(onColorName);
LEDDefinition_add(level, room, id, onColorName, c->red, c->green, c->blue);
}
void LEDDefinition_init(int numberOfLeds, bool loadDefaultData) {
// initialize
numberOfLEDDefinitions = 0;
if (loadDefaultData) {
do {
LEDDefinition_add("EG", "Wohnzimmer", "EG-WoZi", 200,200,200);
LEDDefinition_add("EG", "Bad", "EG-Bad", 130,130,130);
LEDDefinition_add("EG", "Schlafzimmer", "EG-Schlafen", 150,150,130);
LEDDefinition_add("EG", "Buero 0.1", "EG-Buero-1", 150,130,130);
LEDDefinition_add("EG", "Buero 0.2", "EG-Buero-2", 150,200,200);
LEDDefinition_add("EG", "Flur", "EG-Flur-1", 100,100,100);
LEDDefinition_add("EG", "Flur", "EG-Flur-2", 140,100,100);
LEDDefinition_add("OG1", "Buero 1.1", "OG1-WoZi", 200,200,200);
LEDDefinition_add("OG1", "Bad OG1", "OG1-Bad", 130,130,130);
LEDDefinition_add("OG1", "Buero 1.2", "OG1-Schlafen", 150,150,130);
LEDDefinition_add("OG1", "Buero 1.3", "OG1Buero-1", 150,150,130);
LEDDefinition_add("OG1", "Buero 1.4", "OG1-Buero-2", 150,200,200);
LEDDefinition_add("OG1", "Flur", "OG1-Flur-1", 100,100,100);
LEDDefinition_add("OG1", "Flur", "OG1-Flur-2", 140,100,100);
LEDDefinition_add("EG", "Wohnzimmer", "EG-WoZi", "demo", 200,200,200);
LEDDefinition_add("EG", "Bad", "EG-Bad", "demo", 130,130,130);
LEDDefinition_add("EG", "Schlafzimmer", "EG-Schlafen", "demo", 150,150,130);
LEDDefinition_add("EG", "Buero 0.1", "EG-Buero-1", "demo", 150,130,130);
LEDDefinition_add("EG", "Buero 0.2", "EG-Buero-2", "demo", 150,200,200);
LEDDefinition_add("EG", "Flur", "EG-Flur-1", "demo", 100,100,100);
LEDDefinition_add("EG", "Flur", "EG-Flur-2", "demo", 140,100,100);
LEDDefinition_add("OG1", "Buero 1.1", "OG1-WoZi", "demo", 200,200,200);
LEDDefinition_add("OG1", "Bad OG1", "OG1-Bad", "demo", 130,130,130);
LEDDefinition_add("OG1", "Buero 1.2", "OG1-Schlafen", "demo", 150,150,130);
LEDDefinition_add("OG1", "Buero 1.3", "OG1Buero-1", "demo", 150,150,130);
LEDDefinition_add("OG1", "Buero 1.4", "OG1-Buero-2", "demo", 150,200,200);
LEDDefinition_add("OG1", "Flur", "OG1-Flur-1", "demo", 100,100,100);
LEDDefinition_add("OG1", "Flur", "OG1-Flur-2", "demo", 140,100,100);
} while(numberOfLEDDefinitions < numberOfLeds);
}
}
@@ -121,4 +126,4 @@ int LEDDefinition_getOnColorGreen(int ledNum) {
int LEDDefinition_getOnColorBlue(int ledNum) {
ledNum = verifyLedDefinitionNum(ledNum);
return ledDefinition[ledNum].onColor.blue;
}
}

View File

@@ -7,7 +7,6 @@
#include "fw/src/mgos.h"
#include "mjs.h"
#include "mongoose/mongoose.h"
#include "common/cs_dbg.h"
#define MAX_LEDS 50
@@ -36,7 +35,8 @@ extern LEDDefinition ledDefinition[MAX_LEDS];
extern LEDDefinition *LEDDefinition_get(int ledNum);
extern void LEDDefinition_init(int numberOfLeds, bool loadDefaultData);
extern void LEDDefinition_add(char *level, char *room, char *id, uint8_t red, uint8_t green, uint8_t blue);
extern void LEDDefinition_add(char *level, char *room, char *id, char *onColorName, uint8_t red, uint8_t green, uint8_t blue);
extern void LEDDefinition_addByName(char *level, char *room, char *id, char *onColorName);
extern char *LEDDefinition_getLevel(int ledNum);
extern char *LEDDefinition_getRoom(int ledNum);
extern char *LEDDefinition_getId(int ledNum);
@@ -44,4 +44,4 @@ extern int LEDDefinition_getOnColorRed(int ledNum);
extern int LEDDefinition_getOnColorGreen(int ledNum);
extern int LEDDefinition_getOnColorBlue(int ledNum);
#endif
#endif

View File

@@ -1,9 +1,11 @@
/* LEDState.c */
#include "mgos_sys_config.h"
#include "LEDDefinition.h"
#include "LEDState.h"
#include "AnimationConfig.h"
#include "NeoPixel.h"
static LEDStateEngine theLEDStateEngine;
static int ticks = 0;
@@ -15,13 +17,16 @@ void LEDStateEngine_setNumberOfLeds(int numberOfLeds) {
LOG(LL_ERROR, ("Invalid number of LEDs %d", numberOfLeds));
numberOfLeds = MAX_LEDS;
}
NeoPixel_release();
NeoPixel_create(theLEDStateEngine.pin, numberOfLeds, NeoPixel_colorOrder_RGB);
theLEDStateEngine.numberOfLeds = numberOfLeds;
LOG(LL_INFO, ("LEDStateEngine initialized: numLEDs=%d, MAX_LEDS=%d", numberOfLeds, MAX_LEDS));
LOG(LL_INFO, ("LEDStateEngine initialized: numLEDs=%d, MAX_LEDS=%d, pin=%d", numberOfLeds, MAX_LEDS, theLEDStateEngine.pin));
}
void LEDStateEngine_init(int numberOfLeds) {
LEDStateEngine_setNumberOfLeds(numberOfLeds);
void LEDStateEngine_init(int ledPin, int numberOfLeds) {
theLEDStateEngine.comment = "";
theLEDStateEngine.pin = ledPin;
LEDStateEngine_setNumberOfLeds(numberOfLeds);
for (int i=0; i<numberOfLeds; ++i) {
LEDState_init(i, LEDDefinition_get(i));
}
@@ -42,6 +47,18 @@ void LEDStateEngine_tick() {
for (int i=0; i<theLEDStateEngine.numberOfLeds; ++i) {
LEDState_tick(i);
}
NeoPixel_show();
}
static uint8_t adjustBrightness(uint8_t value) {
return (value * mgos_sys_config_get_led_brightness()/100);
}
static void updateLedDisplay(LEDState *state) {
// strip.setPixel(i, adjustBrightness(LEDState_getRed(i)), adjustBrightness(LEDState_getGreen(i)), adjustBrightness(LEDState_getBlue(i)));
// strip.setPixel(i, adjustBrightness(LEDState_getRed(i)), adjustBrightness(LEDState_getGreen(i)), adjustBrightness(LEDState_getBlue(i)));
NeoPixel_set(state->index,
adjustBrightness(state->currentColor.red), adjustBrightness(state->currentColor.green), adjustBrightness(state->currentColor.blue));
}
void LEDState_tick(int ledNum) {
@@ -65,6 +82,7 @@ void LEDState_tick(int ledNum) {
state->currentColor = dimmedRedColor;
break;
}
updateLedDisplay(state);
}
// do animations, if necessary
}

View File

@@ -23,6 +23,7 @@ typedef struct LEDState_t {
} LEDState;
typedef struct LEDStateEngine_t {
uint8_t pin;
uint8_t numberOfLeds;
LEDState ledState[MAX_LEDS];
char *comment;
@@ -31,7 +32,7 @@ typedef struct LEDStateEngine_t {
extern int getTicks(void);
/* LEDStateEngine */
extern void LEDStateEngine_init(int numberOfLeds);
extern void LEDStateEngine_init(int ledPin, int numberOfLeds);
extern void LEDStateEngine_addComment(char *comment);
extern LEDState *LEDStateEngine_getLedState(int n);

View File

@@ -1,18 +1,26 @@
#include "common/platform.h"
#include "common/cs_dbg.h"
#include "mgos_bitbang.h"
#include "mgos_gpio.h"
#include "mgos_system.h"
#include "NeoPixel.h"
enum NeoPixel_ColorOrder {
RGB = 0,
GRB = 1,
BGR = 2,
};
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;
#define MAX_LEDS 100
static uint8_t NeoPixel_pin = 0;
static uint8_t NeoPixel_numPixels = 0;
static uint8_t NeoPixel_leds[3 * MAX_LEDS];
static NeoPixel_ColorOrder NeoPixel_colorOrder = RGB;
// ## **`NeoPixel_clear()`**
// Clear in-memory values of the pixels.
void NeoPixel_clear() {
if (NeoPixel_leds == NULL) {
LOG(LL_ERROR, ("NeoPixel data space not allocated"));
return;
}
for (int i=0; i<NeoPixel_numPixels * 3; ++i) {
NeoPixel_leds[i] = 0;
}
}
// ## **`NeoPixel_create(pin, numPixels, order)`**
// Create and return a NeoPixel strip object. Example:
@@ -26,56 +34,73 @@ static NeoPixel_ColorOrder NeoPixel_colorOrder = RGB;
// strip.setPixel(1 /* pixel */, 12, 34, 56);
// strip.show();
// ```
void NeoPixel_create(uint8_t, pin, uint8_t numPixels, enum NeoPixel_ColorOrder order) {
void NeoPixel_create(uint8_t pin, uint8_t numPixels, enum NeoPixel_ColorOrder order) {
mgos_gpio_init();
NeoPixel_pin = pin;
NeoPixel_numPixels = numPixels;
NeoPixel_colorOrder = order;
NeoPixel_leds = malloc(NeoPixel_numPixels * 3);
// GPIO.set_mode(pin, GPIO.MODE_OUTPUT);
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));
NeoPixel_clear();
}
// ## **`NeoPixel_clear()`**
// Clear in-memory values of the pixels.
void NeoPixel_clear() {
for (int i=0; i<NeoPixel_numPixels * 3; ++i) {
NeoPixel_leds[i] = 0;
void NeoPixel_release() {
if (NeoPixel_leds == NULL) {
LOG(LL_ERROR, ("NeoPixel data space not allocated"));
return;
}
free(NeoPixel_leds);
NeoPixel_leds = NULL;
NeoPixel_numPixels = 0;
}
// ## **`NeoPixel_set(i, r, g, b)`**
// Set i-th's pixel's RGB value.
// Note that this only affects in-memory value of the pixel.
void NeoPixel_set(uint8_t pixel, uint8_t red, uint8_t green, uint8_t blue) {
void NeoPixel_set(int pixel, int red, int green, int blue) {
uint8_t v0, v1, v2;
if (NeoPixel_colorOrder == RGB) {
if (NeoPixel_leds == NULL) {
LOG(LL_ERROR, ("NeoPixel data space not allocated"));
return;
}
if (pixel < 0 || pixel >= NeoPixel_numPixels) {
LOG(LL_ERROR, ("Invalid pixel number %d", pixel));
return;
}
if (NeoPixel_colorOrder == NeoPixel_colorOrder_RGB) {
v0 = red; v1 = green; v2 = blue;
} else if (NeoPixel_colorOrder == GRB) {
} else if (NeoPixel_colorOrder == NeoPixel_colorOrder_GRB) {
v0 = green; v1 = red; v2 = blue;
} else if (NeoPixel_colorOrder == BGR) {
} else if (NeoPixel_colorOrder == NeoPixel_colorOrder_BGR) {
v0 = blue; v1 = green; v2 = red;
} else return;
NeoPixel_leds[pixel] = v0;
NeoPixel_leds[pixel+1] = v1;
NeoPixel_leds[pixel+2] = v2;
NeoPixel_leds[3*pixel] = v0;
NeoPixel_leds[3*pixel+1] = v1;
NeoPixel_leds[3*pixel+2] = v2;
}
// ## **`NeoPixel_show()`**
// Output values of the pixels.
void NeoPixel_show() {
if (NeoPixel_leds == NULL) {
LOG(LL_ERROR, ("NeoPixel data space not allocated"));
return;
}
// GPIO.write(this.pin, 0);
mgos_gpio_write(pin, false);
mgos_gpio_write(NeoPixel_pin, false);
// Sys.usleep(60);
mgos_usleep(60);
// BitBang.write(this.pin, BitBang.DELAY_100NSEC, 3, 8, 8, 6, this.data, this.len);
mgos_bitbang_write_bits(NeoPixel_pin, DELAY_100NSEC, 3, 8, 8, 6, NeoPixel_leds, NeoPixel_numPixels);
mgos_bitbang_write_bits(NeoPixel_pin, MGOS_DELAY_100NSEC, 3, 8, 8, 6, NeoPixel_leds, 3 * NeoPixel_numPixels);
// GPIO.write(this.pin, 0);
mgos_gpio_write(pin, false);
mgos_gpio_write(NeoPixel_pin, false);
// Sys.usleep(60);
mgos_usleep(60);
// GPIO.write(this.pin, 1);
mgos_gpio_write(pin, true);
mgos_gpio_write(NeoPixel_pin, true);
}

15
src/NeoPixel.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef NeoPixel_h_loaded
#define NeoPixel_h_loaded
enum NeoPixel_ColorOrder {
NeoPixel_colorOrder_RGB = 0,
NeoPixel_colorOrder_GRB = 1,
NeoPixel_colorOrder_BGR = 2
};
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();
#endif

View File

@@ -13,6 +13,7 @@
#include "LEDDefinition.h"
#include "AnimationConfig.h"
#include "LEDState.h"
#include "NeoPixel.h"
#if CS_PLATFORM == CS_P_ESP8266
#define LED_GPIO 2 /* On ESP-12E there is a blue LED connected to GPIO2 */
@@ -36,24 +37,30 @@ int get_led_gpio_pin(void) {
LEDStateEngine ledStateEngine;
static bool stateEngineRunning = false;
static bool pausedReported = false;
static void stateEngineTickTimer() {
if (stateEngineRunning) {
// LOG(LL_INFO, ("digg"));
LEDStateEngine_tick();
pausedReported = false;
} else {
LOG(LL_INFO, ("--paused--"));
if (!pausedReported) {
LOG(LL_INFO, ("--paused--"));
pausedReported = true;
}
}
}
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); // every 0.1 second call timer_cb
mgos_set_timer(mgos_sys_config_get_led_tickDuration(), true, stateEngineTickTimer, NULL);
}
enum mgos_app_init_result mgos_app_init(void) {
int numberOfLeds = mgos_sys_config_get_led_count();
bool loadDefaultData = mgos_sys_config_get_led_useDefaults();
int ledPin = mgos_sys_config_get_led_pin();
LOG(LL_DEBUG, ("LEDColor_init(loadDefaultData=%s)", loadDefaultData ? "true" : "false"));
mgos_msleep(50);
@@ -67,13 +74,13 @@ enum mgos_app_init_result mgos_app_init(void) {
if (loadDefaultData) {
LOG(LL_DEBUG, ("LEDStateEngine_init(numberOfLeds=%d)", numberOfLeds));
mgos_msleep(50);
LEDStateEngine_init(numberOfLeds);
LEDStateEngine_init(ledPin, numberOfLeds);
// stateEngineRunning = true;
} else {
LOG(LL_INFO, ("LEDStateEngine needs to be initialized, not started yet as LEDDefinition not loaded so far"));
}
mgos_set_timer(5000, false, delayed_boot, NULL); // after 5 seconds boot the functions
mgos_set_timer(1000, false, delayed_boot, NULL);
return MGOS_APP_INIT_SUCCESS;
}
@@ -86,10 +93,7 @@ void printColor(char *name) {
void addColor(char *name, int red, int green, int blue) {
LEDColor_add(name, red, green, blue);
}
void addLedDefinition(char *level, char *room, char *id, char *onColorName) {
LEDColor *c = LEDColor_get(onColorName);
LEDDefinition_add(level, room, id, c->red, c->green, c->blue);
}
void addAnimationStep(int ledIndex, char *ledMode, int duration) {
LEDMode m = LEDMode_off;
if (strcmp(ledMode, "on") == 0 || strcmp(ledMode, "LEDMode_on") == 0) {