denko 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_atmega_avr.yml +2 -1
  3. data/.github/workflows/build_atmega_megaavr.yml +2 -1
  4. data/.github/workflows/build_atsam3x.yml +1 -0
  5. data/.github/workflows/build_atsamd21.yml +2 -1
  6. data/.github/workflows/build_esp32.yml +4 -2
  7. data/.github/workflows/build_esp32c3.yml +4 -3
  8. data/.github/workflows/build_esp32c6.yml +4 -2
  9. data/.github/workflows/build_esp32h2.yml +4 -2
  10. data/.github/workflows/build_esp32s2.yml +4 -2
  11. data/.github/workflows/build_esp32s3.yml +4 -2
  12. data/.github/workflows/build_esp8266.yml +2 -1
  13. data/.github/workflows/build_ra4m1.yml +1 -0
  14. data/.github/workflows/build_rp2040.yml +4 -3
  15. data/.github/workflows/ruby.yml +1 -1
  16. data/CHANGELOG.md +203 -0
  17. data/DEPS_CLI.md +16 -16
  18. data/DEPS_IDE.md +31 -30
  19. data/MICROCONTROLLERS.md +103 -0
  20. data/PERIPHERALS.md +178 -0
  21. data/README.md +28 -21
  22. data/denko.gemspec +6 -1
  23. data/lib/denko/analog_io/ads1118.rb +5 -5
  24. data/lib/denko/analog_io/ads111x.rb +23 -19
  25. data/lib/denko/analog_io/joystick.rb +87 -0
  26. data/lib/denko/analog_io/potentiometer.rb +1 -5
  27. data/lib/denko/analog_io.rb +22 -8
  28. data/lib/denko/behaviors/bus_controller.rb +2 -1
  29. data/lib/denko/behaviors/bus_peripheral.rb +1 -1
  30. data/lib/denko/behaviors/callbacks.rb +18 -16
  31. data/lib/denko/behaviors/component.rb +0 -4
  32. data/lib/denko/behaviors/lifecycle.rb +1 -1
  33. data/lib/denko/behaviors/listener.rb +9 -3
  34. data/lib/denko/behaviors/multi_pin.rb +4 -6
  35. data/lib/denko/behaviors/poller.rb +11 -2
  36. data/lib/denko/behaviors/reader.rb +109 -21
  37. data/lib/denko/behaviors/single_pin.rb +2 -4
  38. data/lib/denko/behaviors/state.rb +18 -13
  39. data/lib/denko/behaviors/threaded.rb +19 -8
  40. data/lib/denko/behaviors.rb +36 -23
  41. data/lib/denko/board/eeprom.rb +1 -1
  42. data/lib/denko/board/i2c.rb +1 -1
  43. data/lib/denko/board/i2c_bit_bang.rb +9 -5
  44. data/lib/denko/board/map.rb +6 -2
  45. data/lib/denko/board/one_wire.rb +3 -3
  46. data/lib/denko/board/spi.rb +30 -30
  47. data/lib/denko/board/spi_bit_bang.rb +8 -11
  48. data/lib/denko/board.rb +6 -3
  49. data/lib/denko/connection/flow_control.rb +1 -1
  50. data/lib/denko/connection/serial.rb +5 -5
  51. data/lib/denko/digital_io/output.rb +12 -4
  52. data/lib/denko/digital_io/pcf8574.rb +114 -0
  53. data/lib/denko/digital_io/rotary_encoder.rb +10 -6
  54. data/lib/denko/digital_io.rb +24 -6
  55. data/lib/denko/display/canvas.rb +350 -157
  56. data/lib/denko/display/font/bmp_5x7.rb +142 -0
  57. data/lib/denko/display/font/bmp_6x8.rb +142 -0
  58. data/lib/denko/display/font/bmp_8x16.rb +141 -0
  59. data/lib/denko/display/font.rb +22 -0
  60. data/lib/denko/display/hd44780.rb +24 -20
  61. data/lib/denko/display/il0373.rb +186 -0
  62. data/lib/denko/display/mono_oled.rb +193 -0
  63. data/lib/denko/display/pcd8544.rb +154 -0
  64. data/lib/denko/display/pixel_common.rb +83 -0
  65. data/lib/denko/display/sh1106.rb +17 -21
  66. data/lib/denko/display/sh1107.rb +10 -0
  67. data/lib/denko/display/spi_common.rb +35 -0
  68. data/lib/denko/display/spi_epaper_common.rb +30 -0
  69. data/lib/denko/display/ssd1306.rb +6 -228
  70. data/lib/denko/display/ssd1680.rb +14 -0
  71. data/lib/denko/display/ssd1681.rb +8 -0
  72. data/lib/denko/display/ssd168x.rb +227 -0
  73. data/lib/denko/display/st7302.rb +207 -0
  74. data/lib/denko/display/st7565.rb +166 -0
  75. data/lib/denko/display.rb +40 -4
  76. data/lib/denko/eeprom/at24c.rb +67 -0
  77. data/lib/denko/eeprom/board.rb +69 -0
  78. data/lib/denko/eeprom.rb +15 -1
  79. data/lib/denko/helpers/engine_check.rb +13 -0
  80. data/lib/denko/{mutex_stub.rb → helpers/mutex_stub.rb} +6 -0
  81. data/lib/denko/helpers.rb +6 -0
  82. data/lib/denko/i2c/bit_bang.rb +1 -0
  83. data/lib/denko/i2c/bus_common.rb +9 -4
  84. data/lib/denko/i2c/peripheral.rb +5 -1
  85. data/lib/denko/i2c.rb +17 -4
  86. data/lib/denko/led/apa102.rb +1 -3
  87. data/lib/denko/led/base.rb +5 -0
  88. data/lib/denko/led/rgb.rb +16 -10
  89. data/lib/denko/led/seven_segment.rb +1 -1
  90. data/lib/denko/led.rb +17 -8
  91. data/lib/denko/motor/{stepper.rb → a3967.rb} +1 -1
  92. data/lib/denko/motor/servo.rb +16 -6
  93. data/lib/denko/motor.rb +16 -3
  94. data/lib/denko/one_wire/bus.rb +20 -16
  95. data/lib/denko/one_wire/bus_enumerator.rb +25 -14
  96. data/lib/denko/one_wire/helper.rb +4 -2
  97. data/lib/denko/one_wire.rb +18 -5
  98. data/lib/denko/pulse_io/buzzer.rb +2 -6
  99. data/lib/denko/pulse_io/ir_output.rb +1 -5
  100. data/lib/denko/pulse_io/pwm_output.rb +56 -31
  101. data/lib/denko/pulse_io.rb +17 -3
  102. data/lib/denko/rtc/ds3231.rb +4 -3
  103. data/lib/denko/rtc.rb +14 -1
  104. data/lib/denko/sensor/aht.rb +16 -20
  105. data/lib/denko/sensor/bme280.rb +23 -36
  106. data/lib/denko/sensor/bmp180.rb +8 -13
  107. data/lib/denko/sensor/dht.rb +17 -7
  108. data/lib/denko/sensor/ds18b20.rb +5 -4
  109. data/lib/denko/sensor/hdc1080.rb +174 -0
  110. data/lib/denko/sensor/htu21d.rb +17 -6
  111. data/lib/denko/sensor/htu31d.rb +6 -5
  112. data/lib/denko/sensor/jsnsr04t.rb +49 -0
  113. data/lib/denko/sensor/qmp6988.rb +14 -30
  114. data/lib/denko/sensor/rcwl9620.rb +1 -0
  115. data/lib/denko/sensor/sht3x.rb +6 -5
  116. data/lib/denko/sensor/sht4x.rb +125 -0
  117. data/lib/denko/sensor/vl53l0x.rb +58 -0
  118. data/lib/denko/sensor.rb +33 -15
  119. data/lib/denko/spi/base_register.rb +11 -7
  120. data/lib/denko/spi/bus_common.rb +12 -15
  121. data/lib/denko/spi/input_register.rb +6 -6
  122. data/lib/denko/spi/output_register.rb +13 -4
  123. data/lib/denko/spi/peripheral.rb +82 -84
  124. data/lib/denko/spi.rb +20 -10
  125. data/lib/denko/uart/bit_bang.rb +2 -27
  126. data/lib/denko/uart/common.rb +33 -0
  127. data/lib/denko/uart/hardware.rb +1 -26
  128. data/lib/denko/uart.rb +16 -2
  129. data/lib/denko/version.rb +1 -1
  130. data/lib/denko.rb +22 -25
  131. data/lib/denko_cli/targets.rb +7 -7
  132. data/lib/denko_cli/targets.txt +19 -20
  133. data/src/lib/Denko.cpp +26 -13
  134. data/src/lib/Denko.h +4 -4
  135. data/src/lib/DenkoDefines.h +7 -26
  136. data/src/lib/DenkoLEDArray.cpp +1 -8
  137. data/src/lib/DenkoSPI.cpp +31 -29
  138. data/src/lib/DenkoSPIBB.cpp +12 -14
  139. data/test/analog_io/input_test.rb +1 -1
  140. data/test/analog_io/potentiometer_test.rb +2 -2
  141. data/test/behaviors/bus_peripheral_test.rb +4 -4
  142. data/test/behaviors/callbacks_test.rb +20 -10
  143. data/test/behaviors/component_test.rb +18 -8
  144. data/test/board/board_test.rb +9 -9
  145. data/test/board/one_wire_test.rb +25 -14
  146. data/test/board/spi_test.rb +31 -15
  147. data/test/digital_io/input_test.rb +2 -2
  148. data/test/display/canvas_test.rb +306 -0
  149. data/test/display/hd44780_test.rb +34 -7
  150. data/test/eeprom/board_test.rb +45 -0
  151. data/test/helpers/mruby_minitest.rb +95 -0
  152. data/test/helpers/mruby_runner.rb +13 -0
  153. data/test/i2c/bus_test.rb +93 -30
  154. data/test/i2c/peripheral_test.rb +2 -2
  155. data/test/led/apa102_test.rb +24 -0
  156. data/test/led/rgb_test.rb +4 -4
  157. data/test/motor/{stepper_test.rb → a3967_test.rb} +2 -2
  158. data/test/one_wire/bus_enumerator_test.rb +1 -1
  159. data/test/one_wire/bus_test.rb +42 -35
  160. data/test/one_wire/peripheral_test.rb +5 -17
  161. data/test/pulse_io/ir_output_test.rb +5 -0
  162. data/test/pulse_io/pwm_output_test.rb +10 -10
  163. data/test/rtc/ds3231_test.rb +3 -2
  164. data/test/sensor/dht_test.rb +11 -11
  165. data/test/spi/bitbang_test.rb +27 -0
  166. data/test/spi/bus_test.rb +19 -29
  167. data/test/spi/input_register_test.rb +2 -2
  168. data/test/spi/{peripheral_multi_pin_test.rb → peripheral_test.rb} +25 -5
  169. data/test/test_helper.rb +44 -124
  170. data/vendor/board-maps/BoardMap.h +264 -0
  171. data/vendor/board-maps/yaml/ALFREDO_NOU3.yml +2 -0
  172. data/vendor/board-maps/yaml/ATD143_S3.yml +1 -0
  173. data/vendor/board-maps/yaml/BHARATPI_A7672S_4G.yml +14 -0
  174. data/vendor/board-maps/yaml/BHARATPI_LORA.yml +14 -0
  175. data/vendor/board-maps/yaml/BHARATPI_NODE_WIFI.yml +14 -0
  176. data/vendor/board-maps/yaml/BPI_LEAF_S3.yml +0 -1
  177. data/vendor/board-maps/yaml/CEZERIO_DEV_ESP32C6.yml +14 -0
  178. data/vendor/board-maps/yaml/CEZERIO_MINI_DEV_ESP32C6.yml +12 -0
  179. data/vendor/board-maps/yaml/CIRCUITART_ZERO_S3.yml +71 -0
  180. data/vendor/board-maps/yaml/CODECELLC3.yml +13 -0
  181. data/vendor/board-maps/yaml/CYOBOT_V2_ESP32S3.yml +7 -0
  182. data/vendor/board-maps/yaml/EDGES3D.yml +25 -0
  183. data/vendor/board-maps/yaml/ESP32C6_DEV.yml +3 -4
  184. data/vendor/board-maps/yaml/ESP32C6_THING_PLUS.yml +0 -1
  185. data/vendor/board-maps/yaml/ESP32H2_DEV.yml +0 -1
  186. data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +0 -1
  187. data/vendor/board-maps/yaml/ESP32P4_DEV.yml +35 -0
  188. data/vendor/board-maps/yaml/ESP32S2_DEV.yml +0 -1
  189. data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO.yml +0 -1
  190. data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +0 -1
  191. data/vendor/board-maps/yaml/ESP32_2432S028R.yml +14 -0
  192. data/vendor/board-maps/yaml/FEATHERS3.yml +1 -1
  193. data/vendor/board-maps/yaml/FRI3D_2024_ESP32S3.yml +43 -0
  194. data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +0 -1
  195. data/vendor/board-maps/yaml/GEEKBLE_NANO_ESP32S3.yml +25 -0
  196. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E290.yml +41 -0
  197. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E_213.yml +41 -0
  198. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_T190.yml +41 -0
  199. data/vendor/board-maps/yaml/HUIDU_HD_WF2.yml +5 -0
  200. data/vendor/board-maps/yaml/HUIDU_HD_WF4.yml +1 -0
  201. data/vendor/board-maps/yaml/LILYGO_LORA_CC1101.yml +6 -0
  202. data/vendor/board-maps/yaml/LILYGO_LORA_LR1121.yml +6 -0
  203. data/vendor/board-maps/yaml/LILYGO_LORA_SI4432.yml +6 -0
  204. data/vendor/board-maps/yaml/LILYGO_LORA_SX1262.yml +6 -0
  205. data/vendor/board-maps/yaml/LILYGO_LORA_SX1280.yml +6 -0
  206. data/vendor/board-maps/yaml/LOLIN_C3_MINI.yml +0 -1
  207. data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +1 -2
  208. data/vendor/board-maps/yaml/LoPy.yml +0 -1
  209. data/vendor/board-maps/yaml/LoPy4.yml +0 -1
  210. data/vendor/board-maps/yaml/M5STACK_DINMETER.yml +8 -0
  211. data/vendor/board-maps/yaml/M5STACK_FIRE.yml +1 -1
  212. data/vendor/board-maps/yaml/OMGS3.yml +25 -0
  213. data/vendor/board-maps/yaml/PCBCUPID_GLYPHC3.yml +23 -0
  214. data/vendor/board-maps/yaml/PCBCUPID_GLYPHC6.yml +32 -0
  215. data/vendor/board-maps/yaml/PCBCUPID_GLYPHH2.yml +24 -0
  216. data/vendor/board-maps/yaml/PYCOM_GPY.yml +0 -1
  217. data/vendor/board-maps/yaml/SENSEBOX_MCU_ESP32S2.yml +1 -1
  218. data/vendor/board-maps/yaml/SPARKFUN_ESP32S3_THING_PLUS.yml +13 -0
  219. data/vendor/board-maps/yaml/SPARKLEMOTIONMINI_ESP32.yml +12 -0
  220. data/vendor/board-maps/yaml/SPARKLEMOTIONSTICK_ESP32.yml +11 -0
  221. data/vendor/board-maps/yaml/SPARKLEMOTION_ESP32.yml +12 -0
  222. data/vendor/board-maps/yaml/SQUIXL.yml +7 -0
  223. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +0 -1
  224. data/vendor/board-maps/yaml/T_LORA_PAGER.yml +6 -0
  225. data/vendor/board-maps/yaml/T_WATCH_S3.yml +7 -0
  226. data/vendor/board-maps/yaml/T_WATCH_S3_ULTRA.yml +6 -0
  227. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_146.yml +41 -0
  228. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_147.yml +41 -0
  229. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_169.yml +38 -0
  230. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_185.yml +41 -0
  231. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_RELAY_6CH.yml +41 -0
  232. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_143.yml +7 -0
  233. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_164.yml +7 -0
  234. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_18.yml +38 -0
  235. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_191.yml +7 -0
  236. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_241.yml +7 -0
  237. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_146.yml +41 -0
  238. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_169.yml +38 -0
  239. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185.yml +41 -0
  240. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185_BOX.yml +41 -0
  241. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_21.yml +41 -0
  242. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_28.yml +41 -0
  243. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_4.yml +36 -0
  244. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43.yml +38 -0
  245. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43B.yml +38 -0
  246. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5.yml +38 -0
  247. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5B.yml +38 -0
  248. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_7.yml +38 -0
  249. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_ZERO.yml +36 -0
  250. data/vendor/board-maps/yaml/WIPY3.yml +0 -1
  251. data/vendor/board-maps/yaml/WS_ESP32_S3_MATRIX.yml +38 -0
  252. data/vendor/board-maps/yaml/XIAO_ESP32S3_PLUS.yml +46 -0
  253. data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V2.yml +28 -0
  254. data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V3.yml +28 -0
  255. data/vendor/board-maps/yaml/YB_ESP32S3_ETH.yml +40 -0
  256. data/vendor/board-maps/yaml/mercury.yml +20 -0
  257. metadata +116 -101
  258. data/.vscode/settings.json +0 -5
  259. data/.vscode/tasks.json +0 -20
  260. data/HARDWARE.md +0 -263
  261. data/benchmarks/analog_listen.rb +0 -49
  262. data/benchmarks/digital_write.rb +0 -28
  263. data/benchmarks/i2c_ssd1306_refresh.rb +0 -91
  264. data/examples/advanced/m5_env3.rb +0 -46
  265. data/examples/advanced/rotary_encoder_mac_volume.rb +0 -53
  266. data/examples/advanced/ssd1306_time_temp_rh.rb +0 -43
  267. data/examples/analog_io/ads1100.rb +0 -48
  268. data/examples/analog_io/ads1115.rb +0 -57
  269. data/examples/analog_io/ads1118.rb +0 -65
  270. data/examples/analog_io/dac_loopback.rb +0 -34
  271. data/examples/analog_io/input.rb +0 -56
  272. data/examples/analog_io/input_smoothing.rb +0 -27
  273. data/examples/analog_io/potentiometer.rb +0 -31
  274. data/examples/connection/binary_echo.rb +0 -34
  275. data/examples/connection/tcp.rb +0 -19
  276. data/examples/digital_io/button.rb +0 -17
  277. data/examples/digital_io/relay.rb +0 -17
  278. data/examples/digital_io/rotary_encoder.rb +0 -36
  279. data/examples/display/hd44780.png +0 -0
  280. data/examples/display/hd44780.rb +0 -47
  281. data/examples/display/ssd1306.rb +0 -43
  282. data/examples/display/ssd1306_s2_pico.rb +0 -29
  283. data/examples/eeprom/built_in.rb +0 -32
  284. data/examples/i2c/search.rb +0 -39
  285. data/examples/led/apa102_bounce.rb +0 -32
  286. data/examples/led/apa102_fade.rb +0 -44
  287. data/examples/led/builtin_blink.rb +0 -14
  288. data/examples/led/builtin_fade.rb +0 -19
  289. data/examples/led/rgb_led.rb +0 -31
  290. data/examples/led/seven_segment_char_echo.rb +0 -17
  291. data/examples/led/ws2812_bounce.rb +0 -30
  292. data/examples/led/ws2812_builtin_blink.rb +0 -22
  293. data/examples/led/ws2812_fade.rb +0 -43
  294. data/examples/motor/l298.rb +0 -45
  295. data/examples/motor/servo.rb +0 -17
  296. data/examples/motor/stepper.png +0 -0
  297. data/examples/motor/stepper.rb +0 -43
  298. data/examples/one_wire/search.rb +0 -32
  299. data/examples/pulse_io/buzzer.rb +0 -35
  300. data/examples/pulse_io/ir_output.rb +0 -51
  301. data/examples/pulse_io/pwm_output.rb +0 -30
  302. data/examples/rtc/ds3231.rb +0 -31
  303. data/examples/sensor/aht10.rb +0 -17
  304. data/examples/sensor/aht20.rb +0 -17
  305. data/examples/sensor/bme280.rb +0 -38
  306. data/examples/sensor/bmp180.rb +0 -26
  307. data/examples/sensor/dht.rb +0 -29
  308. data/examples/sensor/ds18b20.rb +0 -57
  309. data/examples/sensor/generic_pir.rb +0 -27
  310. data/examples/sensor/hcsr04.rb +0 -17
  311. data/examples/sensor/htu21d.rb +0 -43
  312. data/examples/sensor/htu31d.rb +0 -33
  313. data/examples/sensor/neat_tph_readings.rb +0 -32
  314. data/examples/sensor/qmp6988.rb +0 -51
  315. data/examples/sensor/rcwl9620.rb +0 -15
  316. data/examples/sensor/sht3x.rb +0 -32
  317. data/examples/spi/bitbang_loopback.rb +0 -46
  318. data/examples/spi/input_register.rb +0 -40
  319. data/examples/spi/output_register.rb +0 -41
  320. data/examples/spi/ssd_through_registers.rb +0 -28
  321. data/examples/spi/two_registers.rb +0 -40
  322. data/examples/uart/bit_bang_demo.rb +0 -25
  323. data/examples/uart/board_passthrough.rb +0 -40
  324. data/examples/uart/hardware_loopback.rb +0 -16
  325. data/lib/denko/eeprom/built_in.rb +0 -72
  326. data/lib/denko/fonts.rb +0 -106
  327. data/test/eeprom/built_in_test.rb +0 -61
  328. data/test/spi/peripheral_single_pin_test.rb +0 -48
  329. data/tutorial/01-led/led.fzz +0 -0
  330. data/tutorial/01-led/led.pdf +0 -0
  331. data/tutorial/01-led/led.rb +0 -73
  332. data/tutorial/02-button/button.fzz +0 -0
  333. data/tutorial/02-button/button.pdf +0 -0
  334. data/tutorial/02-button/button.rb +0 -65
  335. data/tutorial/03-potentiometer/potentiometer.fzz +0 -0
  336. data/tutorial/03-potentiometer/potentiometer.pdf +0 -0
  337. data/tutorial/03-potentiometer/potentiometer.rb +0 -66
  338. data/tutorial/04-pwm_led/pwm_led.fzz +0 -0
  339. data/tutorial/04-pwm_led/pwm_led.pdf +0 -0
  340. data/tutorial/04-pwm_led/pwm_led.rb +0 -64
  341. data/tutorial/05-rgb_led/rgb_led.fzz +0 -0
  342. data/tutorial/05-rgb_led/rgb_led.pdf +0 -0
  343. data/tutorial/05-rgb_led/rgb_led.rb +0 -58
  344. data/tutorial/05-rgb_led/rgb_mapping.rb +0 -76
