Atm_out.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #include "Atm_out.h"
  2. Atm_out& Atm_out::begin( int attached_pin, bool activeLow,
  3. EthernetUDP& udpRef, OSCBundle& bndl, const char* address ) {
  4. // clang-format off
  5. static const state_t state_table[] PROGMEM = {
  6. /* ON_ENTER ON_LOOP ON_EXIT EVT_ON_TIMER EVT_OFF_TIMER EVT_WT_TIMER EVT_COUNTER EVT_ON EVT_OFF EVT_BLINK EVT_TOGGLE EVT_TOGGLE_BLINK ELSE */
  7. /* IDLE */ ENT_INIT, ATM_SLEEP, -1, -1, -1, -1, -1, WT_ON, -1, WT_START, ON, WT_START, -1, // LED off
  8. /* ON */ ENT_ON, ATM_SLEEP, -1, -1, -1, -1, -1, -1, OFF, WT_START, OFF, OFF, -1, // LED on
  9. /* START */ ENT_ON, -1, -1, BLINK_OFF, -1, -1, -1, WT_ON, OFF, -1, OFF, OFF, -1, // Start blinking
  10. /* BLINK_OFF */ ENT_OFF, -1, -1, -1, LOOP, -1, -1, WT_ON, OFF, -1, OFF, OFF, -1,
  11. /* LOOP */ -1, -1, -1, -1, -1, -1, DONE, WT_ON, OFF, -1, OFF, OFF, START,
  12. /* DONE */ -1, -1, EXT_CHAIN, -1, OFF, -1, -1, WT_ON, OFF, WT_START, OFF, OFF, -1, // Wait after last blink
  13. /* OFF */ ENT_OFF, -1, -1, -1, -1, -1, -1, WT_ON, OFF, WT_START, -1, -1, IDLE, // All off -> IDLE
  14. /* WT_ON */ -1, -1, -1, -1, -1, ON, -1, WT_ON, OFF, WT_START, -1, -1, -1, // LEAD for ON
  15. /* WT_START */ -1, -1, -1, -1, -1, START, -1, WT_ON, OFF, WT_START, -1, -1, -1, // LEAD for BLINK
  16. };
  17. // clang-format on
  18. Machine::begin( state_table, ELSE );
  19. pin = attached_pin;
  20. this->activeLow = activeLow;
  21. level = 255;
  22. toLow = 0;
  23. toHigh = 255;
  24. wrap = false;
  25. pinMode( pin, OUTPUT );
  26. digitalWrite( pin, activeLow ? HIGH : LOW );
  27. on_timer.set( 500 );
  28. off_timer.set( 500 );
  29. pwm( 512, 1 );
  30. lead_timer.set( 0 );
  31. repeat_count = ATM_COUNTER_OFF;
  32. counter.set( repeat_count );
  33. while ( state() != 0 ) cycle();
  34. _adress = address;
  35. this->_udpRef = &udpRef;
  36. this->_bndl = &bndl ;
  37. return *this;
  38. }
  39. Atm_out& Atm_out::pwm( uint16_t width, float freq ) {
  40. if ( freq > -1 ) {
  41. this->freq = freq;
  42. } else {
  43. freq = this->freq;
  44. }
  45. this->width = width;
  46. float cycle_width = 1000 / freq;
  47. on_timer.set( cycle_width / 1024 * this->width );
  48. off_timer.set( cycle_width / 1024 * ( 1024 - this->width ) );
  49. return *this;
  50. }
  51. Atm_out& Atm_out::frequency( float freq ) {
  52. this->freq = freq;
  53. float cycle_width = 1000 / freq;
  54. on_timer.set( cycle_width / 1024 * this->width );
  55. off_timer.set( cycle_width / 1024 * ( 1024 - this->width ) );
  56. return *this;
  57. }
  58. int Atm_out::event( int id ) {
  59. switch ( id ) {
  60. case EVT_ON_TIMER:
  61. return on_timer.expired( this );
  62. case EVT_OFF_TIMER:
  63. return off_timer.expired( this );
  64. case EVT_WT_TIMER:
  65. return lead_timer.expired( this );
  66. case EVT_COUNTER:
  67. return counter.expired();
  68. }
  69. return 0;
  70. }
  71. void Atm_out::action( int id ) {
  72. switch ( id ) {
  73. case ENT_INIT:
  74. counter.set( repeat_count );
  75. return;
  76. case ENT_ON:
  77. if ( on_timer.value > 0 ) { // Never turn if on_timer is zero (duty cycle 0 must be dark)
  78. if ( activeLow ) {
  79. digitalWrite( pin, LOW );
  80. } else {
  81. if ( level == toHigh ) {
  82. digitalWrite( pin, HIGH );
  83. } else {
  84. analogWrite( pin, mapLevel( level ) );
  85. }
  86. }
  87. }
  88. return;
  89. case ENT_OFF:
  90. counter.decrement();
  91. if ( !activeLow ) {
  92. digitalWrite( pin, LOW );
  93. } else {
  94. if ( level == toHigh ) {
  95. digitalWrite( pin, HIGH );
  96. } else {
  97. analogWrite( pin, mapLevel( level ) );
  98. }
  99. }
  100. return;
  101. case EXT_CHAIN:
  102. onfinish.push( 0 );
  103. return;
  104. }
  105. }
  106. int Atm_out::mapLevel( int level ) {
  107. if ( levelMapSize ) {
  108. return levelMap[level];
  109. } else {
  110. return map( level, toLow, toHigh, 0, 255 );
  111. }
  112. }
  113. Atm_out& Atm_out::on( void ) {
  114. trigger( EVT_ON );
  115. return *this;
  116. }
  117. Atm_out& Atm_out::off( void ) {
  118. trigger( EVT_OFF );
  119. return *this;
  120. }
  121. Atm_out& Atm_out::toggle( void ) {
  122. trigger( EVT_TOGGLE );
  123. return *this;
  124. }
  125. Atm_out& Atm_out::toggleBlink( void ) {
  126. trigger( EVT_TOGGLE_BLINK );
  127. return *this;
  128. }
  129. Atm_out& Atm_out::start( void ) {
  130. trigger( EVT_BLINK );
  131. return *this;
  132. }
  133. Atm_out& Atm_out::onFinish( Machine& machine, int event /* = 0 */ ) {
  134. onfinish.set( &machine, event );
  135. return *this;
  136. }
  137. Atm_out& Atm_out::onFinish( atm_cb_push_t callback, int idx /* = 0 */ ) {
  138. onfinish.set( callback, idx );
  139. return *this;
  140. }
  141. Atm_out& Atm_out::blink( uint32_t duration, uint32_t pause_duration, uint16_t repeat_count /* = ATM_COUNTER_OFF */ ) {
  142. blink( duration ); // Time in which led is fully on
  143. pause( pause_duration );
  144. repeat( repeat_count );
  145. return *this;
  146. }
  147. Atm_out& Atm_out::blink( uint32_t duration ) {
  148. on_timer.set( duration ); // Time in which led is fully on
  149. return *this;
  150. }
  151. Atm_out& Atm_out::blink( void ) {
  152. trigger( EVT_BLINK );
  153. return *this;
  154. }
  155. Atm_out& Atm_out::range( int toLow, int toHigh, bool wrap /* = false */ ) {
  156. this->toLow = toLow;
  157. this->toHigh = toHigh;
  158. this->wrap = wrap;
  159. level = toHigh;
  160. return *this;
  161. }
  162. Atm_out& Atm_out::levels( unsigned char* map, int mapsize, bool wrap /* = false */ ) {
  163. this->levelMap = map;
  164. levelMapSize = mapsize;
  165. range( 0, mapsize - 1, wrap );
  166. return *this;
  167. }
  168. Atm_out& Atm_out::pause( uint32_t duration ) { // Time in which led is fully off
  169. off_timer.set( duration ? duration : 1 ); // Make sure off_timer is never 0 (work around)
  170. return *this;
  171. }
  172. Atm_out& Atm_out::fade( int fade ) {
  173. return *this;
  174. } // Dummy for method compatibility with Atm_fade
  175. Atm_out& Atm_out::lead( uint32_t ms ) {
  176. lead_timer.set( ms );
  177. return *this;
  178. }
  179. Atm_out& Atm_out::repeat( uint16_t repeat ) {
  180. counter.set( repeat_count = repeat );
  181. return *this;
  182. }
  183. int Atm_out::brightness( int level /* = -1 */ ) {
  184. if ( level > -1 ) {
  185. this->level = level;
  186. if ( current == ON || current == START ) {
  187. analogWrite( pin, mapLevel( level ) );
  188. }
  189. }
  190. return this->level;
  191. }
  192. int Atm_out::brighten( int v ) {
  193. if ( abs( v ) == 1 ) {
  194. int br = (int)this->level + v;
  195. if ( br > toHigh )
  196. br = wrap ? toLow : toHigh;
  197. if ( br < toLow )
  198. br = wrap ? toHigh : toLow;
  199. brightness( br );
  200. }
  201. return this->level;
  202. }
  203. Atm_out& Atm_out::trigger( int event ) {
  204. if ( event > ELSE ) {
  205. brighten( event == EVT_BRUP ? 1 : -1 );
  206. } else {
  207. Machine::trigger( event );
  208. }
  209. return *this;
  210. }
  211. Atm_out& Atm_out::onOSC(OSCMessage& msg ){
  212. Serial.println("OSC");
  213. int patternOffset = msg.match(_adress) ;
  214. if(patternOffset){
  215. if(msg.fullMatch("/on", patternOffset)){trigger(EVT_ON);}
  216. if(msg.fullMatch("/off", patternOffset)){trigger(EVT_OFF);}
  217. if(msg.fullMatch("/toggle", patternOffset)){trigger(EVT_TOGGLE);}
  218. if(msg.fullMatch("/blink", patternOffset)){trigger(EVT_BLINK);}
  219. if(msg.fullMatch("/brightness", patternOffset)){brightness(msg.getInt(0));}
  220. return *this;
  221. }
  222. }
  223. Atm_out& Atm_out::trace( Stream& stream ) {
  224. setTrace( &stream, atm_serial_debug::trace,
  225. "LED\0EVT_ON_TIMER\0EVT_OFF_TIMER\0EVT_WT_TIMER\0EVT_COUNTER\0EVT_ON\0EVT_OFF\0EVT_"
  226. "BLINK\0EVT_TOGGLE\0EVT_TOGGLE_BLINK\0ELSE\0"
  227. "IDLE\0ON\0START\0BLINK_OFF\0LOOP\0DONE\0OFF\0WT_ON\0WT_START" );
  228. return *this;
  229. }