stripe.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * stripe.cpp
  3. *
  4. * Created on: Sep 25, 2017
  5. * Author: Philipp Hinz
  6. */
  7. #include <wiringPiI2C.h>
  8. #include <stdlib.h>
  9. #include <errno.h>
  10. #include <pthread.h>
  11. #include <unistd.h>
  12. #include <string.h>
  13. #include "stripe.h"
  14. #include "global.h"
  15. #include "timer.h"
  16. #include "logger.h"
  17. stripe_color currentColor;
  18. stripe_color effectColor;
  19. int currentWhite = 0, currentDim = 0;
  20. stripe_transient_t currentTransient = TRANS_DIRECT;
  21. timer stripeTimer(stripeTimerHandler);
  22. int i2cfd;
  23. /**
  24. * This is the handler for time based stripe effects
  25. * @param *threadid Thread ID
  26. */
  27. void *stripeTimerHandler(void *threadid) {
  28. if (currentColor.red == effectColor.red
  29. && currentColor.green == effectColor.green
  30. && currentColor.blue == effectColor.blue) {
  31. stripeSetRGB(0, 0, 0);
  32. } else {
  33. stripeSetColor(effectColor);
  34. }
  35. pthread_exit(NULL);
  36. }
  37. /**
  38. * Thread for the stripe control. Requests data from other threads or HAL
  39. * @param *threadid Thread ID
  40. */
  41. void *stripeThread(void *threadid) {
  42. logger(V_STRIPE, "Initializing Stripe thread...\n");
  43. stripeInit();
  44. stripeTimer.setDivider(40);
  45. stripeTimer.stop();
  46. logger(V_BASIC, "Initialized Stripe thread\n");
  47. stripe_color col;
  48. col.red = 255;
  49. col.green = 0;
  50. col.blue = 0;
  51. stripeEffectPulse(col);
  52. int tmp = 0, inc = 1;
  53. while (1) {
  54. pause();
  55. stripeEffectHeating(tmp);
  56. logger(V_NONE, LOG_ERRORC, "Simulating %d%% percent heating\n", tmp);
  57. sleep(1);
  58. if (inc) {
  59. if (++tmp >= 100)
  60. inc = 0;
  61. } else {
  62. if (--tmp <= 0)
  63. inc = 1;
  64. }
  65. }
  66. pthread_exit(NULL);
  67. }
  68. /**
  69. * Initializes i2c communication to stripe controller
  70. */
  71. void stripeInit() {
  72. i2cfd = wiringPiI2CSetup(I2C_ADDRESS_STRIPE);
  73. if (i2cfd < 0) {
  74. logger_error("Could not initialize i2c with device ID 0x%.2x (%s)\n",
  75. I2C_ADDRESS_STRIPE, strerror(errno));
  76. pthread_exit(NULL);
  77. }
  78. logger(V_STRIPE, "Initialized i2c device on address 0x%.2x\n",
  79. I2C_ADDRESS_STRIPE);
  80. currentColor.red = 0;
  81. currentColor.green = 0;
  82. currentColor.blue = 0;
  83. currentWhite = 0;
  84. currentDim = 0xff;
  85. currentTransient = TRANS_DIRECT;
  86. }
  87. /**
  88. * Sends out command data to the stripe controller via i2c
  89. * @param len Length of the data array
  90. * @param *data Pointer to data array
  91. * @return Number of failed bytes, 0 if successful
  92. */
  93. int stripeCommand(int len, char* data) {
  94. int ret = 0;
  95. int i = 0;
  96. pthread_mutex_lock(&mutex);
  97. for (i = 0; i < len; i++) {
  98. ret -= wiringPiI2CWriteReg8(i2cfd, i, data[i]);
  99. }
  100. logger(V_STRIPE, "Wrote %d bytes to i2c device\n", len);
  101. if (ret)
  102. logger(V_NONE, LOG_WARN,
  103. "Failed to write %d of %d bytes on i2c device\n", ret, len);
  104. pthread_mutex_unlock(&mutex);
  105. return ret;
  106. }
  107. /**
  108. * Updates the color data and prepares the stripe command
  109. */
  110. void stripeUpdate(void) {
  111. char data[7];
  112. int len = 7;
  113. if (currentTransient == TRANS_DIRECT) {
  114. data[0] = STRIPE_CMD_SET;
  115. data[1] = currentDim;
  116. data[2] = currentColor.red;
  117. data[3] = currentColor.green;
  118. data[4] = currentColor.blue;
  119. data[5] = currentWhite;
  120. len = 6;
  121. } else {
  122. data[0] = STRIPE_CMD_FADETO;
  123. data[1] = currentColor.red;
  124. data[2] = currentColor.green;
  125. data[3] = currentColor.blue;
  126. data[4] = currentWhite;
  127. data[5] = (currentTransient >> 8) & 0xff;
  128. data[6] = currentTransient & 0xff;
  129. }
  130. stripeCommand(len, data);
  131. }
  132. /**
  133. * Updates the dimmer value of the stripe
  134. */
  135. void stripeUpdateDim(void) {
  136. char data[2];
  137. int len = 2;
  138. data[0] = STRIPE_CMD_SETDIM;
  139. data[1] = currentDim;
  140. stripeCommand(len, data);
  141. }
  142. /**
  143. * Updates the color of the stripe
  144. * @param red Red value (max 255)
  145. * @param green Green value (max 255)
  146. * @param blue Blue value (max 255)
  147. */
  148. void stripeSetRGB(int red, int green, int blue) {
  149. currentColor.red = red & 0xff;
  150. currentColor.green = green & 0xff;
  151. currentColor.blue = blue & 0xff;
  152. stripeUpdate();
  153. }
  154. /**
  155. * Updates the color of the stripe
  156. * @param color Color struct
  157. */
  158. void stripeSetColor(stripe_color color) {
  159. stripeSetRGB(color.red, color.green, color.blue);
  160. }
  161. /**
  162. * Updates the transient time for the stripe (fading)
  163. * @param transient Transient time in ticks
  164. */
  165. void stripeSetTransient(stripe_transient_t transient) {
  166. currentTransient = transient;
  167. }
  168. /**
  169. * Updates the dimmer value of the stripe
  170. * @param dim Dimmer value
  171. */
  172. void stripeSetDim(int dim) {
  173. dim = dim & 0xff;
  174. }
  175. /**
  176. * Updates the white value of the stripe (4th channel)
  177. * @param white White value
  178. */
  179. void stripeSetWhite(int white) {
  180. currentWhite = white & 0xff;
  181. }
  182. /**
  183. * Turns the stripe on (Sets dimmer to 100%)
  184. */
  185. void stripeOn(void) {
  186. if (!currentDim) {
  187. currentDim = 0xff;
  188. }
  189. stripeUpdateDim();
  190. }
  191. /**
  192. * Turns the stripe on (Sets dimmer to 0%)
  193. */
  194. void stripeOff(void) {
  195. currentDim = 0;
  196. stripeUpdateDim();
  197. }
  198. /**
  199. * Reads the current stripe color
  200. * @param *red Pointer to red variable
  201. * @param *green Pointer to green variable
  202. * @param *blue Pointer to blue variable
  203. */
  204. void stripeGetRGB(int* red, int* green, int* blue) {
  205. *red = currentColor.red;
  206. *green = currentColor.green;
  207. *blue = currentColor.blue;
  208. }
  209. /**
  210. * Reads the current stripe dimmer value
  211. * @param *dim Pointer to dimmer variable
  212. */
  213. void stripeGetDim(int* dim) {
  214. *dim = currentDim;
  215. }
  216. /**
  217. * Reads the current stripe white value (4th channel)
  218. * @param *white Pointer to white variable
  219. */
  220. void stripeGetWhite(int* white) {
  221. *white = currentWhite;
  222. }
  223. /**
  224. * Stops current running effects
  225. */
  226. void stripeEffectDisable(void) {
  227. stripeTimer.stop();
  228. }
  229. /**
  230. * Sets the stripe to a correspondending color to the heating status
  231. * @param percent Heating level (0-100%)
  232. */
  233. void stripeEffectHeating(int percent) {
  234. long red, blue;
  235. if (percent > 100)
  236. percent = 100;
  237. red = percent * 255;
  238. blue = (100 - percent) * 255;
  239. stripeSetTransient(TRANS_FAST);
  240. stripeSetRGB(red / 100, 0, blue / 100);
  241. }
  242. /**
  243. * Enables pulsing with a given color of the stripe
  244. * @param color Effect color
  245. */
  246. void stripeEffectPulse(stripe_color color) {
  247. effectColor = color;
  248. stripeSetTransient(TRANS_MEDIUM);
  249. stripeTimer.setDivider(40);
  250. stripeTimer.start();
  251. }