@@ -4,8 +4,6 @@ module Denko
4
4
  include Behaviors::BusPeripheral
5
5
  include Behaviors::Lifecycle
6
6
 
7
- def pin; nil; end
8
-
9
7
  def length
10
8
  @length ||= params[:length] || 1
11
9
  end
@@ -94,7 +92,7 @@ module Denko
94
92
 
95
93
  def show
96
94
  data = start_frame + buffer + end_frame
97
- bus.transfer(pin, write: data)
95
+ bus.transfer(nil, write: data)
98
96
  end
99
97
  end
100
98
  end
@@ -14,5 +14,10 @@ module Denko
14
14
  end
15
15
  attr_reader :blink_interval
16
16
  end
17
+
18
+ # Shortcut, so LED.new does LED::Base.new.
19
+ def self.new(options={})
20
+ self::Base.new(options)
21
+ end
17
22
  end
18
23
  end
data/lib/denko/led/rgb.rb CHANGED
@@ -11,20 +11,26 @@ module Denko
11
11
 
12
12
  # Format: [R, G, B]
13
13
  COLORS = {
14
- red: [255, 000, 000],
15
- green: [000, 255, 000],
16
- blue: [000, 000, 255],
17
- cyan: [000, 255, 255],
18
- yellow: [255, 255, 000],
19
- magenta: [255, 000, 255],
20
- white: [255, 255, 255],
14
+ red: [100, 000, 000],
15
+ green: [000, 100, 000],
16
+ blue: [000, 000, 100],
17
+ cyan: [000, 100, 100],
18
+ yellow: [100, 100, 000],
19
+ magenta: [100, 000, 100],
20
+ white: [100, 100, 100],
21
21
  off: [000, 000, 000]
22
22
  }
