Atm_encoderInt.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #ifdef Encoder_h_
  2. #include "Atm_encoderInt.h"
  3. #include <limits.h>
  4. // Loosely based on https://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino (Oleg Mazurov)
  5. const char Atm_encoderInt::enc_states[16] = {0, (char)-1, 1, 0, 1, 0, 0, (char)-1, (char)-1, 0, 0, 1, 0, 1, (char)-1, 0};
  6. Atm_encoderInt& Atm_encoderInt::begin( int pin1, int pin2, int divider /* = 1 */ ) {
  7. // clang-format off
  8. const static state_t state_table[] PROGMEM = {
  9. /* ON_ENTER ON_LOOP ON_EXIT EVT_UP EVT_DOWN ELSE */
  10. /* IDLE */ -1, LP_IDLE, -1, UP, DOWN, -1,
  11. /* UP */ ENT_UP, -1, -1, -1, -1, IDLE,
  12. /* DOWN */ ENT_DOWN, -1, -1, -1, -1, IDLE,
  13. };
  14. // clang-format on
  15. Machine::begin( state_table, ELSE );
  16. this->pin1 = pin1;
  17. this->pin2 = pin2;
  18. this->divider = divider;
  19. encoder = new Encoder(pin1, pin2);
  20. // sendTimer.set(send_rate);
  21. // sendTimer.setFromNow(this, send_rate);
  22. // pinMode( pin1, INPUT );
  23. // pinMode( pin2, INPUT );
  24. // digitalWrite( pin1, HIGH );
  25. // digitalWrite( pin2, HIGH );
  26. min = INT_MIN;
  27. max = INT_MAX;
  28. value = 0;
  29. return *this;
  30. }
  31. int Atm_encoderInt::event( int id ) {
  32. switch ( id ) {
  33. case EVT_UP:
  34. return enc_direction == +1 && ( enc_counter % divider == 0 );
  35. case EVT_DOWN:
  36. return enc_direction == -1 && ( enc_counter % divider == 0 );
  37. }
  38. return 0;
  39. }
  40. void Atm_encoderInt::action( int id ) {
  41. int8_t enc_counter_prev = enc_counter;
  42. switch ( id ) {
  43. case LP_IDLE:
  44. // enc_bits = ( ( enc_bits << 2 ) | ( digitalRead( pin1 ) << 1 ) | ( digitalRead( pin2 ) ) ) & 0x0f;
  45. // enc_direction = enc_states[enc_bits];
  46. // if ( enc_direction != 0 ) {
  47. // enc_counter = enc_counter + enc_direction;
  48. // if ( ( enc_counter != 0 ) && ( enc_counter % divider == 0 ) ) {
  49. // if ( !count( enc_direction ) ) {
  50. // enc_direction = 0;
  51. // }
  52. // } // enc_bits = ( ( enc_bits << 2 ) | ( digitalRead( pin1 ) << 1 ) | ( digitalRead( pin2 ) ) ) & 0x0f;
  53. // enc_direction = enc_states[enc_bits];
  54. // if ( enc_direction != 0 ) {
  55. // enc_counter = enc_counter + enc_direction;
  56. // if ( ( enc_counter != 0 ) && ( enc_counter % divider == 0 ) ) {
  57. // if ( !count( enc_direction ) ) {
  58. // enc_direction = 0;
  59. // }
  60. // }
  61. // }
  62. // }
  63. enc_counter = encoder->read();
  64. enc_direction = enc_counter > enc_counter_prev ? 1 : -1;
  65. enc_direction = enc_counter == enc_counter_prev ? 0 : enc_direction;
  66. count(enc_direction);
  67. return;
  68. case ENT_UP:
  69. if(millis()-send_last > send_rate) {
  70. onup.push( state(), 1 );
  71. send_last = millis();
  72. }
  73. return;
  74. case ENT_DOWN:
  75. if(millis()-send_last > send_rate) {
  76. ondown.push( state(), 0 );
  77. send_last = millis();
  78. }
  79. return;
  80. }
  81. }
  82. Atm_encoderInt& Atm_encoderInt::range( int min, int max, bool wrap /* = false */ ) {
  83. if ( min > max ) {
  84. range_invert = true;
  85. this->min = max;
  86. this->max = min;
  87. } else {
  88. range_invert = false;
  89. this->min = min;
  90. this->max = max;
  91. }
  92. this->wrap = wrap;
  93. if ( value < min || value > max ) {
  94. value = min;
  95. }
  96. return *this;
  97. }
  98. Atm_encoderInt& Atm_encoderInt::set( int value ) {
  99. this->value = range_invert ? map( value, min, max, max, min ) : value;
  100. return *this;
  101. }
  102. Atm_encoderInt& Atm_encoderInt::onChange( Machine& machine, int event /* = 0 */ ) {
  103. onup.set( &machine, event );
  104. ondown.set( &machine, event );
  105. return *this;
  106. }
  107. Atm_encoderInt& Atm_encoderInt::onChange( atm_cb_push_t callback, int idx /* = 0 */ ) {
  108. onup.set( callback, idx );
  109. ondown.set( callback, idx );
  110. return *this;
  111. }
  112. Atm_encoderInt& Atm_encoderInt::onChange( bool status, Machine& machine, int event /* = 0 */ ) {
  113. if ( status ) {
  114. onup.set( &machine, event );
  115. } else {
  116. ondown.set( &machine, event );
  117. }
  118. return *this;
  119. }
  120. Atm_encoderInt& Atm_encoderInt::onChange( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
  121. if ( status ) {
  122. onup.set( callback, idx );
  123. } else {
  124. ondown.set( callback, idx );
  125. }
  126. return *this;
  127. }
  128. int Atm_encoderInt::state( void ) {
  129. return range_invert ? map( value, min, max, max, min ) : value;
  130. }
  131. bool Atm_encoderInt::count( int direction ) {
  132. if ( (long)value + direction > max ) {
  133. if ( wrap ) {
  134. value = min;
  135. } else {
  136. return false;
  137. }
  138. } else if ( (long)value + direction < min ) {
  139. if ( wrap ) {
  140. value = max;
  141. } else {
  142. return false;
  143. }
  144. } else {
  145. value += direction;
  146. }
  147. return true;
  148. }
  149. Atm_encoderInt& Atm_encoderInt::trace( Stream& stream ) {
  150. Machine::setTrace( &stream, atm_serial_debug::trace, "ENCODER\0EVT_UP\0EVT_DOWN\0ELSE\0IDLE\0UP\0DOWN" );
  151. return *this;
  152. }
  153. #endif