ESP8266 Treppenlichtsteuerung mit OTA zum Firmware Upload
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.

treppe.cpp 8.2KB

3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include "treppe.h"
  2. uint8_t Treppe::softstart_led(uint8_t led, uint16_t startval, uint16_t stopval)
  3. {
  4. /*
  5. softstart task
  6. - get's called at regular intervals (1ms at the moment)
  7. - dimms single led (0 - 15, PCA9685 outputs) with linear intervals vom startval to stopval
  8. - calculates pwm steps depending on startval, stopval and timeinterval
  9. - -> results in constanst speed
  10. - returns 1 if led dimming is running
  11. - returns 0 if led dimming is finished
  12. */
  13. static uint8_t lastled = 255;
  14. static float current_pwm = 0;
  15. static float stepsize = 1.0;
  16. if (led != lastled)
  17. {
  18. pwmController.setChannelPWM(led, (uint16_t)startval);
  19. lastled = led;
  20. current_pwm = startval;
  21. stepsize = INT_TIME * abs(stopval - startval) / (float)time_per_stair; // only valid at 1ms function call interval
  22. return 1;
  23. }
  24. if (startval > stopval)
  25. {
  26. current_pwm -= stepsize;
  27. }
  28. else
  29. {
  30. current_pwm += stepsize;
  31. }
  32. // Serial.println((uint16_t)current_pwm);
  33. pwmController.setChannelPWM(led, (uint16_t)current_pwm);
  34. if (current_pwm > stopval - stepsize && current_pwm < stopval + stepsize)
  35. {
  36. if (stopval == 0)
  37. pwmController.setChannelPWM(led, 0);
  38. return 0;
  39. }
  40. return 1;
  41. }
  42. void Treppe::ledsequence()
  43. {
  44. static int8_t led = 0;
  45. static uint16_t brightness = 0;
  46. static uint16_t lastbrightness = 0;
  47. static uint16_t status = 0;
  48. uint16_t status_build = 0;
  49. status_build |= direction << 8;
  50. status_build |= state;
  51. if (status_build != status)
  52. { // check if any parameter changed
  53. finish = 0; // set state unfinished -> start action
  54. if (direction)
  55. led = 0; // reset led counter depending of direction
  56. else
  57. led = stairs - 1;
  58. if (state)
  59. {
  60. brightness = active_brightness; // set brightness value depending of on/off
  61. lastbrightness = idle_brightness;
  62. }
  63. else
  64. {
  65. brightness = idle_brightness;
  66. lastbrightness = active_brightness;
  67. }
  68. status = status_build; // set parameter memory
  69. Serial.printf("----Status Changed! onoff: %d, dir: %d\n", state, direction);
  70. }
  71. if (!finish)
  72. { // finish == 0 -> action pending
  73. if (!softstart_led(led, lastbrightness, brightness))
  74. {
  75. Serial.printf("one LED finished: led: %d, last: %d, curr %d\n",
  76. led, lastbrightness, brightness);
  77. if (direction)
  78. {
  79. led++;
  80. if (led >= stairs)
  81. finish = 1;
  82. }
  83. else
  84. {
  85. led--;
  86. if (led < 0)
  87. finish = 1;
  88. }
  89. }
  90. }
  91. }
  92. void Treppe::rampe()
  93. {
  94. if (state)
  95. {
  96. finish = 0;
  97. state = 0; // set parameter memory
  98. }
  99. if (!finish)
  100. {
  101. if (direction)
  102. { // aufwärts
  103. if (tick >= ticks_treppe - 1)
  104. { // ziel erreicht
  105. Serial.println("[Treppe] oberster tick !");
  106. finish = 1;
  107. return;
  108. }
  109. tick++; // eins hoch
  110. }
  111. else
  112. { // abwärts
  113. if (tick <= 0)
  114. { // ziel erreicht
  115. Serial.println("[Treppe] unterster tick !");
  116. finish = 1;
  117. return;
  118. }
  119. tick--; // eins runter
  120. }
  121. stufe = tick / ticks_pro_stufe;
  122. float new_pwm = 0.0;
  123. if (an_aus)
  124. {
  125. new_pwm = differenz_pwm_pro_tick * (tick - ticks_pro_stufe * stufe);
  126. new_pwm += idle_brightness;
  127. if (direction)
  128. new_pwm += differenz_pwm_pro_tick;
  129. }
  130. else
  131. {
  132. new_pwm = active_brightness - differenz_pwm_pro_tick * (tick - ticks_pro_stufe * stufe);
  133. new_pwm += idle_brightness;
  134. if (direction)
  135. new_pwm -= differenz_pwm_pro_tick;
  136. }
  137. pwmController.setChannelPWM(stufe, (uint16_t)new_pwm);
  138. Serial.printf("tick %04u, led %02d:%02u, pwm %4.1f\n",
  139. tick,
  140. stufe,
  141. (tick - ticks_pro_stufe * stufe),
  142. new_pwm);
  143. }
  144. }
  145. void Treppe::setup()
  146. {
  147. pwmController.resetDevices();
  148. // Deactive PCA9685 Phase Balancer due to LED Flickering
  149. // https://github.com/NachtRaveVL/PCA9685-Arduino/issues/15
  150. // see also lib/PCA9685-Arduin/PCA9685.h:204
  151. pwmController.init(PCA9685_PhaseBalancer_None);
  152. //pwmController.init(PCA9685_PhaseBalancer_Linear);
  153. pwmController.setPWMFrequency(100);
  154. pwmController.setAllChannelsPWM(idle_brightness);
  155. pinMode(A0, INPUT);
  156. pinMode(SENSOR_OBEN, INPUT);
  157. pinMode(SENSOR_UNTEN, INPUT);
  158. pinMode(OE, OUTPUT);
  159. digitalWrite(OE, 0);
  160. Serial.printf("differenz_pwm_pro_tick %f\n", differenz_pwm_pro_tick);
  161. Serial.println("Hello from Treppe");
  162. Serial.print("Treppe: initial parameters: stairs=");
  163. Serial.println(stairs);
  164. }
  165. void Treppe::print_state_on_change()
  166. {
  167. static FSMTreppeModelClass::ExtU_FSMTreppe_T last_in;
  168. static FSMTreppeModelClass::ExtY_FSMTreppe_T last_out;
  169. if (
  170. fsm_inputs.anim_beendet != last_in.anim_beendet ||
  171. fsm_inputs.sensor_oben != last_in.sensor_oben ||
  172. fsm_inputs.sensor_unten != last_in.sensor_unten ||
  173. fsm_outputs.dimmrichtung != last_out.dimmrichtung ||
  174. fsm_outputs.laufrichtung != last_out.laufrichtung ||
  175. fsm_outputs.status != last_out.status)
  176. {
  177. last_in.anim_beendet = fsm_inputs.anim_beendet;
  178. last_in.sensor_oben = fsm_inputs.sensor_oben;
  179. last_in.sensor_unten = fsm_inputs.sensor_unten;
  180. last_out.dimmrichtung = fsm_outputs.dimmrichtung;
  181. last_out.laufrichtung = fsm_outputs.laufrichtung;
  182. last_out.status = fsm_outputs.status;
  183. Serial.printf("FSM IN: s_u: %d, s_o: %d, beendet: %d =>",
  184. fsm_inputs.sensor_oben, fsm_inputs.sensor_unten, fsm_inputs.anim_beendet);
  185. Serial.print(" step => ");
  186. Serial.printf("OUT: LR: %d DR: %d ST: %d\n",
  187. fsm_outputs.laufrichtung, fsm_outputs.dimmrichtung, fsm_outputs.status);
  188. }
  189. }
  190. void Treppe::task()
  191. {
  192. //Serial.printf("LDR: %f\n", ((float)analogRead(A0))/1023.*3.68);
  193. if (finish)
  194. {
  195. direction = switch_direction;
  196. state = switch_state;
  197. }
  198. fsm_inputs.ldr_schwelle = true;
  199. fsm_inputs.sensor_oben = read_sensor(SENSOR_OBEN);
  200. fsm_inputs.sensor_unten = read_sensor(SENSOR_UNTEN);
  201. fsm_inputs.anim_beendet = static_cast<bool>(finish);
  202. FSMTreppe_Obj.setExternalInputs(&fsm_inputs);
  203. FSMTreppe_Obj.step();
  204. fsm_outputs = FSMTreppe_Obj.getExternalOutputs();
  205. print_state_on_change();
  206. direction = fsm_outputs.laufrichtung;
  207. state = fsm_outputs.dimmrichtung;
  208. // setTick(ticks_treppe);
  209. // setAnAus(1);
  210. // setDirection(0);
  211. // setState(0);
  212. ledsequence();
  213. }
  214. uint16_t Treppe::setIdle(uint16_t _idle_brightness)
  215. {
  216. idle_brightness = _idle_brightness;
  217. Serial.println("Treppe: idle brightness changed!");
  218. return idle_brightness;
  219. }
  220. uint16_t Treppe::setActive(uint16_t _active_brightness)
  221. {
  222. active_brightness = _active_brightness;
  223. Serial.println("Treppe: active brightness changed!");
  224. return active_brightness;
  225. }
  226. uint16_t Treppe::setTime(uint16_t _time_per_stair)
  227. {
  228. time_per_stair = _time_per_stair;
  229. Serial.println("Treppe: time changed!");
  230. return time_per_stair;
  231. }
  232. void Treppe::setDirection(uint8_t _direction)
  233. {
  234. switch_direction = _direction;
  235. Serial.printf("Treppe: switch_direction=%d!\n", switch_direction);
  236. if (finish)
  237. Serial.println("apply direction request immediately");
  238. else
  239. Serial.println("currently active, dir change afterwards");
  240. // to do: implement state command variable to determine dimm-state
  241. }
  242. void Treppe::setState(uint8_t _state)
  243. {
  244. if (state == _state)
  245. return;
  246. else
  247. {
  248. switch_state = _state;
  249. Serial.printf("Treppe: switch_state=%d!\n", switch_state);
  250. if (finish)
  251. Serial.println("apply state request immediately");
  252. else
  253. Serial.println("currently active, state changes after activity");
  254. }
  255. }