DIY fertilizer mixer and plant watering machine https://www.xythobuz.de/giessomat.html
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.

Statemachine.cpp 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #include <Arduino.h>
  2. #include "Statemachine.h"
  3. Statemachine::DigitBuffer::DigitBuffer(int _size) {
  4. size = _size;
  5. pos = 0;
  6. digits = new int[size];
  7. }
  8. Statemachine::DigitBuffer::~DigitBuffer() {
  9. delete digits;
  10. }
  11. bool Statemachine::DigitBuffer::spaceLeft(void) {
  12. return (pos < size);
  13. }
  14. bool Statemachine::DigitBuffer::hasDigits(void) {
  15. return (pos > 0);
  16. }
  17. int Statemachine::DigitBuffer::countDigits(void) {
  18. return pos;
  19. }
  20. void Statemachine::DigitBuffer::addDigit(int d) {
  21. if (spaceLeft()) {
  22. digits[pos] = d;
  23. pos++;
  24. }
  25. }
  26. void Statemachine::DigitBuffer::removeDigit(void) {
  27. if (hasDigits()) {
  28. pos--;
  29. }
  30. }
  31. void Statemachine::DigitBuffer::clear(void) {
  32. pos = 0;
  33. }
  34. uint32_t Statemachine::DigitBuffer::getNumber(void) {
  35. uint32_t fact = 1;
  36. uint32_t sum = 0;
  37. for (int i = (pos - 1); i >= 0; i--) {
  38. sum += digits[i] * fact;
  39. fact *= 10;
  40. }
  41. return sum;
  42. }
  43. Statemachine::Statemachine(print_fn _print, backspace_fn _backspace)
  44. : db(7) {
  45. state = init;
  46. print = _print;
  47. backspace = _backspace;
  48. selected_id = 0;
  49. selected_time = 0;
  50. }
  51. void Statemachine::begin(void) {
  52. switch_to(init);
  53. }
  54. void Statemachine::input(int n) {
  55. if (state == init) {
  56. switch_to(menu);
  57. } else if (state == menu) {
  58. if (n == 1) {
  59. switch_to(menu_auto);
  60. } else if (n == 2) {
  61. switch_to(menu_pumps);
  62. } else if (n == 3) {
  63. switch_to(menu_valves);
  64. } else if ((n == -1) || (n == -2)) {
  65. switch_to(init);
  66. }
  67. } else if (state == menu_auto) {
  68. if ((n == -1) || (n == -2)) {
  69. switch_to(menu);
  70. } else if (n == 1) {
  71. // water only
  72. } else if (n == 2) {
  73. // with fertilizer
  74. }
  75. } else if (state == menu_auto_mode) {
  76. switch_to(menu);
  77. } else if (state == menu_auto_go) {
  78. switch_to(menu);
  79. } else if (state == menu_auto_done) {
  80. switch_to(menu);
  81. } else if (state == menu_pumps) {
  82. if (n == -1) {
  83. if (db.hasDigits()) {
  84. backspace();
  85. db.removeDigit();
  86. } else {
  87. switch_to(menu);
  88. }
  89. } else if (n == -2) {
  90. if (!db.hasDigits()) {
  91. return;
  92. }
  93. selected_id = number_input();
  94. // TODO validate
  95. switch_to(menu_pumps_time);
  96. } else {
  97. if (db.spaceLeft()) {
  98. db.addDigit(n);
  99. } else {
  100. backspace();
  101. }
  102. }
  103. } else if (state == menu_pumps_time) {
  104. if (n == -1) {
  105. if (db.hasDigits()) {
  106. backspace();
  107. db.removeDigit();
  108. } else {
  109. switch_to(menu_pumps);
  110. }
  111. } else if (n == -2) {
  112. if (!db.hasDigits()) {
  113. return;
  114. }
  115. selected_time = number_input();
  116. // TODO validate
  117. switch_to(menu_pumps_go);
  118. } else {
  119. if (db.spaceLeft()) {
  120. db.addDigit(n);
  121. } else {
  122. backspace();
  123. }
  124. }
  125. } else if (state == menu_pumps_go) {
  126. switch_to(menu);
  127. } else if (state == menu_pumps_running) {
  128. switch_to(menu);
  129. } else if (state == menu_pumps_done) {
  130. switch_to(menu);
  131. } else if (state == menu_valves) {
  132. if (n == -1) {
  133. if (db.hasDigits()) {
  134. backspace();
  135. db.removeDigit();
  136. } else {
  137. switch_to(menu);
  138. }
  139. } else if (n == -2) {
  140. if (!db.hasDigits()) {
  141. return;
  142. }
  143. selected_id = number_input();
  144. // TODO validate
  145. switch_to(menu_valves_time);
  146. } else {
  147. if (db.spaceLeft()) {
  148. db.addDigit(n);
  149. } else {
  150. backspace();
  151. }
  152. }
  153. } else if (state == menu_valves_time) {
  154. if (n == -1) {
  155. if (db.hasDigits()) {
  156. backspace();
  157. db.removeDigit();
  158. } else {
  159. switch_to(menu_valves);
  160. }
  161. } else if (n == -2) {
  162. if (!db.hasDigits()) {
  163. return;
  164. }
  165. selected_time = number_input();
  166. // TODO validate
  167. switch_to(menu_valves_go);
  168. } else {
  169. if (db.spaceLeft()) {
  170. db.addDigit(n);
  171. } else {
  172. backspace();
  173. }
  174. }
  175. } else if (state == menu_valves_go) {
  176. switch_to(menu);
  177. } else if (state == menu_valves_running) {
  178. switch_to(menu);
  179. } else if (state == menu_valves_done) {
  180. switch_to(menu);
  181. }
  182. }
  183. uint32_t Statemachine::number_input(void) {
  184. for (int i = 0; i < db.countDigits(); i++) {
  185. backspace();
  186. }
  187. uint32_t n = db.getNumber();
  188. db.clear();
  189. Serial.print("Whole number input: ");
  190. Serial.println(n);
  191. return n;
  192. }
  193. void Statemachine::act(void) {
  194. }
  195. void Statemachine::switch_to(States s) {
  196. state = s;
  197. if (s == init) {
  198. print("- Giess-o-mat V0.1 -",
  199. "Usage: Enter number",
  200. "* Delete prev. digit",
  201. "# Execute input num.",
  202. -1);
  203. } else if (s == menu) {
  204. print("------- Menu -------",
  205. "1: Automatic program",
  206. "2: Fertilizer pumps",
  207. "3: Outlet valves",
  208. -1);
  209. } else if (s == menu_auto) {
  210. print("------- Auto -------",
  211. "1: Water only",
  212. "2: With fertilizer",
  213. "",
  214. -1);
  215. } else if (s == menu_auto_mode) {
  216. print("",
  217. "",
  218. "",
  219. "",
  220. -1);
  221. } else if (s == menu_auto_go) {
  222. print("",
  223. "",
  224. "",
  225. "",
  226. -1);
  227. } else if (s == menu_auto_done) {
  228. print("",
  229. "",
  230. "",
  231. "",
  232. -1);
  233. } else if (s == menu_pumps) {
  234. print("------- Pump -------",
  235. "Please select pump",
  236. "(Input 1 to 3)",
  237. "Pump: ",
  238. 3);
  239. } else if (s == menu_pumps_time) {
  240. print("------ Pump X ------",
  241. "Please set runtime",
  242. "(Input in seconds)",
  243. "Runtime: ",
  244. 3);
  245. } else if (s == menu_pumps_go) {
  246. print("",
  247. "",
  248. "",
  249. "",
  250. -1);
  251. } else if (s == menu_pumps_running) {
  252. print("",
  253. "",
  254. "",
  255. "",
  256. -1);
  257. } else if (s == menu_pumps_done) {
  258. print("",
  259. "",
  260. "",
  261. "",
  262. -1);
  263. } else if (s == menu_valves) {
  264. print("------ Valves ------",
  265. "Please select valve",
  266. "(Input 1 to 5)",
  267. "Valve: ",
  268. 3);
  269. } else if (s == menu_valves_time) {
  270. print("----- Valve XX -----",
  271. "Please set runtime",
  272. "(Input in seconds)",
  273. "Runtime: ",
  274. 3);
  275. } else if (s == menu_valves_go) {
  276. print("",
  277. "",
  278. "",
  279. "",
  280. -1);
  281. } else if (s == menu_valves_running) {
  282. print("",
  283. "",
  284. "",
  285. "",
  286. -1);
  287. } else if (s == menu_valves_done) {
  288. print("",
  289. "",
  290. "",
  291. "",
  292. -1);
  293. }
  294. }