23
23
 
24
24
  def write(r, g, b)
25
- red.write(r)
26
- green.write(g)
27
- blue.write(b)
25
+ red.duty = r
26
+ green.duty = g
27
+ blue.duty = b
28
+ end
29
+
30
+ def write_8_bit(r, g, b)
31
+ red.duty = ((r / 255.0) * 100).round
32
+ green.duty = ((g / 255.0) * 100).round
33
+ blue.duty = ((b / 255.0) * 100).round
28
34
  end
29
35
 
30
36
  def color=(color)
@@ -99,7 +99,7 @@ module Denko
99
99
  bits = bits.map { |b| 1^b } if anode
100
100
 
101
101
  bits.each_with_index do |bit, index|
102
- if board_is_register?
102
+ if board.is_a_register?
103
103
  # On a register, use #bit_set except for the last bit. This changes state in memory.
104
104
  # #digital_write on the last bit causes the register to write to its parallel out.
105
105
  if (index == bits.length-1)
data/lib/denko/led.rb CHANGED
@@ -1,13 +1,22 @@
1
+ # Represent files to be autoloaded in CRuby as an Array.
2
+ # This allows Mruby::Build to parse and preload them instead.
3
+ LED_FILES = [
4
+ [nil, "base"],
5
+ [:RGB, "rgb"],
6
+ [:SevenSegment, "seven_segment"],
7
+ [:WS2812, "ws2812"],
8
+ [:APA102, "apa102"],
9
+ ]
10
+
1
11
  module Denko
