led.lua 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. --pin definitions, should we move it out to another module?
  2. local led_pin = 1 --filler value
  3. local override_pin = 2 --filler value
  4. --pattern definitions
  5. local STOPPED = 0
  6. local HEARTBEAT = 1
  7. local FADE_IN = 2
  8. local FADE_OUT = 3
  9. local TRIPLE_BLINK = 4
  10. --private constants
  11. local heartbeat_times = {40, 200, 40, 900} --format is alternating on and off times in ms
  12. local triple_blink_times = {100, 20, 100, 20, 100, 20, 100} --format is alternating off and on times in ms
  13. local timer_id = nil --"constant"
  14. local led_pwm_frequency = 500 --units: hz
  15. local led_max_brightness = 1023
  16. --state variables
  17. local current_pattern
  18. local pattern_queue = {}
  19. local heartbeat_index = 1
  20. local triple_blink_index = 1
  21. -----------------------public functions------------------------------
  22. local function init(timer)
  23. --handle timer, take exclusive control
  24. timer_id = timer
  25. tmr.unregister(timer_id)
  26. --init pins
  27. gpio.mode(override_pin, gpio.OUTPUT)
  28. pwm.setup(led_pin, led_pwm_frequency, 0)
  29. stop()
  30. end
  31. local function stop()
  32. if(invalid_timer()) then
  33. print "Error, call led.init(timer_id) before calling any member functions"
  34. return
  35. end
  36. tmr.unregister(timer_id)
  37. --deassert control
  38. override_disable()
  39. --stop pwm
  40. pwm.stop(led_pin)
  41. current_pattern = STOPPED
  42. pattern_queue = {}
  43. end
  44. local function do_pattern(pattern)
  45. if(invalid_timer()) then
  46. print "Error, call led.init(timer_id) before calling any member functions"
  47. return
  48. end
  49. --TODO: CONFIRM VALID PATTERN
  50. --if(not is_valid_pattern(pattern))
  51. if(pattern == current_pattern) then
  52. --do nothing
  53. return
  54. end
  55. if not (current_pattern == STOPPED) then
  56. --put pattern in queue
  57. table.insert(pattern_queue, pattern)
  58. else
  59. --start pattern!
  60. current_pattern = pattern
  61. override_enable()
  62. --if train could be optimized with else's but this is more readable
  63. if(current_pattern == FADE_IN) then
  64. pwm.setduty(led_pin, 0)
  65. pwm.start()
  66. fade_in_update()
  67. end
  68. if(current_pattern == FADE_OUT) then
  69. pwm.setduty(led_pin, led_max_brightness)
  70. pwm.start()
  71. fade_out_update()
  72. end
  73. if(current_pattern == HEARTBEAT) then
  74. pwm.setduty(led_pin, 0)
  75. pwm.start()
  76. heartbeat_index = 1
  77. heartbeat_update()
  78. end
  79. if(current_pattern == TRIPLE_BLINK) then
  80. pwm.setduty(led_pin, led_max_brightness)
  81. pwm.start()
  82. triple_blink_index = 1
  83. triple_blink_update()
  84. end
  85. end
  86. end
  87. -----------------------private functions-------------------------
  88. local function fade_in_update()
  89. local current_brightness = pwm.getduty(led_pin)
  90. current_brightness = current_brightness + 1
  91. if(current_brightness > led_max_brightness) then
  92. current_brightness = led_max_brightness
  93. end
  94. pwm.setduty(led_pin, current_brightness)
  95. if current_brightness < led_max_brightness then
  96. tmr.alarm(timer_id, 2, tmr.ALARM_SINGLE, fade_in_update)
  97. else
  98. end_pattern()
  99. end
  100. end
  101. local function fade_out_update()
  102. local current_brightness = pwm.getduty(led_pin)
  103. current_brightness = current_brightness - 1
  104. if(current_brightness < 0) then
  105. current_brightness = 0
  106. end
  107. pwm.setduty(led_pin, current_brightness)
  108. if current_brightness > 0 then
  109. tmr.alarm(timer_id, 2, tmr.ALARM_SINGLE, fade_out_update)
  110. else
  111. end_pattern()
  112. end
  113. end
  114. local function heartbeat_update()
  115. local current_brightness = pwm.getduty(led_pin)
  116. current_brightness = led_max_brightness - current_brightness
  117. pwm.setduty(led_pin, current_brightness)
  118. tmr.alarm(timer_id, heartbeat_times[heartbeat_index], tmr.ALARM_SINGLE, heartbeat_update)
  119. heartbeat_index = heartbeat_index + 1
  120. if heartbeat_index > table.getn(heartbeat_times) then
  121. heartbeat_index = 1
  122. end
  123. --pattern does not end
  124. end
  125. local function triple_blink_update()
  126. local current_brightness = pwm.getduty(led_pin)
  127. current_brightness = led_max_brightness - current_brightness
  128. pwm.setduty(led_pin, current_brightness)
  129. tmr.alarm(timer_id, triple_blink_times[triple_blink_index], tmr.ALARM_SINGLE, triple_blink_update)
  130. triple_blink_index = triple_blink_index + 1
  131. if triple_blink_index > table.getn(triple_blink_times) then
  132. end_pattern()
  133. end
  134. end
  135. local function end_pattern()
  136. if table.getn(pattern_queue) == 0 then
  137. stop()
  138. else
  139. p = pattern_queue[1]
  140. table.remove(pattern_queue, 1)
  141. current_pattern = STOPPED
  142. tmr.unregister(timer_id)
  143. do_pattern(p)
  144. end
  145. end
  146. local function override_enable()
  147. gpio.write(override_pin, gpio.HIGH)
  148. end
  149. local function override_disable()
  150. gpio.write(override_pin, gpio.LOW)
  151. end
  152. local function invalid_timer()
  153. return (timer_id == nil or timer_id > 6)
  154. end
  155. return {
  156. init = init,
  157. stop = stop,
  158. do_pattern = do_pattern,
  159. HEARTBEAT = HEARTBEAT,
  160. FADE_IN = FADE_IN,
  161. FADE_OUT = FADE_OUT,
  162. TRIPLE_BLINK = TRIPLE_BLINK,
  163. }