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.

Keymatrix.cpp 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Copyright (c) 2021 Thomas Buck <thomas@xythobuz.de>
  3. *
  4. * This file is part of Giess-o-mat.
  5. *
  6. * Giess-o-mat is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Giess-o-mat is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Giess-o-mat. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. #include <Arduino.h>
  20. #include "Keymatrix.h"
  21. #ifdef FUNCTION_UI
  22. //#define DEBUG_PRINT_MATRIX_STATE
  23. #ifdef DEBUG_PRINT_MATRIX_STATE
  24. #include "DebugLog.h"
  25. #endif // DEBUG_PRINT_MATRIX_STATE
  26. Keymatrix::Event::Event(EventType _type, int _row, int _col) {
  27. type = _type;
  28. row = _row;
  29. col = _col;
  30. }
  31. Keymatrix::Event::EventType Keymatrix::Event::getType(void) {
  32. return type;
  33. }
  34. int Keymatrix::Event::getRow(void) {
  35. return row;
  36. }
  37. int Keymatrix::Event::getCol(void) {
  38. return col;
  39. }
  40. // -1 is *, -2 is #, or digits 0-9
  41. int Keymatrix::Event::getNum(void) {
  42. if (row == 3) {
  43. switch (col) {
  44. case 0:
  45. return -1; // *
  46. case 2:
  47. return -2; // #
  48. default:
  49. return 0;
  50. }
  51. } else {
  52. return (row * 3) + col + 1;
  53. }
  54. }
  55. Keymatrix::Keymatrix(int _rows, int _cols) {
  56. debounce = default_debounce;
  57. last_scan_time = 0;
  58. rows = _rows;
  59. cols = _cols;
  60. pins = new int[rows + cols];
  61. lastPressed = new bool[rows * cols];
  62. lastState = new bool[rows * cols];
  63. for (int i = 0; i < (rows * cols); i++) {
  64. lastPressed[i] = false;
  65. lastState[i] = false;
  66. }
  67. }
  68. Keymatrix::~Keymatrix(void) {
  69. delete pins;
  70. delete lastPressed;
  71. delete lastState;
  72. }
  73. // first rows, then cols
  74. void Keymatrix::setPins(int _pins[]) {
  75. for (int i = 0; i < (rows + cols); i++) {
  76. pins[i] = _pins[i];
  77. // rows as outputs, cols as inputs
  78. if (i < rows) {
  79. //pinMode(pins[i], OUTPUT);
  80. pinMode(pins[i], INPUT);
  81. } else {
  82. pinMode(pins[i], INPUT_PULLUP);
  83. }
  84. }
  85. }
  86. void Keymatrix::setDebounce(unsigned long ms) {
  87. debounce = ms;
  88. }
  89. void Keymatrix::scan(void) {
  90. // only continue when enough time has passed
  91. unsigned long current_time = millis();
  92. if (current_time < (last_scan_time + debounce)) {
  93. return;
  94. }
  95. last_scan_time = current_time;
  96. // disable all rows
  97. for (int r = 0; r < rows; r++) {
  98. //digitalWrite(pins[r], HIGH);
  99. pinMode(pins[r], INPUT);
  100. }
  101. int buttons = rows * cols;
  102. bool pressed[buttons];
  103. // go through all rows
  104. for (int r = 0; r < rows; r++) {
  105. // enable current row
  106. pinMode(pins[r], OUTPUT);
  107. digitalWrite(pins[r], LOW);
  108. // read out all columns
  109. for (int c = 0; c < cols; c++) {
  110. int v = digitalRead(pins[rows + c]);
  111. pressed[(r * cols) + c] = (v == LOW);
  112. }
  113. // disable current row
  114. //digitalWrite(pins[r], HIGH);
  115. pinMode(pins[r], INPUT);
  116. }
  117. #ifdef DEBUG_PRINT_MATRIX_STATE
  118. for (int i = 0; i < buttons; i++) {
  119. debug.print(pressed[i] ? "1" : "0");
  120. if (i < (buttons - 1)) {
  121. debug.print(" ");
  122. } else {
  123. debug.println();
  124. }
  125. }
  126. #endif // DEBUG_PRINT_MATRIX_STATE
  127. for (int i = 0; i < buttons; i++) {
  128. // debounce - compare to previous state
  129. if ((lastPressed[i] == pressed[i]) && (pressed[i] != lastState[i])) {
  130. lastState[i] = pressed[i];
  131. int c = i % cols;
  132. int r = i / cols;
  133. Event::EventType et = (pressed[i]) ? Event::button_down : Event::button_up;
  134. events.push(new Event(et, r, c));
  135. }
  136. // save current state for next time
  137. lastPressed[i] = pressed[i];
  138. }
  139. }
  140. bool Keymatrix::hasEvent(void) {
  141. return !events.isEmpty();
  142. }
  143. Keymatrix::Event Keymatrix::getEvent(void) {
  144. if (hasEvent()) {
  145. Event *e = events.shift();
  146. Event e_copy = *e;
  147. delete e;
  148. return e_copy;
  149. } else {
  150. return Keymatrix::Event(Event::no_event, -1, -1);
  151. }
  152. }
  153. #endif // FUNCTION_UI