2
12
  module LED
3
- autoload :Base, "#{__dir__}/led/base"
4
- autoload :RGB, "#{__dir__}/led/rgb"
5
- autoload :SevenSegment, "#{__dir__}/led/seven_segment"
6
- autoload :WS2812, "#{__dir__}/led/ws2812"
7
- autoload :APA102, "#{__dir__}/led/apa102"
8
-
9
- def self.new(options={})
10
- self::Base.new(options)
13
+ LED_FILES.each do |file|
14
+ file_path = "#{__dir__}/led/#{file[1]}"
15
+ if file[0]
16
+ autoload file[0], file_path
17
+ else
18
+ require file_path
19
+ end
11
20
  end
12
21
  end
13
22
  end
@@ -1,6 +1,6 @@
1
1
  module Denko
2
2
  module Motor
3
- class Stepper
3
+ class A3967
4
4
  include Behaviors::MultiPin
5
5
  include Behaviors::Lifecycle
6
6
 
@@ -1,8 +1,10 @@
1
1
  module Denko
2
2
  module Motor
3
3
  class Servo
4
+ FREQUENCY = 50
5
+ PERIOD_NS = 20_000_000
6
+
4
7
  include Behaviors::SinglePin
5
- include Behaviors::Threaded
6
8
  include Behaviors::Lifecycle
