/* * stripe.cpp * * Created on: Sep 25, 2017 * Author: Philipp Hinz */ #include #include #include #include #include #include #include #include "stripe.h" #include "global.h" #include "timer.h" #include "logger.h" #include "coffee.h" stripe_color currentColor; stripe_color effectColor; int currentWhite = 0, currentDim = 0; stripe_transient_t currentTransient = TRANS_DIRECT; timer stripeTimer(stripeTimerHandler); int i2cfd; coffee_status_t lastState = STATE_OFF; /** * This is the handler for time based stripe effects * @param *threadid Thread ID */ void *stripeTimerHandler(void *threadid) { if (currentColor.red == effectColor.red && currentColor.green == effectColor.green && currentColor.blue == effectColor.blue) { stripeSetRGB(0, 0, 0); } else { stripeSetColor(effectColor); } pthread_exit(NULL); } /** * Thread for the stripe control. Requests data from other threads or HAL * @param *threadid Thread ID */ void *stripeThread(void *threadid) { logger(V_STRIPE, "Initializing Stripe thread...\n"); stripeInit(); stripeTimer.setDivider(ms2Divider(2000)); stripeTimer.stop(); logger(V_BASIC, "Initialized Stripe thread\n"); stripeOn(); stripeSetRGB(0, 0, 0); stripe_color col; //int tmp = 0, inc = 1; while (1) { if (getState() != lastState) { lastState = getState(); switch (lastState) { case STATE_IDLE: case STATE_HEATING: case STATE_BREW: case STATE_BREWMANUAL: case STATE_CLEANING: case STATE_NULL: col.red = 255; col.green = 0; col.blue = 0; stripeEffectPulse(col); break; case STATE_FULLTANK: col.red = 255; col.green = 0; col.blue = 255; stripeEffectPulse(col); break; case STATE_INITALHEATING: col.red = 0; col.green = 0; col.blue = 255; stripeEffectPulse(col); break; case STATE_ERROR: stripeEffectDisable(); stripeSetTransient(TRANS_FAST); stripeSetRGB(255, 0, 0); break; case STATE_OFF: usleep(50000); stripeEffectDisable(); stripeSetTransient(TRANS_SLOW); stripeSetRGB(0, 0, 0); stripeSetRGB(0, 0, 0); // do it twice, else it doesn't work?! dafuq.. break; case STATE_WAIT_OFF: col.red = 255; col.green = 0; col.blue = 0; stripeEffectPulse(col); stripeSetTransient(TRANS_FAST); break; } } usleep(100000); /* pause(); stripeEffectHeating(tmp); logger(V_NONE, LOG_ERRORC, "Simulating %d%% percent heating\n", tmp); sleep(1); if (inc) { if (++tmp >= 100) inc = 0; } else { if (--tmp <= 0) inc = 1; }*/ } pthread_exit(NULL); } /** * Initializes i2c communication to stripe controller */ void stripeInit(void) { i2cfd = wiringPiI2CSetup(I2C_ADDRESS_STRIPE); if (i2cfd < 0) { logger_error("Could not initialize i2c with device ID 0x%.2x (%s)\n", I2C_ADDRESS_STRIPE, strerror(errno)); pthread_exit(NULL); } logger(V_STRIPE, "Initialized i2c device on address 0x%.2x\n", I2C_ADDRESS_STRIPE); currentColor.red = 0; currentColor.green = 0; currentColor.blue = 0; currentWhite = 0; currentDim = 0xff; currentTransient = TRANS_DIRECT; } /** * Sends out command data to the stripe controller via i2c * @param len Length of the data array * @param *data Pointer to data array * @return Number of failed bytes, 0 if successful */ int stripeCommand(int len, char* data) { int ret = 0; int i = 0; pthread_mutex_lock(&mutex_i2c); for (i = 0; i < len; i++) { ret -= wiringPiI2CWriteReg8(i2cfd, i, data[i]); } logger(V_STRIPE, "Wrote %d bytes to i2c device\n", len); if (ret) logger(V_NONE, LOG_WARN, "Failed to write %d of %d bytes on i2c device\n", ret, len); pthread_mutex_unlock(&mutex_i2c); return ret; } /** * Updates the color data and prepares the stripe command */ void stripeUpdate(void) { char data[7]; int len = 7; if (currentTransient == TRANS_DIRECT) { data[0] = STRIPE_CMD_SET; data[1] = currentDim; data[2] = currentColor.red; data[3] = currentColor.green; data[4] = currentColor.blue; data[5] = currentWhite; len = 6; } else { data[0] = STRIPE_CMD_FADETO; data[1] = currentColor.red; data[2] = currentColor.green; data[3] = currentColor.blue; data[4] = currentWhite; data[5] = (currentTransient >> 8) & 0xff; data[6] = currentTransient & 0xff; } stripeCommand(len, data); logger(V_STRIPE, "Updated stripe to color r %d g %d b %d\n", currentColor.red, currentColor.green, currentColor.blue); } /** * Updates the dimmer value of the stripe */ void stripeUpdateDim(void) { char data[2]; int len = 2; data[0] = STRIPE_CMD_SETDIM; data[1] = currentDim; stripeCommand(len, data); } /** * Let the stripe fade out and turn off */ void stripeFadeOut(void) { char data[3]; int len = 3; data[0] = STRIPE_CMD_FADEOUT; data[1] = (currentTransient >> 8) & 0xff; data[2] = currentTransient & 0xff; stripeCommand(len, data); } /** * Stops the current fading */ void stripeFadeStop(void) { char data[1]; int len = 1; data[0] = STRIPE_CMD_FADESTOP; stripeCommand(len, data); } /** * Updates the color of the stripe * @param red Red value (max 255) * @param green Green value (max 255) * @param blue Blue value (max 255) */ void stripeSetRGB(int red, int green, int blue) { currentColor.red = red & 0xff; currentColor.green = green & 0xff; currentColor.blue = blue & 0xff; stripeUpdate(); } /** * Updates the color of the stripe * @param color Color struct */ void stripeSetColor(stripe_color color) { stripeSetRGB(color.red, color.green, color.blue); } /** * Updates the transient time for the stripe (fading) * @param transient Transient time in ticks */ void stripeSetTransient(stripe_transient_t transient) { currentTransient = transient; } /** * Updates the dimmer value of the stripe * @param dim Dimmer value */ void stripeSetDim(int dim) { dim = dim & 0xff; } /** * Updates the white value of the stripe (4th channel) * @param white White value */ void stripeSetWhite(int white) { currentWhite = white & 0xff; } /** * Turns the stripe on (Sets dimmer to 100%) */ void stripeOn(void) { if (!currentDim) { currentDim = 0xff; } stripeUpdateDim(); } /** * Turns the stripe on (Sets dimmer to 0%) */ void stripeOff(void) { currentDim = 0; stripeUpdateDim(); } /** * Reads the current stripe color * @param *red Pointer to red variable * @param *green Pointer to green variable * @param *blue Pointer to blue variable */ void stripeGetRGB(int* red, int* green, int* blue) { *red = currentColor.red; *green = currentColor.green; *blue = currentColor.blue; } /** * Reads the current stripe dimmer value * @param *dim Pointer to dimmer variable */ void stripeGetDim(int* dim) { *dim = currentDim; } /** * Reads the current stripe white value (4th channel) * @param *white Pointer to white variable */ void stripeGetWhite(int* white) { *white = currentWhite; } /** * Stops current running effects */ void stripeEffectDisable(void) { stripeTimer.stop(); stripeFadeStop(); } /** * Sets the stripe to a correspondending color to the heating status * @param percent Heating level (0-100%) */ void stripeEffectHeating(int percent) { long red, blue; if (percent > 100) percent = 100; red = percent * 255; blue = (100 - percent) * 255; stripeSetTransient(TRANS_FAST); stripeSetRGB(red / 100, 0, blue / 100); } /** * Enables pulsing with a given color of the stripe * @param color Effect color */ void stripeEffectPulse(stripe_color color) { effectColor = color; stripeSetTransient(TRANS_MEDIUM); stripeTimer.setDivider(ms2Divider(2150)); stripeTimer.start(); }