Atm_comparator.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "Atm_comparator.hpp"
  2. Atm_comparator& Atm_comparator::begin( int attached_pin, int samplerate /* = 50 */ ) {
  3. // clang-format off
  4. const static state_t state_table[] PROGMEM = {
  5. /* ON_ENTER ON_LOOP ON_EXIT EVT_TRIGGER EVT_TIMER ELSE */
  6. /* IDLE */ -1, -1, -1, -1, SAMPLE, -1,
  7. /* SAMPLE */ ENT_SAMPLE, -1, -1, SEND, -1, IDLE,
  8. /* SEND */ ENT_SEND, -1, -1, -1, -1, IDLE,
  9. };
  10. // clang-format on
  11. Machine::begin( state_table, ELSE );
  12. pin = attached_pin;
  13. timer.set( samplerate );
  14. bitmap_sample = 0;
  15. bitmap_previous = 0;
  16. skip_mode = 0;
  17. return *this;
  18. }
  19. int Atm_comparator::event( int id ) {
  20. switch ( id ) {
  21. case EVT_TRIGGER:
  22. if ( bitmap_diff ) {
  23. return 1;
  24. }
  25. return 0;
  26. case EVT_TIMER:
  27. return timer.expired( this );
  28. }
  29. return 0;
  30. }
  31. void Atm_comparator::action( int id ) {
  32. switch ( id ) {
  33. case ENT_SAMPLE:
  34. v_previous = v_sample;
  35. bitmap_previous = bitmap_sample;
  36. v_sample = sample();
  37. bitmap( v_sample );
  38. return;
  39. case ENT_SEND:
  40. int final_step = -1;
  41. if ( v_sample >= v_previous ) {
  42. for ( uint16_t i = 0; i < p_threshold_size; i++ ) {
  43. if ( ( bitmap_diff >> i ) & 1 ) {
  44. if ( skip_mode == 0 ) {
  45. onup.push( i, 1 );
  46. } else {
  47. final_step = i;
  48. }
  49. }
  50. }
  51. } else {
  52. for ( int i = p_threshold_size; i >= 0; i-- ) {
  53. if ( ( bitmap_diff >> i ) & 1 ) {
  54. if ( skip_mode == 0 ) {
  55. ondown.push( i, 0 );
  56. } else {
  57. final_step = i;
  58. }
  59. }
  60. }
  61. }
  62. if ( final_step > -1 ) {
  63. if ( v_sample >= v_previous ) {
  64. onup.push( final_step, 0 );
  65. } else {
  66. ondown.push( final_step, 0 );
  67. }
  68. }
  69. return;
  70. }
  71. }
  72. Atm_comparator& Atm_comparator::onChange( atm_cb_push_t callback, int idx /* = 0 */ ) {
  73. onup.set( callback, idx );
  74. ondown.set( callback, idx );
  75. return *this;
  76. }
  77. Atm_comparator& Atm_comparator::onChange( Machine& machine, int event /* = 0 */ ) {
  78. onup.set( &machine, event );
  79. ondown.set( &machine, event );
  80. return *this;
  81. }
  82. Atm_comparator& Atm_comparator::onChange( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
  83. if ( status ) {
  84. onup.set( callback, idx );
  85. } else {
  86. ondown.set( callback, idx );
  87. }
  88. return *this;
  89. }
  90. Atm_comparator& Atm_comparator::onChange( bool status, Machine& machine, int event /* = 0 */ ) {
  91. if ( status ) {
  92. onup.set( &machine, event );
  93. } else {
  94. ondown.set( &machine, event );
  95. }
  96. return *this;
  97. }
  98. Atm_comparator& Atm_comparator::skip() {
  99. skip_mode = 1;
  100. return *this;
  101. }
  102. int Atm_comparator::read_sample() {
  103. return analogRead( pin );
  104. }
  105. int Atm_comparator::avg() {
  106. uint16_t v = read_sample();
  107. avg_buf_total = avg_buf_total + v - avg_buf[avg_buf_head];
  108. avg_buf[avg_buf_head] = v;
  109. if ( avg_buf_head + 1 >= avg_buf_size ) {
  110. avg_buf_head = 0;
  111. } else {
  112. avg_buf_head++;
  113. }
  114. return avg_buf_total / avg_buf_size;
  115. }
  116. int Atm_comparator::sample() {
  117. return avg_buf_size > 0 ? avg() : read_sample();
  118. }
  119. int Atm_comparator::state( void ) {
  120. return v_sample;
  121. }
  122. Atm_comparator& Atm_comparator::threshold( uint16_t* v, uint16_t size, bool catchUp /* = false */ ) {
  123. p_threshold = v;
  124. p_threshold_size = size / sizeof( uint16_t );
  125. if ( !catchUp ) {
  126. v_sample = sample();
  127. bitmap( v_sample );
  128. v_previous = v_sample;
  129. bitmap_previous = bitmap_sample;
  130. }
  131. return *this;
  132. }
  133. Atm_comparator& Atm_comparator::average( uint16_t* v, uint16_t size ) {
  134. avg_buf = v;
  135. avg_buf_size = size / sizeof( uint16_t );
  136. avg_buf_head = 0;
  137. avg_buf_total = 0;
  138. for ( uint16_t i = 0; i < avg_buf_size; i++ ) {
  139. avg_buf[i] = read_sample();
  140. avg_buf_total += avg_buf[i];
  141. }
  142. return *this;
  143. }
  144. Atm_comparator& Atm_comparator::bitmap( uint16_t v ) {
  145. bitmap_sample = 0;
  146. for ( uint8_t i = 0; i < p_threshold_size; i++ ) {
  147. if ( v >= p_threshold[i] ) bitmap_sample |= ( 1 << i );
  148. }
  149. bitmap_diff = bitmap_sample ^ bitmap_previous;
  150. return *this;
  151. }
  152. Atm_comparator& Atm_comparator::trace( Stream& stream ) {
  153. setTrace( &stream, atm_serial_debug::trace,
  154. "EVT_TRIGGER\0EVT_TIMER\0ELSE\0"
  155. "IDLE\0SAMPLE\0SEND" );
  156. return *this;
  157. }