7
9
 
8
10
  before_initialize do
@@ -24,18 +26,22 @@ module Denko
24
26
  attr_writer :min, :max
25
27
 
26
28
  def attach
27
- board.servo_toggle(pin, :on, min: min, max: max)
29
+ if board.platform == :arduino
30
+ board.servo_toggle(pin, :on, min: min, max: max)
31
+ else
32
+ board.set_pin_mode(pin, :output_pwm, {frequency: FREQUENCY, period: PERIOD_NS})
33
+ end
28
34
  end
29
35
 
30
36
  def detach
31
- board.servo_toggle(pin, :off)
37
+ board.servo_toggle(pin, :off) if board.platform == :arduino
32
38
  end
33
39
 
34
40
  def position=(value)
35
41
  value = value % 180 unless value == 180
36
42
 
37
43
  microseconds = ((value.to_f / 180) * (max - min)) + min
38
- board.servo_write(pin, microseconds.round)
44
+ write_microseconds(microseconds)
39
45
 
40
46
  self.state = value
41
47
  end
@@ -44,7 +50,7 @@ module Denko
44
50
  raise 'invalid speed value' if value > 100 || value < -100
45
51
 
46
52
  microseconds = (((value.to_f + 100) / 200) * (max - min)) + min
47
- board.servo_write(pin, microseconds.round)
53
+ write_microseconds(microseconds)
48
54
 
