Fork of the espurna firmware for `mhsw` switches
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.

143 lines
4.0 KiB

  1. // -----------------------------------------------------------------------------
  2. // Event Counter Sensor
  3. // Copyright (C) 2017 by Xose Pérez <xose dot perez at gmail dot com>
  4. // -----------------------------------------------------------------------------
  5. #pragma once
  6. #include "Arduino.h"
  7. #include "BaseSensor.h"
  8. class EventSensor : public BaseSensor {
  9. public:
  10. // ---------------------------------------------------------------------
  11. // Public
  12. // ---------------------------------------------------------------------
  13. EventSensor(): BaseSensor() {
  14. _count = 1;
  15. }
  16. ~EventSensor() {
  17. detachInterrupt(_gpio);
  18. }
  19. // ---------------------------------------------------------------------
  20. void setGPIO(unsigned char gpio) {
  21. _gpio = gpio;
  22. }
  23. void setMode(unsigned char mode) {
  24. _mode = mode;
  25. }
  26. void setInterruptMode(unsigned char mode) {
  27. _interrupt_mode = mode;
  28. }
  29. void setDebounceTime(unsigned long debounce) {
  30. _debounce = debounce;
  31. }
  32. // ---------------------------------------------------------------------
  33. unsigned char getGPIO() {
  34. return _gpio;
  35. }
  36. unsigned char getMode() {
  37. return _mode;
  38. }
  39. unsigned char getInterruptMode() {
  40. return _interrupt_mode;
  41. }
  42. unsigned long getDebounceTime() {
  43. return _debounce;
  44. }
  45. // ---------------------------------------------------------------------
  46. // Sensors API
  47. // ---------------------------------------------------------------------
  48. // Initialization method, must be idempotent
  49. // Defined outside the class body
  50. void begin() {
  51. if (_interrupt_gpio != GPIO_NONE) detach(_interrupt_gpio);
  52. pinMode(_gpio, _mode);
  53. attach(this, _gpio, _interrupt_mode);
  54. }
  55. // Descriptive name of the sensor
  56. String description() {
  57. char buffer[20];
  58. snprintf(buffer, sizeof(buffer), "INTERRUPT @ GPIO%d", _gpio);
  59. return String(buffer);
  60. }
  61. // Descriptive name of the slot # index
  62. String slot(unsigned char index) {
  63. (void) index;
  64. return description();
  65. }
  66. // Type for slot # index
  67. magnitude_t type(unsigned char index) {
  68. _error = SENSOR_ERROR_OK;
  69. if (index == 0) return MAGNITUDE_EVENTS;
  70. _error = SENSOR_ERROR_OUT_OF_RANGE;
  71. return MAGNITUDE_NONE;
  72. }
  73. // Current value for slot # index
  74. double value(unsigned char index) {
  75. _error = SENSOR_ERROR_OK;
  76. if (index == 0) {
  77. double value = _events;
  78. _events = 0;
  79. return value;
  80. };
  81. _error = SENSOR_ERROR_OUT_OF_RANGE;
  82. return 0;
  83. }
  84. // Handle interrupt calls
  85. void handleInterrupt(unsigned char gpio) {
  86. (void) gpio;
  87. static unsigned long last = 0;
  88. if (millis() - last > _debounce) {
  89. _events = _events + 1;
  90. last = millis();
  91. }
  92. }
  93. // Interrupt attach callback
  94. void attached(unsigned char gpio) {
  95. BaseSensor::attached(gpio);
  96. _interrupt_gpio = gpio;
  97. }
  98. // Interrupt detach callback
  99. void detached(unsigned char gpio) {
  100. BaseSensor::detached(gpio);
  101. if (_interrupt_gpio == gpio) _interrupt_gpio = GPIO_NONE;
  102. }
  103. protected:
  104. // ---------------------------------------------------------------------
  105. // Protected
  106. // ---------------------------------------------------------------------
  107. volatile unsigned long _events = 0;
  108. unsigned long _debounce = EVENTS_DEBOUNCE;
  109. unsigned char _gpio;
  110. unsigned char _mode;
  111. unsigned char _interrupt_mode;
  112. unsigned char _interrupt_gpio = GPIO_NONE;
  113. };