Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.98 KB | None | 0 0
  1. #include "Arduino.h"
  2. #include <Wire.h>
  3. #include <EEPROM.h>
  4. #include "LiquidCrystal_I2C.h"
  5. #include "OneButton.h"
  6.  
  7.  
  8. // set the LCD address to 0x27 for a 20 chars 4 line display
  9. // Set the pins on the I2C chip used for LCD connections:
  10. // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
  11. // Alternately, some boards use 0x3F as the I2C Address
  12.  
  13. //#define LCD_I2C_ADDRESS 0x27
  14. #define LCD_I2C_ADDRESS 0x3F
  15.  
  16. #define PIN_ROTARY_CLK 2 // Used for generating interrupts using CLK signal
  17. #define PIN_ROTARY_DAT 3 // Used for reading DT signal
  18. #define PIN_ROTARY_SW 4 // Used for the Rotary push button switch
  19. #define PIN_LIGHT_GREEN 5 // Output pin for Green Light
  20. #define PIN_LIGHT_YELLOW 6 // Output pin for Yellow Light
  21. #define PIN_LIGHT_RED 7 // Output pin for Red Light
  22. #define PIN_MANUAL_BUTTON 14 // Pushbutton to change light in Manual Mode
  23.  
  24. #define LIGHT_NONE 0 // All Lights Off
  25. #define LIGHT_GREEN 1 // Green Light On
  26. #define LIGHT_YELLOW 2 // Yellow Light On
  27. #define LIGHT_RED 3 // Red Light On
  28.  
  29. #define TIME_LIM_INDEX_EEPROM_ADDRESS 0
  30.  
  31. LiquidCrystal_I2C lcd(LCD_I2C_ADDRESS, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
  32.  
  33. OneButton btnMan(PIN_MANUAL_BUTTON, HIGH); // Pushbutton for Manual Mode
  34. OneButton btnRot(PIN_ROTARY_SW, HIGH); // Rotary Select button
  35.  
  36. volatile int time_lim_index = 0;
  37.  
  38. unsigned long start_millis;
  39. int start_elapsed_sec;
  40. int elapsed_sec;
  41. int old_elapsed_sec;
  42.  
  43. int timer_running;
  44.  
  45.  
  46. int time_limits[13][2] = { { 0,0 },{ 1,2 },{ 2,3 },{ 3,5 },{ 4,6 },{ 5,7 },{ 6,8 },{ 7,9 },{ 8,10 },{ 10,12 },{ 10,14 },{ 12,15 },{ 15,20 } };
  47. const int time_limit_count = 13;
  48.  
  49. int min_min;
  50. int max_min;
  51. int min_sec;
  52. int max_sec;
  53. int mid_sec;
  54.  
  55. int manual_mode;
  56. int time_lim_changed;
  57. int manual_mode_light_select;
  58.  
  59. int rotary_disabled;
  60. int old_light_index;
  61.  
  62. void rotaryClick() {
  63.  
  64. static unsigned long lastInterruptTime = 0;
  65. unsigned long interruptTime = millis();
  66.  
  67. if (rotary_disabled) return;
  68.  
  69. // If interrupts come faster than 5ms, assume it's a bounce and ignore
  70. if (interruptTime - lastInterruptTime > 5) {
  71. if (digitalRead(PIN_ROTARY_DAT))
  72. rotaryDown();
  73. else
  74. rotaryUp();
  75. }
  76. lastInterruptTime = interruptTime;
  77. }
  78.  
  79.  
  80. void setup()
  81. {
  82. lcd.begin(16, 2);
  83. lcd.backlight();
  84.  
  85. pinMode(PIN_ROTARY_CLK, INPUT);
  86. pinMode(PIN_ROTARY_DAT, INPUT);
  87. pinMode(PIN_ROTARY_SW, INPUT);
  88. pinMode(PIN_MANUAL_BUTTON, INPUT_PULLUP);
  89.  
  90. pinMode(PIN_LIGHT_GREEN, OUTPUT);
  91. pinMode(PIN_LIGHT_YELLOW, OUTPUT);
  92. pinMode(PIN_LIGHT_RED, OUTPUT);
  93.  
  94. // Relay module takes IN=HIGH for Open and IN=LOW for Close
  95. digitalWrite(PIN_LIGHT_GREEN, HIGH);
  96. digitalWrite(PIN_LIGHT_YELLOW, HIGH);
  97. digitalWrite(PIN_LIGHT_RED, HIGH);
  98. old_light_index = LIGHT_NONE;
  99. manual_mode_light_select = LIGHT_NONE;
  100.  
  101. attachInterrupt(0, rotaryClick, FALLING);
  102.  
  103. btnMan.attachClick(&btnManClick);
  104. btnMan.setPressTicks(2000);
  105.  
  106. btnRot.attachClick(&btnRotClick);
  107. btnRot.attachLongPressStart(&btnRotLongPress);
  108. btnRot.setPressTicks(2000);
  109.  
  110. readSelectedTime();
  111. time_lim_changed = 1;
  112. refreshElapsedTime();
  113. rotary_disabled = 0;
  114. }
  115.  
  116. void lcdDebug(String s)
  117. {
  118. lcd.setCursor(0, 0);
  119. lcd.print(s);
  120. lcd.print(" ");
  121. delay(3000);
  122. }
  123.  
  124. void rotaryUp()
  125. {
  126. time_lim_index++;
  127. if (time_lim_index >= time_limit_count) time_lim_index = time_limit_count - 1;
  128. time_lim_changed = 1;
  129. }
  130.  
  131. void rotaryDown()
  132. {
  133. time_lim_index--;
  134. if (time_lim_index<0) time_lim_index = 0;
  135. time_lim_changed = 1;
  136. }
  137.  
  138.  
  139. void btnManClick()
  140. {
  141. if (timer_running && !manual_mode) return;
  142.  
  143. manual_mode_light_select++;
  144. if (manual_mode_light_select > LIGHT_RED)
  145. manual_mode_light_select = LIGHT_NONE;
  146. }
  147.  
  148. void btnRotClick()
  149. {
  150. startPressed();
  151. }
  152.  
  153. void btnRotLongPress()
  154. {
  155. resetPressed();
  156. }
  157.  
  158. void loop()
  159. {
  160. btnMan.tick();
  161. btnRot.tick();
  162.  
  163. normalLoop();
  164.  
  165. }
  166.  
  167.  
  168. void normalLoop()
  169. {
  170.  
  171. if (timer_running)
  172. elapsed_sec = start_elapsed_sec + ((millis() - start_millis) / 1000);
  173.  
  174. if (elapsed_sec != old_elapsed_sec)
  175. refreshElapsedTime();
  176. old_elapsed_sec = elapsed_sec;
  177.  
  178. if (time_lim_changed)
  179. {
  180. refreshTimeLim();
  181. writeSelectedTime();
  182. }
  183.  
  184. updateLights();
  185. delay(10);
  186.  
  187. }
  188.  
  189. void refreshElapsedTime() {
  190.  
  191. int mins;
  192. int sec;
  193.  
  194. lcd.setCursor(0, 1);
  195.  
  196. mins = elapsed_sec / 60;
  197. sec = elapsed_sec - (mins * 60);
  198.  
  199. if (!timer_running && elapsed_sec>0)
  200. lcd.print(F("STOP "));
  201. else
  202. lcd.print(F(" "));
  203.  
  204. lcd.print(mins);
  205. lcd.print(F(":"));
  206. if (sec<10) lcd.print(F("0"));
  207. lcd.print(sec);
  208. lcd.print(F(" "));
  209. }
  210.  
  211.  
  212. void startPressed()
  213. {
  214. if (timer_running)
  215. {
  216. timer_running = 0;
  217. start_elapsed_sec = elapsed_sec;
  218. }
  219. else
  220. {
  221. timer_running = 1;
  222. start_millis = millis();
  223. if (!manual_mode) manual_mode_light_select = LIGHT_NONE;
  224. }
  225. refreshElapsedTime();
  226. }
  227.  
  228. void resetPressed()
  229. {
  230. if (timer_running == 0)
  231. {
  232. elapsed_sec = 0;
  233. start_elapsed_sec = 0;
  234. }
  235. }
  236.  
  237. void writeSelectedTime()
  238. {
  239. eeprom_write_byte(TIME_LIM_INDEX_EEPROM_ADDRESS, (byte)time_lim_index);
  240. }
  241.  
  242. void readSelectedTime()
  243. {
  244. time_lim_index = eeprom_read_byte(TIME_LIM_INDEX_EEPROM_ADDRESS);
  245. if (time_lim_index<0) time_lim_index = 0;
  246. if (time_lim_index>time_limit_count - 1) time_lim_index = time_limit_count - 1;
  247. }
  248.  
  249. void refreshTimeLim()
  250. {
  251. min_min = time_limits[time_lim_index][0];
  252. max_min = time_limits[time_lim_index][1];
  253. min_sec = min_min * 60;
  254. max_sec = max_min * 60;
  255. mid_sec = (max_sec + min_sec) / 2;
  256.  
  257. if (time_lim_index == 0)
  258. manual_mode = 1;
  259. else
  260. manual_mode = 0;
  261.  
  262. timeLim2LCD();
  263. time_lim_changed = 0;
  264. }
  265.  
  266. void timeLim2LCD() {
  267.  
  268. lcd.setCursor(0, 0);
  269. if (manual_mode)
  270. {
  271. lcd.print(F(" Manual Mode "));
  272. }
  273. else
  274. {
  275. lcd.print(F("Time: "));
  276. lcd.print(min_min);
  277.  
  278. if (max_min >= 10)
  279. lcd.print(F("-"));
  280. else
  281. lcd.print(F(" to "));
  282.  
  283. lcd.print(max_min);
  284. lcd.print(F(" min "));
  285. }
  286. }
  287.  
  288. void updateLights()
  289. {
  290. int s;
  291.  
  292. s = elapsed_sec;
  293.  
  294. if (manual_mode || (!timer_running && s == 0))
  295. {
  296. setLightOn(manual_mode_light_select);
  297. }
  298. else
  299. {
  300. if (s<min_sec || s == 0) setLightOn(LIGHT_NONE);
  301. if (s >= min_sec && s<mid_sec) setLightOn(LIGHT_GREEN);
  302. if (s >= mid_sec && s<max_sec) setLightOn(LIGHT_YELLOW);
  303. if (s >= max_sec) setLightOn(LIGHT_RED);
  304. }
  305. }
  306.  
  307. void setLightOn(int light_index)
  308. {
  309.  
  310. if (light_index != old_light_index)
  311. {
  312. rotary_disabled = 1;
  313. delay(100);
  314. switch (light_index)
  315. {
  316. case LIGHT_NONE:
  317. setOutput(PIN_LIGHT_GREEN, 0);
  318. setOutput(PIN_LIGHT_YELLOW, 0);
  319. setOutput(PIN_LIGHT_RED, 0);
  320. break;
  321. case LIGHT_GREEN:
  322. setOutput(PIN_LIGHT_GREEN, 1);
  323. setOutput(PIN_LIGHT_YELLOW, 0);
  324. setOutput(PIN_LIGHT_RED, 0);
  325. break;
  326. case LIGHT_YELLOW:
  327. setOutput(PIN_LIGHT_GREEN, 0);
  328. setOutput(PIN_LIGHT_YELLOW, 1);
  329. setOutput(PIN_LIGHT_RED, 0);
  330. break;
  331. case LIGHT_RED:
  332. setOutput(PIN_LIGHT_GREEN, 0);
  333. setOutput(PIN_LIGHT_YELLOW, 0);
  334. setOutput(PIN_LIGHT_RED, 1);
  335. break;
  336. }
  337.  
  338. delay(100);
  339. rotary_disabled = 0;
  340. old_light_index = light_index;
  341. }
  342. }
  343.  
  344. void setOutput(int pin, int state)
  345. {
  346. // Relay module requires a Ground to Energize relay and +5V to de=energize
  347. // Thus turning Light On, requires a LOW on the output
  348.  
  349. if (state>0)
  350. digitalWrite(pin, LOW);
  351. else
  352. digitalWrite(pin, HIGH);
  353. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement