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.

156 lines
4.3 KiB

  1. /*
  2. ENCODER MODULE
  3. Copyright (C) 2018-2019 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #if ENCODER_SUPPORT && (LIGHT_PROVIDER != LIGHT_PROVIDER_NONE)
  6. #include <Encoder.h>
  7. #include <vector>
  8. typedef struct {
  9. Encoder * encoder;
  10. unsigned char button_pin;
  11. unsigned char button_logic;
  12. unsigned char button_mode;
  13. unsigned char mode;
  14. unsigned char channel1; // default
  15. unsigned char channel2; // only if button defined and pressed
  16. } encoder_t;
  17. std::vector<encoder_t> _encoders;
  18. void _encoderConfigure() {
  19. // Clean previous encoders
  20. for (unsigned char i=0; i<_encoders.size(); i++) {
  21. free(_encoders[i].encoder);
  22. }
  23. _encoders.clear();
  24. // Load encoders
  25. #if (ENCODER1_PIN1 != GPIO_NONE) && (ENCODER1_PIN2 != GPIO_NONE)
  26. {
  27. _encoders.push_back({
  28. new Encoder(ENCODER1_PIN1, ENCODER1_PIN2),
  29. ENCODER1_BUTTON_PIN, ENCODER1_BUTTON_LOGIC, ENCODER1_BUTTON_MODE, ENCODER1_MODE,
  30. ENCODER1_CHANNEL1, ENCODER1_CHANNEL2
  31. });
  32. }
  33. #endif
  34. #if (ENCODER2_PIN1 != GPIO_NONE) && (ENCODER2_PIN2 != GPIO_NONE)
  35. {
  36. _encoders.push_back({
  37. new Encoder(ENCODER2_PIN1, ENCODER2_PIN2),
  38. ENCODER2_BUTTON_PIN, ENCODER2_BUTTON_LOGIC, ENCODER2_BUTTON_MODE, ENCODER2_MODE,
  39. ENCODER2_CHANNEL1, ENCODER2_CHANNEL2
  40. });
  41. }
  42. #endif
  43. #if (ENCODER3_PIN1 != GPIO_NONE) && (ENCODER3_PIN2 != GPIO_NONE)
  44. {
  45. _encoders.push_back({
  46. new Encoder(ENCODER3_PIN1, ENCODER3_PIN2),
  47. ENCODER3_BUTTON_PIN, ENCODER3_BUTTON_LOGIC, ENCODER3_BUTTON_MODE, ENCODER3_MODE,
  48. ENCODER3_CHANNEL1, ENCODER3_CHANNEL2
  49. });
  50. }
  51. #endif
  52. #if (ENCODER4_PIN1 != GPIO_NONE) && (ENCODER4_PIN2 != GPIO_NONE)
  53. {
  54. _encoders.push_back({
  55. new Encoder(ENCODER4_PIN1, ENCODER4_PIN2),
  56. ENCODER4_BUTTON_PIN, ENCODER4_BUTTON_LOGIC, ENCODER4_BUTTON_MODE, ENCODER4_MODE,
  57. ENCODER4_CHANNEL1, ENCODER4_CHANNEL2
  58. });
  59. }
  60. #endif
  61. #if (ENCODER5_PIN1 != GPIO_NONE) && (ENCODER5_PIN2 != GPIO_NONE)
  62. {
  63. _encoders.push_back({
  64. new Encoder(ENCODER5_PIN1, ENCODER5_PIN2),
  65. ENCODER5_BUTTON_PIN, ENCODER5_BUTTON_LOGIC, ENCODER5_BUTTON_MODE, ENCODER5_MODE,
  66. ENCODER5_CHANNEL1, ENCODER5_CHANNEL2
  67. });
  68. }
  69. #endif
  70. // Setup encoders
  71. for (unsigned char i=0; i<_encoders.size(); i++) {
  72. if (GPIO_NONE != _encoders[i].button_pin) {
  73. pinMode(_encoders[i].button_pin, _encoders[i].button_mode);
  74. }
  75. }
  76. }
  77. void _encoderLoop() {
  78. // for each encoder
  79. for (unsigned char i=0; i<_encoders.size(); i++) {
  80. // get encoder
  81. encoder_t encoder = _encoders[i];
  82. // read encoder
  83. long delta = encoder.encoder->read();
  84. encoder.encoder->write(0);
  85. if (0 == delta) continue;
  86. DEBUG_MSG_P(PSTR("[ENCODER] Delta: %d\n"), delta);
  87. // action
  88. if (encoder.button_pin == GPIO_NONE) {
  89. // if there is no button, the encoder drives CHANNEL1
  90. lightChannelStep(encoder.channel1, delta);
  91. } else {
  92. // check if button is pressed
  93. bool pressed = (digitalRead(encoder.button_pin) != encoder.button_logic);
  94. if (ENCODER_MODE_CHANNEL == encoder.mode) {
  95. // the button controls what channel we are changing
  96. lightChannelStep(pressed ? encoder.channel2 : encoder.channel1, delta);
  97. } if (ENCODER_MODE_RATIO == encoder.mode) {
  98. // the button controls if we are changing the channel ratio or the overall brightness
  99. if (pressed) {
  100. lightChannelStep(encoder.channel1, delta);
  101. lightChannelStep(encoder.channel2, -delta);
  102. } else {
  103. lightBrightnessStep(delta);
  104. }
  105. }
  106. }
  107. lightUpdate(true, true);
  108. }
  109. }
  110. // -----------------------------------------------------------------------------
  111. void encoderSetup() {
  112. // Configure encoders
  113. _encoderConfigure();
  114. // Main callbacks
  115. espurnaRegisterLoop(_encoderLoop);
  116. espurnaRegisterReload(_encoderConfigure);
  117. DEBUG_MSG_P(PSTR("[ENCODER] Number of encoders: %u\n"), _encoders.size());
  118. }
  119. #endif // ENCODER_SUPPORT && (LIGHT_PROVIDER != LIGHT_PROVIDER_NONE)