49
55
  self.state = value
50
56
  end
@@ -56,7 +62,11 @@ module Denko
56
62
 
57
63
  def write_microseconds(value)
58
64
  raise 'invalid microsecond value' if value > max || value < min
59
- board.servo_write(pin, value)
65
+ if board.platform == :arduino
66
+ board.servo_write(pin, value)
67
+ else
68
+ board.pwm_write(pin, (value * 1000.0).round)
69
+ end
60
70
  end
61
71
  end
62
72
  end
data/lib/denko/motor.rb CHANGED
@@ -1,7 +1,20 @@
1
+ # Represent files to be autoloaded in CRuby as an Array.
2
+ # This allows Mruby::Build to parse and preload them instead.
3
+ MOTOR_FILES = [
4
+ [:Servo, "servo"],
5
+ [:A3967, "a3967"],
6
+ [:L298, "l298"],
7
+ ]
8
+
1
9
  module Denko
2
10
  module Motor
3
- autoload :Servo, "#{__dir__}/motor/servo"
4
- autoload :Stepper, "#{__dir__}/motor/stepper"
5
- autoload :L298, "#{__dir__}/motor/l298"
11
+ MOTOR_FILES.each do |file|
12
+ file_path = "#{__dir__}/motor/#{file[1]}"
13
+ if file[0]
14
+ autoload file[0], file_path
15
+ else
16
+ require file_path
17
+ end
18
+ end
6
19
  end
7
20
  end
@@ -14,30 +14,34 @@ module Denko
14
14
  end
15
15
 
16
16
  def read_power_supply
17
- mutex.synchronize do
18
- # Without driving low first, results are inconsistent.
19
- board.set_pin_mode(self.pin, :output)
20
- board.digital_write(self.pin, board.low)
21
- sleep 0.1
17
+ mutex.lock
22
18
 
23
- reset
24
- write(SKIP_ROM, READ_POWER_SUPPLY)
19
+ # Without driving low first, results are inconsistent.
20
+ board.set_pin_mode(self.pin, :output)
21
+ board.digital_write(self.pin, board.low)
22
+ sleep 0.1
25
23
 
26
- # Only LSBIT matters, but we can only read whole bytes.
27
- byte = read(1)
28
- @parasite_power = (byte[0] == 0) ? true : false
29
- end
24
+ reset
25
+ write(SKIP_ROM, READ_POWER_SUPPLY)
26
+
27
+ # Only LSBIT matters, but we can only read whole bytes.
28
+ byte = read(1)
29
+ @parasite_power = (byte & 0b1 == 0) ? true : false
30
+
31
+ mutex.unlock
32
+ @parasite_power
30
33
  end
31
34
 
32
35
  def device_present
33
- mutex.synchronize do
34
- byte = read_using -> { reset(1) }
35
- (byte == 0) ? true : false
36
- end
36
+ mutex.lock
37
+ byte = read_using -> { reset(true) }
38
+ presence = (byte == 0) ? true : false
39
+ mutex.unlock
40
+ presence
37
41
  end
38
42
  alias :device_present? :device_present
39
43
 
40
- def reset(get_presence=0)
44
+ def reset(get_presence=false)
41
45
  board.one_wire_reset(pin, get_presence)
42
46
  end
43
47
 
@@ -44,17 +44,14 @@ module Denko
44
44
  def parse_search_result(result)
45
45
  address, complement = split_search_result(result)
46
46
 
47
- if (address & complement) > 0
48
- raise "OneWire device not connected or disconnected during search"
49
- end
50
-
47
+ raise "OneWire device not connected, or disconnected during search" if (address & complement) > 0
51
48
  raise "CRC error during OneWire search" unless Helper.crc(address)
52
49
 
53
50
  # Gives 0 at every discrepancy we didn't write 1 for on this search.
54
51
  new_discrepancies = address ^ complement
55
52
 
56
53
  high_discrepancy = -1
57
- (0..63).each { |i| high_discrepancy = i if new_discrepancies[i] == 0 }
54
+ (0..63).each { |i| high_discrepancy = i if ((new_discrepancies >> i) & 0b1 == 0) }
58
55
 
59
56
  # LSByte of address is product family.
60
57
  klass = family_lookup(address & 0xFF)
@@ -64,27 +61,41 @@ module Denko
64
61
 
65
62
  # Result is 16 bytes, 8 byte address and complement interleaved LSByte first.
66
63
  def split_search_result(data)
67
- address = 0
64
+ address = 0
68
65
  complement = 0
69
-
70
66
  data.reverse.each_slice(2) do |comp_byte, addr_byte|
71
- address = (address << 8) | addr_byte
67
+ address = (address << 8) | addr_byte
72
68
  complement = (complement << 8) | comp_byte
73
69
  end
74
-
75
70
  [address, complement]
76
71
  end
77
72
 
