Atm_out.cpp 8.0 KB

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