led.lua 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. -- local led_pin = 1 --GPIO 5
  2. local led_pin = 1 --nodeMCU LED
  3. local override_pin = 4 --GPIO 4
  4. local HEARTBEAT_times = {40, 200, 40, 900} --format is alternating on and off times in ms
  5. local TRIPLEBLINK_times = {100, 20, 100, 20, 100, 20, 100} --format is alternating off and on times in ms
  6. local led_pwm_frequency = 500 --units: hz
  7. local led_max_brightness = 1023
  8. local current_pattern
  9. local pattern_queue = {}
  10. local HEARTBEAT_index = 1
  11. local TRIPLEBLINK_index = 1
  12. --pattern definitions
  13. local patterns = {
  14. STOPPED = 0,
  15. HEARTBEAT = 1,
  16. FADEIN = 2,
  17. FADEOUT = 3,
  18. TRIPLEBLINK = 4
  19. }
  20. local patterns_initial_pwm_duty = {
  21. [0] = 0,
  22. 0,
  23. 0,
  24. led_max_brightness,
  25. led_max_brightness
  26. }
  27. local pattern_intervals = {
  28. [0] = 0,
  29. HEARTBEAT_times,
  30. 1,
  31. 1,
  32. TRIPLEBLINK_times
  33. }
  34. --dependencies
  35. local TIMER = TIMERS.led
  36. local debug_message = debug_message
  37. local gpio = gpio
  38. local pwm = pwm
  39. local tmr = tmr
  40. local table = table
  41. local print = print
  42. module(...)
  43. function testcall()
  44. do_pattern(patterns.FADEIN)
  45. do_pattern(patterns.FADEOUT)
  46. end
  47. function init()
  48. debug_message('led.init')
  49. --handle timer, take exclusive control
  50. tmr.unregister(TIMER)
  51. current_pattern = patterns.STOPPED
  52. --init pins
  53. gpio.mode(override_pin, gpio.OUTPUT)
  54. pwm.setup(led_pin, led_pwm_frequency, 0)
  55. pwm.start(led_pin)
  56. pwm.stop(led_pin)
  57. end
  58. function stop()
  59. tmr.unregister(TIMER)
  60. --deassert control
  61. gpio.write(override_pin, gpio.LOW)
  62. current_pattern = patterns.STOPPED
  63. pattern_queue = {}
  64. end
  65. function do_pattern(next_pattern)
  66. debug_message('led.do_pattern: ' .. next_pattern)
  67. if(next_pattern == current_pattern) then
  68. debug_message('led.do_pattern: next same as current')
  69. return
  70. end
  71. if current_pattern ~= patterns.STOPPED then
  72. debug_message('led.do_pattern: current not STOPPED')
  73. --put next_pattern in queue
  74. table.insert(pattern_queue, next_pattern)
  75. else
  76. debug_message('current, next: ' .. current_pattern .. ', ' .. next_pattern)
  77. --start next_pattern!
  78. current_pattern = next_pattern
  79. -- override_enable()
  80. gpio.write(override_pin, gpio.HIGH)
  81. pattern(
  82. patterns_initial_pwm_duty[next_pattern],
  83. pattern_intervals[next_pattern],
  84. next_pattern_funcs[next_pattern]
  85. )
  86. end
  87. --rewrite queue:
  88. --when queueing new pattern, if transition (or flag) not nil then do immediately
  89. --otherwise enqueue and let end_function or similar get next from queue
  90. --STOP should instead a pattern like all others, renamed as OFF
  91. --transition functions transition(t) --> t+1
  92. --if t+1 is nil, end pattern
  93. end
  94. --TODO: intervals not used (still using global state)
  95. function pattern(initial_pwm_duty, intervals, transition)
  96. debug_message('led.pattern')
  97. pwm.setduty(led_pin, initial_pwm_duty)
  98. local pwm_duty = initial_pwm_duty
  99. --looping timer instead of alarm_single, can deregister on nil
  100. transition()
  101. end
  102. function FADEIN_update()
  103. local current_brightness = pwm.getduty(led_pin)
  104. current_brightness = current_brightness + 1
  105. if(current_brightness > led_max_brightness) then
  106. current_brightness = led_max_brightness
  107. end
  108. pwm.setduty(led_pin, current_brightness)
  109. if current_brightness < led_max_brightness then
  110. tmr.alarm(TIMER, 2, tmr.ALARM_SINGLE, FADEIN_update)
  111. else
  112. end_pattern()
  113. end
  114. end
  115. function FADEOUT_update()
  116. local current_brightness = pwm.getduty(led_pin)
  117. current_brightness = current_brightness - 1
  118. if(current_brightness < 0) then
  119. current_brightness = 0
  120. end
  121. pwm.setduty(led_pin, current_brightness)
  122. if current_brightness > 0 then
  123. tmr.alarm(TIMER, 2, tmr.ALARM_SINGLE, FADEOUT_update)
  124. else
  125. end_pattern()
  126. end
  127. end
  128. function HEARTBEAT_update()
  129. local current_brightness = pwm.getduty(led_pin)
  130. current_brightness = led_max_brightness - current_brightness
  131. pwm.setduty(led_pin, current_brightness)
  132. tmr.alarm(TIMER, HEARTBEAT_times[HEARTBEAT_index], tmr.ALARM_SINGLE, HEARTBEAT_update)
  133. HEARTBEAT_index = HEARTBEAT_index + 1
  134. if HEARTBEAT_index > table.getn(HEARTBEAT_times) then
  135. HEARTBEAT_index = 1
  136. end
  137. --pattern does not end
  138. end
  139. function TRIPLEBLINK_update()
  140. local current_brightness = pwm.getduty(led_pin)
  141. current_brightness = led_max_brightness - current_brightness
  142. pwm.setduty(led_pin, current_brightness)
  143. tmr.alarm(TIMER, TRIPLEBLINK_times[TRIPLEBLINK_index], tmr.ALARM_SINGLE, TRIPLEBLINK_update)
  144. TRIPLEBLINK_index = TRIPLEBLINK_index + 1
  145. if TRIPLEBLINK_index > table.getn(TRIPLEBLINK_times) then
  146. end_pattern()
  147. end
  148. end
  149. next_pattern_funcs = {
  150. HEARTBEAT_update,
  151. FADEIN_update,
  152. FADEOUT_update,
  153. TRIPLEBLINK_update
  154. }
  155. function end_pattern()
  156. if table.getn(pattern_queue) == 0 then
  157. stop()
  158. else
  159. p = pattern_queue[1]
  160. table.remove(pattern_queue, 1)
  161. current_pattern = patterns.STOPPED
  162. tmr.unregister(TIMER)
  163. do_pattern(p)
  164. end
  165. end
  166. init(TIMER)