78
- #
79
- # Set FAMILY_CODE in peripheral class, and add the class to this array
80
- # for the class to be identified during search.
73
+ #
74
+ # Set FAMILY_CODE in peripheral class, then add the peripheral class
75
+ # to this array (as a String, since no autoloading on mruby).
76
+ # The class can then be identified during a bus search.
81
77
  #
82
78
  PERIPHERAL_CLASSES = [
83
- Sensor::DS18B20,
79
+ "Denko::Sensor::DS18B20",
84
80
  ]
85
81
 
82
+ def peripheral_classes
83
+ return @peripheral_classes if @peripheral_classes
84
+
85
+ @peripheral_classes = []
86
+ PERIPHERAL_CLASSES.each do |class_name|
87
+ begin
88
+ klass = Object.const_get(class_name)
89
+ rescue
90
+ next
91
+ end
92
+ @peripheral_classes << klass
93
+ end
94
+ @peripheral_classes
95
+ end
96
+
86
97
  def family_lookup(family_code)
87
- PERIPHERAL_CLASSES.each do |klass|
98
+ peripheral_classes.each do |klass|
88
99
  if (klass.const_defined? "FAMILY_CODE")
89
100
  return klass if klass::FAMILY_CODE == family_code
90
101
  end
@@ -2,7 +2,9 @@ module Denko
2
2
  module OneWire
3
3
  class Helper
4
4
  def self.address_to_bytes(address)
5
- [address].pack('Q<').split("").map(&:ord)
5
+ bytes = []
6
+ 8.times { |i| bytes[i] = address >> (8*i) & 0xFF }
7
+ bytes
6
8
  end
7
9
 
8
10
  def self.crc(data)
@@ -20,7 +22,7 @@ module Denko
20
22
  crc = 0b00000000
21
23
  bytes.take(bytes.length - 1).each do |byte|
22
24
  for bit in (0..7)
23
- xor = byte[bit] ^ crc[0]
25
+ xor = ((byte >> bit) & 0b1) ^ (crc & 0b1)
24
26
  crc = crc ^ ((xor * (2 ** 3)) | (xor * (2 ** 4)))
25
27
  crc = crc >> 1
26
28
  crc = crc | (xor * (2 ** 7))
@@ -1,9 +1,22 @@
1
+ # Represent files to be autoloaded in CRuby as an Array.
2
+ # This allows Mruby::Build to parse and preload them instead.
3
+ ONE_WIRE_FILES = [
4
+ [:Constants, "constants"],
5
+ [:Helper, "helper"],
6
+ [:BusEnumerator, "bus_enumerator"],
7
+ [:Bus, "bus"],
8
+ [:Peripheral, "peripheral"],
9
+ ]
10
+
1
11
  module Denko
2
12
  module OneWire
3
- autoload :Constants, "#{__dir__}/one_wire/constants"
4
- autoload :Helper, "#{__dir__}/one_wire/helper"
5
- autoload :BusEnumerator, "#{__dir__}/one_wire/bus_enumerator"
6
- autoload :Bus, "#{__dir__}/one_wire/bus"
7
- autoload :Peripheral, "#{__dir__}/one_wire/peripheral"
13
+ ONE_WIRE_FILES.each do |file|
14
+ file_path = "#{__dir__}/one_wire/#{file[1]}"
15
+ if file[0]
16
+ autoload file[0], file_path
17
+ else
18
+ require file_path
19
+ end
20
+ end
8
21
  end
9
22
  end
@@ -20,12 +20,8 @@ module Denko
20
20
  board.no_tone(pin)
21
21
  end
22
22
 
23
- # Kill the thread if running, and send no_tone.
24
- def stop
25
- stop_thread
26
- board.no_tone(pin)
27
- end
28
- alias :off :stop
23
+ alias :stop :no_tone
24
+ alias :off :no_tone
29
25
  end
30
26
  end
31
27
  end
@@ -1,13 +1,9 @@
1
1
  module Denko
2
2
  module PulseIO
3
3
  class IROutput
4
- include Behaviors::OutputPin
4
+ include Behaviors::SinglePin
5
5
  include Behaviors::Lifecycle
6
6
 
7
- before_initialize do
8
- params[:mode] = :output_pwm
9
- end
10
-
11
7
  def write(pulses=[], frequency: 38)
12
8
  if pulses.length > 255 || pulses.length < 1
13
9
  raise ArgumentError, 'wrong number of IR pulses (expected 1 to 255)'
@@ -5,21 +5,49 @@ module Denko
5
5
 
6
6
  interrupt_with :write, :pwm_write, :digital_write, :duty=
7
7
 
8
+ # Avoid setting :output mode if on PWM pin, and on a platform that muxes externally.
9
+ before_initialize do
10
+ b = params[:board]
11
+ p = params[:pin]
12
+ params[:mode] = :output_pwm if b.platform != :arduino && b.pin_is_pwm?(p)
13
+ end
14
+
15
+ # Call #pwm_enable immediately if params[:mode] was overriden to :output_pwm.
16
+ after_initialize do
17
+ pwm_enable if params[:mode] == :output_pwm
18
+ end
19
+
8
20
  def duty=(percent)
9
- if board_is_piboard
10
- pwm_write(percent)
21
+ if board.platform == :arduino
22
+ pwm_write((percent / 100.0 * pwm_high).round)
11
23
  else
12
- pwm_write(((percent * pwm_high) / 100.0).round)
24
+ pwm_write((percent / 100.0 * period).round)
13
25
  end
14
26
  end
15
27
 
16
28
  def digital_write(value)
17
- pwm_disable if pwm_enabled
18
- super(value)
29
+ # Use regular #digital_write for speed until a PWM method is called.
30
+ unless pwm_enabled?
31
+ super(value)
32
+ else
33
+ # On Arduinos, disable PWM and switch back to regular #digital_write.
34
+ if board.platform == :arduino
35
+ pwm_disable
36
+ super(value)
37
+ # Can't do that on Linux, so mimic DigitalIO.
38
+ else
39
+ if value == 1
40
+ pwm_write(period)
41
+ else
42
+ pwm_write(0)
43
+ end
44
+ end
45
+ end
19
46
  end
