You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

385 lines
8.1 KiB

5 years ago
  1. #include <Wire.h>
  2. #include <Adafruit_NeoPixel.h>
  3. #include <AT24C32.h>
  4. #include <DS3231.h>
  5. #include <States.h>
  6. #include <ViewStates.h>
  7. #include <ControlStates.h>
  8. #include <Button.h>
  9. // debug
  10. #define DEBUG 1
  11. // Neopixel
  12. #define MATRIX_PIN 12
  13. #define MATRIX_SIZE 121
  14. Adafruit_NeoPixel pixels = Adafruit_NeoPixel(MATRIX_SIZE, MATRIX_PIN, NEO_GRB + NEO_KHZ800);
  15. // Date view delimiter
  16. #define DATE_DELIMITER '.'
  17. // Buttons
  18. #define LEFT_PIN 11
  19. #define DECREMENT_PIN 10
  20. #define ENTER_PIN 9
  21. #define INCREMENT_PIN 8
  22. #define RIGHT_PIN 7
  23. Button leftBtn = Button(LEFT_PIN, LOW);
  24. Button decrementBtn = Button(DECREMENT_PIN, LOW);
  25. Button enterBtn = Button(ENTER_PIN, LOW);
  26. Button incrementBtn = Button(INCREMENT_PIN, LOW);
  27. Button rightBtn = Button(RIGHT_PIN, LOW);
  28. // LED matrix
  29. uint8_t matrix[MATRIX_SIZE];
  30. // EPROMM AT24C32
  31. AT24C32 at24c32;
  32. // RTC DS3231
  33. DS3231 ds3231;
  34. // states
  35. ControlStates controlState = ControlStates::VIEW;
  36. ControlStates oldControlState = ControlStates::VIEW;
  37. ViewStates viewState = ViewStates::TIME;
  38. ViewStates oldViewState = ViewStates::TIME;
  39. // control state
  40. ControlState *currentControlState = new ControlViewState(at24c32);
  41. // view state
  42. ViewState *currentViewState = new ViewTimeState(ds3231, at24c32);
  43. /**
  44. setup
  45. */
  46. void setup()
  47. {
  48. #ifdef DEBUG
  49. Serial.begin(9600);
  50. #endif
  51. pixels.begin();
  52. ds3231.begin();
  53. at24c32.begin();
  54. leftBtn.begin();
  55. decrementBtn.begin();
  56. enterBtn.begin();
  57. incrementBtn.begin();
  58. rightBtn.begin();
  59. viewState = ViewStates(at24c32.read(VIEW_STATE_ADDRESS) % 6);
  60. printStatus();
  61. }
  62. /**
  63. loop
  64. */
  65. void loop()
  66. {
  67. checkControlState();
  68. controls();
  69. checkViewState();
  70. // render
  71. renderInterval();
  72. }
  73. /**
  74. check current control state and change eventually
  75. */
  76. void checkControlState()
  77. {
  78. if (controlState != oldControlState)
  79. {
  80. delete currentControlState;
  81. switch (controlState)
  82. {
  83. case ControlStates::VIEW:
  84. currentControlState = new ControlViewState(at24c32);
  85. break;
  86. case ControlStates::TIME_HOURS:
  87. currentControlState = new ControlTimeState(ds3231, at24c32);
  88. break;
  89. case ControlStates::TIME_MINUTES:
  90. currentControlState = new ControlTimeState(ds3231, at24c32);
  91. break;
  92. case ControlStates::TIME_MODE:
  93. currentControlState = new ControlTimeState(ds3231, at24c32);
  94. break;
  95. case ControlStates::TIME_SECONDS:
  96. currentControlState = new ControlSecondsState(ds3231);
  97. break;
  98. case ControlStates::DATE_DATE:
  99. currentControlState = new ControlDateState(ds3231);
  100. break;
  101. case ControlStates::DATE_MONTH:
  102. currentControlState = new ControlDateState(ds3231);
  103. break;
  104. case ControlStates::DATE_YEAR:
  105. currentControlState = new ControlDateState(ds3231);
  106. break;
  107. case ControlStates::COLOR_R:
  108. currentControlState = new ControlColorState(at24c32);
  109. break;
  110. case ControlStates::COLOR_G:
  111. currentControlState = new ControlColorState(at24c32);
  112. break;
  113. case ControlStates::COLOR_B:
  114. currentControlState = new ControlColorState(at24c32);
  115. break;
  116. case ControlStates::TEXT:
  117. currentControlState = new ControlTextState(at24c32);
  118. break;
  119. default:
  120. currentControlState = new ControlViewState(at24c32);
  121. }
  122. oldControlState = controlState;
  123. printStatus();
  124. }
  125. }
  126. /**
  127. check current view state and change eventually
  128. */
  129. void checkViewState()
  130. {
  131. if (viewState != oldViewState)
  132. {
  133. delete currentViewState;
  134. switch (viewState)
  135. {
  136. case ViewStates::TIME:
  137. currentViewState = new ViewTimeState(ds3231, at24c32);
  138. break;
  139. case ViewStates::SECONDS:
  140. currentViewState = new ViewSecondsState(ds3231, at24c32);
  141. break;
  142. case ViewStates::TEMPERATURE:
  143. currentViewState = new ViewTemperatureState(ds3231, at24c32);
  144. break;
  145. case ViewStates::DATE:
  146. currentViewState = new ViewDateState(ds3231, at24c32, DATE_DELIMITER);
  147. break;
  148. case ViewStates::TEXT:
  149. currentViewState = new ViewTextState(at24c32);
  150. break;
  151. case ViewStates::LED_DEMO:
  152. currentViewState = new ViewLEDState();
  153. break;
  154. default:
  155. currentViewState = new ViewTimeState(ds3231, at24c32);
  156. }
  157. oldViewState = viewState;
  158. at24c32.write(VIEW_STATE_ADDRESS, uint8_t(viewState));
  159. printStatus();
  160. }
  161. }
  162. /**
  163. check inputs
  164. */
  165. void controls()
  166. {
  167. leftBtn.loop(leftCallback);
  168. decrementBtn.loop(decrementCallback);
  169. enterBtn.loop(enterCallback);
  170. incrementBtn.loop(incrementCallback);
  171. rightBtn.loop(rightCallback);
  172. }
  173. /**
  174. left callback
  175. */
  176. void leftCallback()
  177. {
  178. // delegate to current control state
  179. currentControlState->leftPressed(viewState, controlState);
  180. #ifdef DEBUG
  181. Serial.print(F("< "));
  182. #endif
  183. }
  184. /**
  185. decrement callback
  186. */
  187. void decrementCallback()
  188. {
  189. // delegate to current control state
  190. currentControlState->decrementPressed(viewState, controlState);
  191. #ifdef DEBUG
  192. Serial.print(F("- "));
  193. #endif
  194. }
  195. /**
  196. enter callback
  197. */
  198. void enterCallback()
  199. {
  200. // delegate to current control state
  201. currentControlState->enterPressed(viewState, controlState);
  202. #ifdef DEBUG
  203. Serial.print(F("# "));
  204. #endif
  205. }
  206. /**
  207. increment callback
  208. */
  209. void incrementCallback()
  210. {
  211. // delegate to current control state
  212. currentControlState->incrementPressed(viewState, controlState);
  213. #ifdef DEBUG
  214. Serial.print(F("+ "));
  215. #endif
  216. }
  217. /**
  218. right callback
  219. */
  220. void rightCallback()
  221. {
  222. // delegate to current control state
  223. currentControlState->rightPressed(viewState, controlState);
  224. #ifdef DEBUG
  225. Serial.print(F("> "));
  226. #endif
  227. }
  228. /**
  229. periodic rendering
  230. */
  231. void renderInterval()
  232. {
  233. static const unsigned long REFRESH_INTERVAL = 100;
  234. static unsigned long lastRefreshTime = 0;
  235. if (millis() - lastRefreshTime >= REFRESH_INTERVAL)
  236. {
  237. lastRefreshTime += REFRESH_INTERVAL;
  238. render();
  239. }
  240. }
  241. /**
  242. render
  243. */
  244. void render()
  245. {
  246. // set default color
  247. uint8_t const color = at24c32.read(COLOR_ADDRESS);
  248. currentViewState->setColor(color);
  249. // set brightness
  250. uint8_t const brightness = at24c32.read(BRIGHTNESS_ADDRESS);
  251. pixels.setBrightness(brightness);
  252. // reset matrix (to black)
  253. for (int i = 0; i < MATRIX_SIZE; i++)
  254. {
  255. matrix[i] = 0x00;
  256. }
  257. // render matrix
  258. currentViewState->render(matrix, controlState);
  259. // set pixel
  260. for (int i = 0; i < MATRIX_SIZE; i++)
  261. {
  262. uint8_t const r = (matrix[i] >> 5) * 255 / 7;
  263. uint8_t const g = ((matrix[i] >> 2) & 0x07) * 255 / 7;
  264. uint8_t const b = (matrix[i] & 0x03) * 255 / 3;
  265. pixels.setPixelColor(i, pixels.Color(r, g, b));
  266. }
  267. pixels.show();
  268. }
  269. /**
  270. print current status VIEW STATE \t CONTROL STATE \t FREE RAM
  271. */
  272. void printStatus()
  273. {
  274. #ifdef DEBUG
  275. switch (viewState)
  276. {
  277. case ViewStates::TIME:
  278. Serial.print(F("TIME"));
  279. break;
  280. case ViewStates::SECONDS:
  281. Serial.print(F("SECS"));
  282. break;
  283. case ViewStates::TEMPERATURE:
  284. Serial.print(F("TEMP"));
  285. break;
  286. case ViewStates::DATE:
  287. Serial.print(F("DATE"));
  288. break;
  289. case ViewStates::TEXT:
  290. Serial.print(F("TEXT"));
  291. break;
  292. case ViewStates::LED_DEMO:
  293. Serial.print(F("LEDS"));
  294. break;
  295. default:
  296. Serial.print(F("TIME"));
  297. }
  298. Serial.print(F("\t"));
  299. switch (controlState)
  300. {
  301. case ControlStates::VIEW:
  302. Serial.print(F("VIEW "));
  303. break;
  304. case ControlStates::TIME_HOURS:
  305. Serial.print(F("HOURS"));
  306. break;
  307. case ControlStates::TIME_MINUTES:
  308. Serial.print(F("MINS "));
  309. break;
  310. case ControlStates::TIME_MODE:
  311. Serial.print(F("MODE "));
  312. break;
  313. case ControlStates::TIME_SECONDS:
  314. Serial.print(F("SECS "));
  315. break;
  316. case ControlStates::DATE_DATE:
  317. Serial.print(F("DATE "));
  318. break;
  319. case ControlStates::DATE_MONTH:
  320. Serial.print(F("MONTH"));
  321. break;
  322. case ControlStates::DATE_YEAR:
  323. Serial.print(F("YEAR "));
  324. break;
  325. case ControlStates::COLOR_R:
  326. Serial.print(F("COLOR_R"));
  327. break;
  328. case ControlStates::COLOR_G:
  329. Serial.print(F("COLOR_G"));
  330. break;
  331. case ControlStates::COLOR_B:
  332. Serial.print(F("COLOR_B"));
  333. break;
  334. case ControlStates::TEXT:
  335. Serial.print(F("TEXT "));
  336. break;
  337. default:
  338. Serial.print(F("VIEW "));
  339. }
  340. extern int __heap_start, *__brkval;
  341. int v;
  342. Serial.print(F("\tRAM: "));
  343. Serial.println((int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval));
  344. #endif
  345. }