瀏覽代碼

Implemented RGB control functionality

Philipp Hinz 8 年之前
父節點
當前提交
5762b86f68
共有 6 個文件被更改,包括 344 次插入4 次删除
  1. 3 0
      CoffeeCode/Release/subdir.mk
  2. 1 1
      CoffeeCode/buildno
  3. 7 3
      CoffeeCode/main.cpp
  4. 1 0
      CoffeeCode/makefile.targets
  5. 273 0
      CoffeeCode/stripe.cpp
  6. 59 0
      CoffeeCode/stripe.h

+ 3 - 0
CoffeeCode/Release/subdir.mk

@@ -11,6 +11,7 @@ CPP_SRCS += \
 ../logger.cpp \
 ../main.cpp \
 ../spi.cpp \
+../stripe.cpp \
 ../timer.cpp 
 
 OBJS += \
@@ -21,6 +22,7 @@ OBJS += \
 ./logger.o \
 ./main.o \
 ./spi.o \
+./stripe.o \
 ./timer.o 
 
 CPP_DEPS += \
@@ -31,6 +33,7 @@ CPP_DEPS += \
 ./logger.d \
 ./main.d \
 ./spi.d \
+./stripe.d \
 ./timer.d 
 
 

+ 1 - 1
CoffeeCode/buildno

@@ -1 +1 @@
-22
+31

+ 7 - 3
CoffeeCode/main.cpp

@@ -22,6 +22,7 @@
 #include "logger.h"
 #include "lcd.h"
 #include "hal.h"
+#include "stripe.h"
 
 const int buildno = (1+(int)(
 #include "buildno"
@@ -136,12 +137,12 @@ int main(int argc, char *argv[]) {
 	if (rc != 0)
 		throw(L"pthread_mutexattr_destroy returns " + rc);
 
-	for (int i = 0; i < 1; i++) {
+	for (int i = 0; i < 2; i++) {
 		if (i == THREAD_MAIN)
 			rc = pthread_create(&thread[i], NULL, mainLoop, (void *) i);
-		/*else if (i == THREAD_STRIPE)
+		else if (i == THREAD_STRIPE)
 			rc = pthread_create(&thread[i], NULL, stripeThread, (void *) i);
-		else if (i == THREAD_CAN)
+		/*else if (i == THREAD_CAN)
 			rc = pthread_create(&thread[i], NULL, canThread, (void *) i);*/
 		if (rc) {
 			logger_error("Error:unable to create thread, %d\n", rc);
@@ -237,6 +238,9 @@ void *mainLoop(void *threadid) {
 	pthread_exit(NULL);
 }
 
+/**
+ * Temporary timer for displaying the current time
+ */
 void timeHandler(void) {
     time_t rawtime;
     struct tm * timeinfo;

+ 1 - 0
CoffeeCode/makefile.targets

@@ -5,5 +5,6 @@ OBJS2 += \
 ./lcd.o \
 ./hal.o \
 ./spi.o \
+./stripe.o \
 ./timer.o \
 ./sqlite/sqlite3.o 

+ 273 - 0
CoffeeCode/stripe.cpp

@@ -0,0 +1,273 @@
+/*
+ * stripe.cpp
+ *
+ *  Created on: Sep 25, 2017
+ *      Author: Philipp Hinz
+ */
+
+#include <wiringPiI2C.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <string.h>
+#include "stripe.h"
+#include "global.h"
+#include "timer.h"
+#include "logger.h"
+
+stripe_color currentColor;
+stripe_color effectColor;
+int currentWhite = 0, currentDim = 0;
+stripe_transient_t currentTransient = TRANS_DIRECT;
+timer stripeTimer(stripeTimerHandler);
+int i2cfd;
+
+/**
+ * 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(40);
+	stripeTimer.stop();
+	logger(V_BASIC, "Initialized Stripe thread\n");
+
+	stripe_color col;
+	col.red = 255;
+	//stripeEffectPulse(col);
+	int tmp = 0, inc = 1;
+	while (1) {
+		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() {
+	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
+ */
+int stripeCommand(int len, char* data) {
+	int ret = 0;
+	int i = 0;
+	pthread_mutex_lock(&mutex);
+	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);
+	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);
+}
+
+/**
+ * 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);
+}
+
+/**
+ * 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();
+}
+
+/**
+ * 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(40);
+	stripeTimer.start();
+}

+ 59 - 0
CoffeeCode/stripe.h

@@ -0,0 +1,59 @@
+/*
+ * stripe.h
+ *
+ *  Created on: Sep 25, 2017
+ *      Author: Philipp Hinz
+ */
+
+#ifndef STRIPE_H_
+#define STRIPE_H_
+
+// i2c
+#define I2C_ADDRESS_STRIPE	0x69
+#define STRIPE_CMD_SETR		0x01
+#define STRIPE_CMD_SETG		0x02
+#define STRIPE_CMD_SETB		0x03
+#define STRIPE_CMD_SETW		0x04
+#define STRIPE_CMD_SETDIM	0x05
+#define STRIPE_CMD_SET		0x06	// Bytes: DIM R G B W
+#define STRIPE_CMD_SET2		0x07	// Bytes: DIM R G B
+#define STRIPE_CMD_RESET	0x09
+#define STRIPE_CMD_FADEOUT	0x0A	// Bytes: TIMEH TIMEL
+#define STRIPE_CMD_FADETO	0x0B	// Bytes: R G B W TIMEH TIMEL
+#define STRIPE_CMD_FADESTOP	0x0C
+
+// Color transient (fading) parameters
+typedef enum {
+	TRANS_DIRECT = 0,
+	TRANS_FAST = 6,
+	TRANS_MEDIUM = 35,
+	TRANS_SLOW = 200
+} stripe_transient_t;
+
+struct stripe_color {
+	int red = 0;
+	int green = 0;
+	int blue = 0;
+};
+
+void *stripeThread(void *threadid);
+void *stripeTimerHandler(void *threadid);
+void stripeInit();
+int stripeCommand(int len, char* data);
+void stripeUpdate(void);
+void stripeUpdateDim(void);
+void stripeSetRGB(int red, int green, int blue);
+void stripeSetColor(stripe_color color);
+void stripeSetTransient(stripe_transient_t transient);
+void stripeSetDim(int dim);
+void stripeSetWhite(int white);
+void stripeOn(void);
+void stripeOff(void);
+void stripeGetRGB(int* red, int* green, int* blue);
+void stripeGetDim(int* dim);
+void stripeGetWhite(int* white);
+void stripeEffectDisable(void);
+void stripeEffectHeating(int percent);
+void stripeEffectPulse(stripe_color color);
+
+#endif /* STRIPE_H_ */