20
47
 
48
+ # Raw write. Takes nanoseconds on Linux, 0..pwm_high on Arduino.
21
49
  def pwm_write(value)
22
- pwm_enable unless pwm_enabled
50
+ pwm_enable unless pwm_enabled?
23
51
  board.pwm_write(pin, value)
24
52
  self.state = value
25
53
  end
@@ -29,6 +57,10 @@ module Denko
29
57
  @frequency ||= params[:frequency] || 1000
30
58
  end
31
59
 
60
+ def period
61
+ @period ||= (1_000_000_000.0 / frequency).round
62
+ end
63
+
32
64
  def resolution
33
65
  @resolution ||= params[:resolution] || board.analog_write_resolution
34
66
  end
@@ -37,51 +69,44 @@ module Denko
37
69
  @pwm_high ||= (2**resolution-1)
38
70
  end
39
71
 
40
- def frequency=(value)
72
+ def _frequency=(value)
41
73
  @frequency = value
74
+ @period = nil
75
+ end
76
+
77
+ def _resolution=(value)
78
+ @resolution = value
79
+ @pwm_high = nil
80
+ end
81
+
82
+ def frequency=(value)
83
+ self._frequency = value
42
84
  pwm_enable
43
85
  end
44
86
 
45
87
  def resolution=(value)
46
- @resolution = value
47
- @pwm_high = (2**value-1)
88
+ self._resolution = value
48
89
  pwm_enable
49
90
  end
50
91
 
51
92
  def pwm_settings_hash
52
- { frequency: frequency, resolution: resolution }
93
+ { frequency: frequency, period: period, resolution: resolution }
53
94
  end
54
95
 
55
96
  def pwm_enable(frequency: nil, resolution: nil)
56
- @frequency = frequency if frequency
57
- if resolution
58
- @resolution = resolution
59
- @pwm_high = (2**resolution-1)
60
- end
97
+ self._frequency = frequency if frequency
98
+ self._resolution = resolution if resolution
61
99
 
62
100
  board.set_pin_mode(pin, :output_pwm, pwm_settings_hash)
63
101
  @mode = :output_pwm
64
102
  end
65
103
 
66
104
  def pwm_disable
67
- self.mode = :output
105
+ self.mode = :output if board.platform == :arduino
68
106
  end
69
107
 
70
- def pwm_enabled
71
- mode == :output_pwm
72
- end
73
-
74
- def board_is_piboard
75
- @board_is_piboard ||= piboard_check
76
- end
77
-
78
- def piboard_check
79
- if Object.const_defined?("Denko::PiBoard")
80
- if board.class.ancestors.include?(Denko::PiBoard)
81
- return true
82
- end
83
- end
84
- false
108
+ def pwm_enabled?
109
+ self.mode == :output_pwm
85
110
  end
86
111
  end
87
112
  end
@@ -1,7 +1,21 @@
1
+ # Represent files to be autoloaded in CRuby as an Array.
2
+ # This allows Mruby::Build to parse and preload them instead.
3
+ PULSE_IO_FILES = [
4
+ # Pin and component setup stuff
5
+ [:PWMOutput, "pwm_output"],
6
+ [:Buzzer, "buzzer"],
7
+ [:IROutput, "ir_output"],
8
+ ]
9
+
1
10
  module Denko
2
11
  module PulseIO
3
- autoload :PWMOutput, "#{__dir__}/pulse_io/pwm_output"
4
- autoload :Buzzer, "#{__dir__}/pulse_io/buzzer"
5
- autoload :IROutput, "#{__dir__}/pulse_io/ir_output"
12
+ PULSE_IO_FILES.each do |file|
13
+ file_path = "#{__dir__}/pulse_io/#{file[1]}"
14
+ if file[0]
15
+ autoload file[0], file_path
16
+ else
17
+ require file_path
18
+ end
19
+ end
6
20
  end
7
21
  end
@@ -1,5 +1,3 @@
1
- require 'bcd'
2
-
3
1
  module Denko
4
2
  module RTC
5
3
  class DS3231
@@ -27,10 +25,13 @@ module Denko
27
25
 
28
26
  # Convert Time object to 7 byte BCD sequence.
29
27
  def time_to_bcd(time)
28
+ wday = time.wday
29
+ wday = 7 if wday == 0
30
+
30
31
  [ BCD.decode(time.sec),
31
32
  BCD.decode(time.min),
32
33
  BCD.decode(time.hour),
33
- BCD.decode(time.strftime('%u').to_i),
34
+ BCD.decode(wday),
34
35
  BCD.decode(time.day),
35
36
  BCD.decode(time.month),
36
37
  BCD.decode(time.year - 1970) ]
data/lib/denko/rtc.rb CHANGED
@@ -1,5 +1,18 @@
1
+ # Represent files to be autoloaded in CRuby as an Array.
2
+ # This allows Mruby::Build to parse and preload them instead.
3
+ RTC_FILES = [
4
+ [:DS3231, "ds3231"],
5
+ ]
6
+
1
7
  module Denko
2
8
  module RTC
3
- autoload :DS3231, "#{__dir__}/rtc/ds3231"
9
+ RTC_FILES.each do |file|
10
+ file_path = "#{__dir__}/rtc/#{file[1]}"
11
+ if file[0]
12
+ autoload file[0], file_path
13
+ else
14
+ require file_path
15
+ end
16
+ end
4
17
  end
5
18
  end