denko 0.13.6 → 0.14.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 (376) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/{build_avr.yml → build_atmega_avr.yml} +18 -18
  3. data/.github/workflows/{build_megaavr.yml → build_atmega_megaavr.yml} +18 -18
  4. data/.github/workflows/{build_sam3x.yml → build_atsam3x.yml} +17 -17
  5. data/.github/workflows/{build_samd.yml → build_atsamd21.yml} +18 -18
  6. data/.github/workflows/build_esp32.yml +17 -18
  7. data/.github/workflows/build_esp32c3.yml +57 -0
  8. data/.github/workflows/build_esp32c6.yml +57 -0
  9. data/.github/workflows/build_esp32h2.yml +56 -0
  10. data/.github/workflows/build_esp32s2.yml +57 -0
  11. data/.github/workflows/build_esp32s3.yml +57 -0
  12. data/.github/workflows/build_esp8266.yml +15 -15
  13. data/.github/workflows/build_ra4m1.yml +16 -16
  14. data/.github/workflows/build_rp2040.yml +17 -16
  15. data/.github/workflows/ruby.yml +20 -20
  16. data/CHANGELOG.md +195 -11
  17. data/DEPS_CLI.md +9 -9
  18. data/DEPS_IDE.md +17 -18
  19. data/HARDWARE.md +50 -51
  20. data/README.md +61 -53
  21. data/Rakefile +1 -1
  22. data/benchmarks/analog_listen.rb +49 -0
  23. data/benchmarks/digital_write.rb +28 -0
  24. data/benchmarks/i2c_ssd1306_refresh.rb +13 -6
  25. data/build +1 -1
  26. data/denko.gemspec +5 -2
  27. data/examples/advanced/{m5_env.rb → m5_env3.rb} +12 -14
  28. data/examples/advanced/rotary_encoder_mac_volume.rb +18 -13
  29. data/examples/advanced/ssd1306_time_temp_rh.rb +8 -13
  30. data/examples/analog_io/ads1100.rb +48 -0
  31. data/examples/analog_io/ads1115.rb +2 -2
  32. data/examples/analog_io/ads1118.rb +3 -11
  33. data/examples/analog_io/input.rb +17 -16
  34. data/examples/analog_io/input_smoothing.rb +27 -0
  35. data/examples/analog_io/potentiometer.rb +31 -0
  36. data/examples/connection/binary_echo.rb +34 -0
  37. data/examples/connection/tcp.rb +12 -27
  38. data/examples/digital_io/button.rb +7 -3
  39. data/examples/digital_io/relay.rb +17 -0
  40. data/examples/digital_io/rotary_encoder.rb +21 -11
  41. data/examples/display/hd44780.rb +13 -5
  42. data/examples/display/ssd1306.rb +20 -17
  43. data/examples/display/ssd1306_s2_pico.rb +2 -2
  44. data/examples/i2c/search.rb +10 -26
  45. data/examples/led/apa102_bounce.rb +3 -4
  46. data/examples/led/apa102_fade.rb +44 -0
  47. data/examples/led/builtin_blink.rb +3 -1
  48. data/examples/led/builtin_fade.rb +19 -0
  49. data/examples/led/rgb_led.rb +31 -0
  50. data/examples/led/seven_segment_char_echo.rb +4 -2
  51. data/examples/led/ws2812_bounce.rb +5 -7
  52. data/examples/led/ws2812_builtin_blink.rb +3 -2
  53. data/examples/led/ws2812_fade.rb +43 -0
  54. data/examples/motor/l298.rb +10 -8
  55. data/examples/motor/servo.rb +4 -3
  56. data/examples/motor/stepper.rb +13 -13
  57. data/examples/one_wire/search.rb +32 -0
  58. data/examples/pulse_io/buzzer.rb +8 -3
  59. data/examples/pulse_io/ir_output.rb +51 -0
  60. data/examples/pulse_io/pwm_output.rb +30 -0
  61. data/examples/rtc/ds3231.rb +18 -35
  62. data/examples/sensor/aht10.rb +4 -6
  63. data/examples/sensor/aht20.rb +4 -6
  64. data/examples/sensor/bme280.rb +4 -4
  65. data/examples/sensor/bmp180.rb +9 -5
  66. data/examples/sensor/dht.rb +20 -15
  67. data/examples/sensor/ds18b20.rb +20 -21
  68. data/examples/sensor/generic_pir.rb +4 -2
  69. data/examples/sensor/hcsr04.rb +5 -2
  70. data/examples/sensor/htu21d.rb +9 -20
  71. data/examples/sensor/htu31d.rb +7 -9
  72. data/examples/sensor/neat_tph_readings.rb +15 -9
  73. data/examples/sensor/qmp6988.rb +5 -7
  74. data/examples/sensor/rcwl9620.rb +3 -3
  75. data/examples/sensor/sht3x.rb +4 -6
  76. data/examples/spi/bitbang_loopback.rb +46 -0
  77. data/examples/spi/input_register.rb +9 -19
  78. data/examples/spi/output_register.rb +9 -17
  79. data/examples/spi/ssd_through_registers.rb +28 -0
  80. data/examples/spi/two_registers.rb +18 -24
  81. data/examples/uart/bit_bang_demo.rb +25 -0
  82. data/examples/uart/board_passthrough.rb +19 -13
  83. data/examples/uart/hardware_loopback.rb +1 -1
  84. data/lib/denko/analog_io/ads1100.rb +127 -0
  85. data/lib/denko/analog_io/ads1115.rb +8 -25
  86. data/lib/denko/analog_io/ads1118.rb +10 -25
  87. data/lib/denko/analog_io/ads111x.rb +25 -11
  88. data/lib/denko/analog_io/input.rb +29 -55
  89. data/lib/denko/analog_io/input_helper.rb +42 -0
  90. data/lib/denko/analog_io/output.rb +5 -5
  91. data/lib/denko/analog_io/potentiometer.rb +6 -8
  92. data/lib/denko/analog_io.rb +2 -1
  93. data/lib/denko/behaviors/board_proxy.rb +13 -1
  94. data/lib/denko/behaviors/bus_controller.rb +1 -0
  95. data/lib/denko/behaviors/bus_controller_addressed.rb +1 -0
  96. data/lib/denko/behaviors/bus_peripheral.rb +3 -4
  97. data/lib/denko/behaviors/bus_peripheral_addressed.rb +8 -6
  98. data/lib/denko/behaviors/callbacks.rb +9 -7
  99. data/lib/denko/behaviors/component.rb +16 -14
  100. data/lib/denko/behaviors/input_pin.rb +14 -15
  101. data/lib/denko/behaviors/lifecycle.rb +51 -0
  102. data/lib/denko/behaviors/multi_pin.rb +22 -18
  103. data/lib/denko/behaviors/output_pin.rb +9 -4
  104. data/lib/denko/behaviors/single_pin.rb +1 -0
  105. data/lib/denko/behaviors/state.rb +15 -9
  106. data/lib/denko/behaviors/subcomponents.rb +72 -12
  107. data/lib/denko/behaviors.rb +2 -1
  108. data/lib/denko/board/core.rb +36 -18
  109. data/lib/denko/board/i2c.rb +14 -14
  110. data/lib/denko/board/i2c_bit_bang.rb +49 -0
  111. data/lib/denko/board/infrared.rb +6 -6
  112. data/lib/denko/board/led_array.rb +6 -5
  113. data/lib/denko/board/spi.rb +15 -10
  114. data/lib/denko/board/spi_bit_bang.rb +9 -7
  115. data/lib/denko/board.rb +35 -33
  116. data/lib/denko/connection/binary_echo.rb +17 -0
  117. data/lib/denko/connection/flow_control.rb +11 -15
  118. data/lib/denko/connection/handshake.rb +2 -0
  119. data/lib/denko/digital_io/button.rb +4 -0
  120. data/lib/denko/digital_io/c_bit_bang.rb +15 -0
  121. data/lib/denko/digital_io/input.rb +4 -5
  122. data/lib/denko/digital_io/output.rb +7 -6
  123. data/lib/denko/digital_io/relay.rb +2 -0
  124. data/lib/denko/digital_io/rotary_encoder.rb +78 -60
  125. data/lib/denko/digital_io.rb +1 -0
  126. data/lib/denko/display/hd44780.rb +136 -93
  127. data/lib/denko/display/sh1106.rb +42 -0
  128. data/lib/denko/display/ssd1306.rb +105 -45
  129. data/lib/denko/display.rb +1 -0
  130. data/lib/denko/eeprom/built_in.rb +19 -16
  131. data/lib/denko/i2c/bit_bang.rb +31 -0
  132. data/lib/denko/i2c/bus.rb +8 -36
  133. data/lib/denko/i2c/bus_common.rb +45 -0
  134. data/lib/denko/i2c/peripheral.rb +28 -19
  135. data/lib/denko/i2c.rb +2 -0
  136. data/lib/denko/led/apa102.rb +43 -29
  137. data/lib/denko/led/base.rb +8 -2
  138. data/lib/denko/led/rgb.rb +5 -7
  139. data/lib/denko/led/seven_segment.rb +24 -9
  140. data/lib/denko/led/ws2812.rb +10 -7
  141. data/lib/denko/message.rb +5 -0
  142. data/lib/denko/motor/l298.rb +11 -10
  143. data/lib/denko/motor/servo.rb +22 -10
  144. data/lib/denko/motor/stepper.rb +11 -14
  145. data/lib/denko/mutex_stub.rb +7 -0
  146. data/lib/denko/one_wire/bus.rb +9 -5
  147. data/lib/denko/one_wire/peripheral.rb +0 -3
  148. data/lib/denko/pulse_io/buzzer.rb +9 -3
  149. data/lib/denko/pulse_io/{ir_transmitter.rb → ir_output.rb} +9 -4
  150. data/lib/denko/pulse_io/pwm_output.rb +69 -15
  151. data/lib/denko/pulse_io.rb +3 -3
  152. data/lib/denko/rtc/ds3231.rb +11 -13
  153. data/lib/denko/sensor/aht.rb +22 -21
  154. data/lib/denko/sensor/bme280.rb +60 -63
  155. data/lib/denko/sensor/bmp180.rb +41 -38
  156. data/lib/denko/sensor/dht.rb +22 -5
  157. data/lib/denko/sensor/ds18b20.rb +40 -34
  158. data/lib/denko/sensor/hcsr04.rb +7 -5
  159. data/lib/denko/sensor/helper.rb +37 -0
  160. data/lib/denko/sensor/htu21d.rb +44 -55
  161. data/lib/denko/sensor/htu31d.rb +32 -33
  162. data/lib/denko/sensor/qmp6988.rb +25 -23
  163. data/lib/denko/sensor/rcwl9620.rb +2 -5
  164. data/lib/denko/sensor/sht3x.rb +23 -21
  165. data/lib/denko/sensor.rb +1 -2
  166. data/lib/denko/spi/base_register.rb +22 -22
  167. data/lib/denko/spi/bit_bang.rb +17 -51
  168. data/lib/denko/spi/bus.rb +15 -29
  169. data/lib/denko/spi/bus_common.rb +36 -0
  170. data/lib/denko/spi/input_register.rb +36 -30
  171. data/lib/denko/spi/output_register.rb +25 -40
  172. data/lib/denko/spi/peripheral.rb +93 -24
  173. data/lib/denko/spi.rb +6 -1
  174. data/lib/denko/uart/bit_bang.rb +5 -3
  175. data/lib/denko/uart/hardware.rb +9 -8
  176. data/lib/denko/version.rb +1 -1
  177. data/lib/denko.rb +10 -0
  178. data/lib/denko_cli/generator.rb +2 -2
  179. data/lib/denko_cli/packages.rb +8 -10
  180. data/lib/denko_cli/targets.rb +8 -8
  181. data/lib/denko_cli/targets.txt +4 -4
  182. data/lib/denko_cli/usage.txt +1 -1
  183. data/src/denko_ethernet.ino +0 -14
  184. data/src/denko_serial.ino +0 -14
  185. data/src/denko_wifi.ino +6 -15
  186. data/src/lib/Denko.cpp +39 -3
  187. data/src/lib/Denko.h +42 -26
  188. data/src/lib/DenkoCoreIO.cpp +57 -102
  189. data/src/lib/DenkoDefines.h +36 -31
  190. data/src/lib/DenkoI2C.cpp +54 -45
  191. data/src/lib/DenkoI2CBB.cpp +238 -0
  192. data/src/lib/DenkoIROut.cpp +12 -7
  193. data/src/lib/DenkoLEDArray.cpp +36 -13
  194. data/src/lib/DenkoSPI.cpp +6 -5
  195. data/src/lib/DenkoSPIBB.cpp +7 -6
  196. data/target.yml +37 -2
  197. data/test/analog_io/potentiometer_test.rb +10 -10
  198. data/test/behaviors/board_proxy_test.rb +1 -1
  199. data/test/behaviors/callbacks_test.rb +11 -3
  200. data/test/behaviors/component_test.rb +17 -9
  201. data/test/behaviors/input_pin_test.rb +14 -9
  202. data/test/behaviors/multi_pin_test.rb +14 -4
  203. data/test/behaviors/output_pin_test.rb +11 -8
  204. data/test/behaviors/poller_test.rb +1 -0
  205. data/test/behaviors/reader_test.rb +3 -2
  206. data/test/behaviors/subcomponents_test.rb +22 -2
  207. data/test/board/core_test.rb +15 -11
  208. data/test/board/i2c_test.rb +39 -33
  209. data/test/board/infrared_test.rb +1 -1
  210. data/test/board/message_test.rb +17 -11
  211. data/test/board/spi_test.rb +21 -21
  212. data/test/digital_io/button_test.rb +15 -0
  213. data/test/digital_io/relay_test.rb +18 -0
  214. data/test/digital_io/rotary_encoder_test.rb +80 -60
  215. data/test/eeprom/built_in_test.rb +9 -9
  216. data/test/i2c/bus_test.rb +30 -14
  217. data/test/i2c/peripheral_test.rb +36 -17
  218. data/test/led/base_test.rb +2 -1
  219. data/test/led/rgb_test.rb +6 -6
  220. data/test/led/seven_segment_test.rb +7 -7
  221. data/test/motor/servo_test.rb +1 -1
  222. data/test/motor/stepper_test.rb +2 -2
  223. data/test/one_wire/bus_test.rb +1 -0
  224. data/test/pulse_io/buzzer_test.rb +7 -4
  225. data/test/pulse_io/{ir_transmitter_test.rb → ir_output_test.rb} +10 -10
  226. data/test/pulse_io/pwm_output_test.rb +74 -18
  227. data/test/rtc/ds3231_test.rb +11 -13
  228. data/test/sensor/dht_test.rb +1 -1
  229. data/test/sensor/ds18b20_test.rb +4 -8
  230. data/test/spi/bus_test.rb +7 -7
  231. data/test/spi/input_register_test.rb +15 -15
  232. data/test/spi/output_register_test.rb +10 -28
  233. data/test/spi/peripheral_multi_pin_test.rb +53 -0
  234. data/test/spi/peripheral_single_pin_test.rb +48 -0
  235. data/test/test_helper.rb +36 -33
  236. data/tutorial/02-button/button.rb +5 -4
  237. data/tutorial/03-potentiometer/potentiometer.rb +9 -5
  238. data/tutorial/04-pwm_led/pwm_led.rb +14 -16
  239. data/tutorial/05-rgb_led/rgb_led.rb +6 -6
  240. data/tutorial/05-rgb_led/rgb_mapping.rb +11 -11
  241. data/vendor/board-maps/BoardMap.h +416 -56
  242. data/vendor/board-maps/lib/header_parser.rb +12 -2
  243. data/vendor/board-maps/yaml/ADAFRUIT_CAMERA_ESP32S3.yml +2 -2
  244. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32C6.yml +15 -0
  245. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32_V2.yml +1 -1
  246. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_RP2040_ADALOGGER.yml +44 -0
  247. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32C3.yml +1 -0
  248. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S2.yml +1 -0
  249. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_N4R2.yml +1 -0
  250. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_NOPSRAM.yml +1 -0
  251. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32_PICO.yml +1 -0
  252. data/vendor/board-maps/yaml/AMKEN_BB.yml +48 -0
  253. data/vendor/board-maps/yaml/AMKEN_ES.yml +48 -0
  254. data/vendor/board-maps/yaml/AMKEN_REVELOP.yml +48 -0
  255. data/vendor/board-maps/yaml/AMKEN_REVELOP_PLUS.yml +48 -0
  256. data/vendor/board-maps/yaml/ASL_CAN_X2.yml +41 -0
  257. data/vendor/board-maps/yaml/BLING.yml +25 -0
  258. data/vendor/board-maps/yaml/BPI_LEAF_S3.yml +1 -0
  259. data/vendor/board-maps/yaml/BRIDGETEK_IDM2040_7A.yml +48 -0
  260. data/vendor/board-maps/yaml/Bee_Motion_Mini.yml +13 -1
  261. data/vendor/board-maps/yaml/Breadstick_Raspberry.yml +31 -0
  262. data/vendor/board-maps/yaml/DFROBOT_BEETLE_ESP32C6.yml +8 -0
  263. data/vendor/board-maps/yaml/DFROBOT_FIREBEETLE_2_ESP32C6.yml +20 -0
  264. data/vendor/board-maps/yaml/DFROBOT_FIREBEETLE_ESP32.yml +46 -0
  265. data/vendor/board-maps/yaml/DPTECHNICS_WALTER.yml +39 -0
  266. data/vendor/board-maps/yaml/ELECROW_CROWPANEL_7.yml +8 -0
  267. data/vendor/board-maps/yaml/ESP32C2_DEV.yml +12 -0
  268. data/vendor/board-maps/yaml/ESP32C3_DEVKIT_LIPO.yml +14 -0
  269. data/vendor/board-maps/yaml/ESP32C6_DEV.yml +15 -0
  270. data/vendor/board-maps/yaml/ESP32C6_EVB.yml +15 -0
  271. data/vendor/board-maps/yaml/ESP32C6_QWIIC_POCKET.yml +15 -0
  272. data/vendor/board-maps/yaml/ESP32C6_THING_PLUS.yml +15 -0
  273. data/vendor/board-maps/yaml/ESP32H2_DEV.yml +13 -0
  274. data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +13 -0
  275. data/vendor/board-maps/yaml/ESP32S2_DEV.yml +1 -0
  276. data/vendor/board-maps/yaml/{RMP.yml → ESP32S2_DEVKIT_LIPO.yml} +2 -1
  277. data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +44 -0
  278. data/vendor/board-maps/yaml/ESP32S3_DEVKIT_LIPO.yml +42 -0
  279. data/vendor/board-maps/yaml/ESP32S3_POWERFEATHER.yml +22 -0
  280. data/vendor/board-maps/yaml/ESP32_SBC_FABGL.yml +35 -0
  281. data/vendor/board-maps/yaml/EVN_ALPHA.yml +48 -0
  282. data/vendor/board-maps/yaml/FEATHERS3NEO.yml +32 -0
  283. data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +14 -0
  284. data/vendor/board-maps/yaml/HELTEC_CAPSULE_SENSOR_V3.yml +43 -0
  285. data/vendor/board-maps/yaml/HELTEC_WIFI_LORA_32_V3.yml +42 -0
  286. data/vendor/board-maps/yaml/HELTEC_WIRELESS_BRIDGE.yml +8 -0
  287. data/vendor/board-maps/yaml/HELTEC_WIRELESS_MINI_SHELL.yml +13 -0
  288. data/vendor/board-maps/yaml/HELTEC_WIRELESS_PAPER.yml +42 -0
  289. data/vendor/board-maps/yaml/HELTEC_WIRELESS_SHELL_V3.yml +42 -0
  290. data/vendor/board-maps/yaml/HELTEC_WIRELESS_STICK_LITE_V3.yml +30 -0
  291. data/vendor/board-maps/yaml/HELTEC_WIRELESS_TRACKER.yml +41 -0
  292. data/vendor/board-maps/yaml/HT_DE01.yml +42 -0
  293. data/vendor/board-maps/yaml/IMBRIOS_LOGSENS_V1P1.yml +1 -1
  294. data/vendor/board-maps/yaml/LILYGO_T3S3_LR1121.yml +9 -0
  295. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1262.yml +9 -0
  296. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1276.yml +9 -0
  297. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1278.yml +9 -0
  298. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280.yml +9 -0
  299. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280PA.yml +8 -0
  300. data/vendor/board-maps/yaml/LILYGO_T_ETH_LITE.yml +21 -0
  301. data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +14 -0
  302. data/vendor/board-maps/yaml/LOLIN_S3.yml +1 -0
  303. data/vendor/board-maps/yaml/LOLIN_S3_MINI_PRO.yml +40 -0
  304. data/vendor/board-maps/yaml/Lion_Bit_Dev_Board.yml +0 -2
  305. data/vendor/board-maps/yaml/LoPy.yml +1 -0
  306. data/vendor/board-maps/yaml/LoPy4.yml +1 -0
  307. data/vendor/board-maps/yaml/M5STACK_CAPSULE.yml +8 -0
  308. data/vendor/board-maps/yaml/M5STACK_CARDPUTER.yml +8 -0
  309. data/vendor/board-maps/yaml/M5STACK_DIAL.yml +8 -0
  310. data/vendor/board-maps/yaml/M5STACK_FIRE.yml +0 -1
  311. data/vendor/board-maps/yaml/M5STACK_NANOC6.yml +17 -0
  312. data/vendor/board-maps/yaml/M5STACK_PAPER.yml +9 -0
  313. data/vendor/board-maps/yaml/M5STACK_POE_CAM.yml +5 -0
  314. data/vendor/board-maps/yaml/M5STACK_STAMP_C3.yml +13 -0
  315. data/vendor/board-maps/yaml/M5STACK_STAMP_S3.yml +4 -0
  316. data/vendor/board-maps/yaml/{M5Stick_C.yml → M5STACK_STICKC.yml} +0 -1
  317. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS.yml +9 -0
  318. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS2.yml +9 -0
  319. data/vendor/board-maps/yaml/M5STACK_TOUGH.yml +9 -0
  320. data/vendor/board-maps/yaml/M5STACK_UNIT_CAM.yml +10 -0
  321. data/vendor/board-maps/yaml/M5STACK_UNIT_CAMS3.yml +4 -0
  322. data/vendor/board-maps/yaml/M5Stack_ATOM.yml +0 -1
  323. data/vendor/board-maps/yaml/MAKERGO_C3_SUPERMINI.yml +14 -0
  324. data/vendor/board-maps/yaml/MARBLE_PICO.yml +48 -0
  325. data/vendor/board-maps/yaml/METEHOCA_AKANA_R1.yml +46 -0
  326. data/vendor/board-maps/yaml/NAMINO_BIANCO.yml +13 -0
  327. data/vendor/board-maps/yaml/NEBULAS3.yml +0 -1
  328. data/vendor/board-maps/yaml/NEWSAN_ARCHI.yml +48 -0
  329. data/vendor/board-maps/yaml/NOLOGO_ESP32C3_SUPER_MINI.yml +14 -0
  330. data/vendor/board-maps/yaml/NOLOGO_ESP32S3_PICO.yml +12 -0
  331. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_16MB.yml +48 -0
  332. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_2MB.yml +48 -0
  333. data/vendor/board-maps/yaml/OPTA_ANALOG.yml +7 -0
  334. data/vendor/board-maps/yaml/OPTA_DIGITAL.yml +5 -0
  335. data/vendor/board-maps/yaml/PINTRONIX_PINMAX.yml +42 -0
  336. data/vendor/board-maps/yaml/PYCOM_GPY.yml +1 -0
  337. data/vendor/board-maps/yaml/REDPILL_ESP32S3.yml +0 -1
  338. data/vendor/board-maps/yaml/SENSEBOX_MCU_ESP32S2.yml +12 -0
  339. data/vendor/board-maps/yaml/SPARKFUN_MICROMOD_RP2040.yml +48 -0
  340. data/vendor/board-maps/yaml/SPARKFUN_PRO_MICRO_ESP32C3.yml +24 -0
  341. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER.yml +31 -0
  342. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +15 -0
  343. data/vendor/board-maps/yaml/TINYC6.yml +25 -0
  344. data/vendor/board-maps/yaml/UPESY_EDU_ESP32.yml +28 -0
  345. data/vendor/board-maps/yaml/UPESY_ESP32C3_BASIC.yml +13 -0
  346. data/vendor/board-maps/yaml/UPESY_ESP32C3_MINI.yml +12 -0
  347. data/vendor/board-maps/yaml/UPESY_ESP32S3_BASIC.yml +42 -0
  348. data/vendor/board-maps/yaml/VIRALINK_GATE32_01.yml +6 -0
  349. data/vendor/board-maps/yaml/VIRALINK_GATE32_11.yml +7 -0
  350. data/vendor/board-maps/yaml/WAVESHARE_ESP32S3_TOUCH_LCD_128.yml +8 -0
  351. data/vendor/board-maps/yaml/WAVESHARE_RP2040_MATRIX.yml +48 -0
  352. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ONE.yml +1 -0
  353. data/vendor/board-maps/yaml/WAVESHARE_RP2040_PIZERO.yml +47 -0
  354. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ZERO.yml +1 -0
  355. data/vendor/board-maps/yaml/WEACT_STUDIO_ESP32C3.yml +14 -0
  356. data/vendor/board-maps/yaml/WIPY3.yml +1 -0
  357. data/vendor/board-maps/yaml/WT32_SC01_PLUS.yml +7 -0
  358. data/vendor/board-maps/yaml/WiFiduinoV2.yml +1 -0
  359. data/vendor/board-maps/yaml/XIAO_ESP32C3.yml +0 -1
  360. data/vendor/board-maps/yaml/XIAO_ESP32C6.yml +22 -0
  361. data/vendor/board-maps/yaml/unphone9.yml +8 -0
  362. metadata +169 -30
  363. data/examples/led/apa102_breathe.rb +0 -45
  364. data/examples/pulse_io/ir_transmitter.rb +0 -55
  365. data/examples/spi/ssd_through_register.rb +0 -40
  366. data/examples/uart/bit_bang_read.rb +0 -16
  367. data/examples/uart/bit_bang_write.rb +0 -16
  368. data/lib/denko/analog_io/sensor.rb +0 -6
  369. data/lib/denko/sensor/virtual.rb +0 -42
  370. data/src/lib/DenkoIROutESP.cpp +0 -26
  371. data/vendor/board-maps/yaml/STAMP_S3.yml +0 -8
  372. /data/vendor/board-maps/yaml/{BRIDGETEK_IDM2040-7A.yml → BRIDGETEK_IDM2040_43A.yml} +0 -0
  373. /data/vendor/board-maps/yaml/{heltec_wifi_32_lora_V3.yml → HELTEC_WIRELESS_STICK_V3.yml} +0 -0
  374. /data/vendor/board-maps/yaml/{M5Stack_Core_ESP32.yml → M5STACK_CORE.yml} +0 -0
  375. /data/vendor/board-maps/yaml/{M5Stamp_Pico.yml → M5STACK_STAMP_PICO.yml} +0 -0
  376. /data/vendor/board-maps/yaml/{M5Stack-Timer-CAM.yml → M5STACK_TIMER_CAM.yml} +0 -0
@@ -4,31 +4,37 @@
4
4
  # For this example, board1 (direct) is an Arduino Mega. board2 (passthrough) is an Uno,
5
5
  # running Denko, with its UART pins (0, 1) connected to the Mega's UART1 pins (18, 19)
6
6
  #
7
- # This isn't 100% reliable. The Rx buffer on the direct board is periodically read, so
8
- # it can potentially overflow, causing data sent from the passthrough board to be lost.
9
- # Eventually flow control data will be lost and the host will stop sending altogether.
7
+ # This isn't 100% reliable. The Rx buffer on the direct board is periodically read, instead
8
+ # of using an interrupt. It can potentially overflow, causing data from the passthrough board
9
+ # to be lost. If flow control data is lost, the connection will halt.
10
10
  #
11
11
  # Use at your own risk, but for the best possible performance:
12
- # 1) Avoid long running commands on the direct board (eg. IR transmission, HTU21D).
13
- # These block the CPU enough that the Rx buffer won't be read in time to avoid overflow.
14
- # 2) Use the lowest practical baud rate on the passthrough board. 19200 is used here, so
15
- # the direct board's Rx buffer takes 6x the time to fill, compared to 115200 baud.
12
+ # 1) Avoid long running commands on the direct board (eg. IR output, WS2812 etc.).
13
+ # These block the CPU enough that the Rx buffer may not be read in time to avoid overflow.
14
+ # 2) Use the lowest practical baud rate on the passthrough board, so the direct board's Rx
15
+ # buffer takes as long as possible to fill, reducing the chance of data loss.
16
16
  #
17
17
  require 'bundler/setup'
18
18
  require 'denko'
19
19
 
20
20
  board1 = Denko::Board.new(Denko::Connection::Serial.new)
21
21
 
22
- uart = Denko::UART::Hardware.new(board: board1, index: 1)
23
- board2 = Denko::Board.new(Denko::Connection::BoardUART.new(uart, baud: 19200))
22
+ uart = Denko::UART::Hardware.new(board: board1, index: 1)
23
+ board2 = Denko::Board.new(Denko::Connection::BoardUART.new(uart, baud: 115200))
24
24
 
25
25
  led1 = Denko::LED.new(board: board1, pin: 13)
26
- led1.blink(0.02)
26
+ led1.blink(0.5)
27
27
 
28
28
  led2 = Denko::LED.new(board: board2, pin: 13)
29
- led2.blink(0.02)
29
+ led2.blink(0.5)
30
30
 
31
- sensor = Denko::AnalogIO::Input.new(board: board1, pin: :A0)
32
- sensor.listen(4)
31
+ input = Denko::AnalogIO::Input.new(board: board2, pin: :A0)
32
+ input.smoothing = true
33
+ input.smoothing_size = 10
34
+ # Show input value only if it differs from previous state.
35
+ input.add_callback do |value|
36
+ puts "A0 value: #{value}" if value != input.state
37
+ end
38
+ input.listen(16)
33
39
 
34
40
  sleep
@@ -1,5 +1,5 @@
1
1
  #
2
- # Example that writes to TX pin of hardware UART1 and reads back on RX pin of same UART.
2
+ # Write to Tx pin of hardware UART1 and read data back on its Rx pin.
3
3
  #
4
4
  require 'bundler/setup'
5
5
  require 'denko'
@@ -0,0 +1,127 @@
1
+ module Denko
2
+ module AnalogIO
3
+ class ADS1100
4
+ include Behaviors::Lifecycle
5
+ include I2C::Peripheral
6
+ include Behaviors::Poller
7
+ include InputHelper
8
+
9
+ I2C_ADDRESS = 0x48
10
+ I2C_FREQUENCY = 400_000
11
+
12
+ # Convert sample rates in samples-per-seconds to their bit representation.
13
+ SAMPLE_RATES = [ # Bitmask
14
+ 128, # 0b00
15
+ 32, # 0b01
16
+ 16, # 0b10
17
+ 8 # 0b11 (default)
18
+ ]
19
+
20
+ # Faster sampling rates have lower resolution.
21
+ BIT_RANGES = [ # Bitmask Bits SPS
22
+ 4_096, # 0b00 12 128
23
+ 16_383, # 0b01 14 32
24
+ 32_767, # 0b10 15 16
25
+ 65_535, # 0b11 16 8
26
+ ]
27
+
28
+ # Wait times need to be slightly longer than the actual sample times.
29
+ WAIT_TIMES = SAMPLE_RATES.map { |rate| (1 / rate.to_f) + 0.0005 }
30
+
31
+ GAINS = [ # Bitmask Full scale voltage
32
+ 1, # 0b00 Vdd
33
+ 2, # 0b01 Vdd / 2
34
+ 4, # 0b10 Vdd / 4
35
+ 8, # 0b11 Vdd / 8
36
+ ]
37
+
38
+ # Default config register:
39
+ # Bit 7 : Start conversion (write 1) | Conversion in progress (read 1)
40
+ # Bit 6-5 : Reserved, must be 00
41
+ # Bit 4 : Conversion mode. 0 = continuous (datasheet default). 1 = single (our default).
42
+ # Bit 3-2 : Sample Rate (see array above)
43
+ # Bit 1-2 : PGA setting (see array above)
44
+ CONFIG_STARTUP = 0b00011100
45
+
46
+ # Masks
47
+ GAIN_CLEAR = 0b11111100
48
+ SAMPLE_RATE_CLEAR = 0b11110011
49
+
50
+ after_initialize do
51
+ # Validate user gave full scale voltage.
52
+ raise ArgumentError "full-scale voltage not a Numeric or not given for ADS1100" unless full_scale_voltage.is_a?(Numeric)
53
+
54
+ i2c_write(config_register)
55
+ sleep WAIT_TIMES[sample_rate_mask]
56
+ end
57
+
58
+ def _read
59
+ # Set bit 7 of the config register and write it to start conversion.
60
+ i2c_write(config_register | (1<<7))
61
+
62
+ # Sleep the right amount of time for conversion, based on sample rate bits.
63
+ sleep WAIT_TIMES[sample_rate_mask]
64
+
65
+ # Read the result, triggering callbacks.
66
+ i2c_read(2)
67
+ end
68
+
69
+ def listen(pin, divider=nil)
70
+ raise StandardError, "ADS1100 does not implement #listen. Use #read or #poll instead"
71
+ end
72
+
73
+ def pre_callback_filter(bytes)
74
+ # Readings are 16-bits, signed, big-endian.
75
+ value = bytes.pack("C*").unpack("s>")[0]
76
+ # Let InputHelper module handle smooothing.
77
+ super(value)
78
+ end
79
+
80
+ # Default to single conversion.
81
+ def config_register
82
+ @config_register ||= CONFIG_STARTUP
83
+ end
84
+
85
+ def sample_rate=(rate)
86
+ raise Argument Error "wrong sample_rate: #{sample_rate.inspect} given for ADS1100" unless SAMPLE_RATES.include?(rate)
87
+ @sample_rate_mask = SAMPLE_RATES.index(rate)
88
+ config_register = (config_register & SAMPLE_RATE_CLEAR) | (sample_rate_mask << 2)
89
+ @sample_rate = rate
90
+ end
91
+
92
+ def sample_rate_mask
93
+ @sample_rate_mask ||= SAMPLE_RATES.index(sample_rate)
94
+ end
95
+
96
+ def sample_rate
97
+ @sample_rate ||= params[:sample_rate] || 8
98
+ end
99
+
100
+ attr_writer :sample_rate_mask
101
+
102
+ def gain=(gain)
103
+ raise ArgumentError "wrong gain: #{gain.inspect} given for ADS1100" unless GAINS.include?(gain)
104
+ @gain_mask = GAINS.index(gain)
105
+ config_register = (config_register & GAIN_CLEAR) | gain_mask
106
+ @gain = gain
107
+ end
108
+
109
+ def gain_mask
110
+ @gain_mask ||= GAINS.index(gain)
111
+ end
112
+
113
+ def gain
114
+ @gain ||= params[:gain] || 1
115
+ end
116
+
117
+ # Unlike some ADS parts, full-scale voltage depends on supply (Vdd). User must specify.
118
+ def full_scale_voltage
119
+ @full_scale_voltage ||= params[:full_scale_voltage]
120
+ end
121
+
122
+ def volts_per_bit
123
+ full_scale_voltage / (GAINS[gain_mask] * BIT_RANGES[sample_rate_mask]).to_f
124
+ end
125
+ end
126
+ end
127
+ end
@@ -1,9 +1,13 @@
1
1
  module Denko
2
2
  module AnalogIO
3
3
  class ADS1115
4
+ include Behaviors::Lifecycle
4
5
  include I2C::Peripheral
5
6
  include ADS111X
6
7
 
8
+ I2C_ADDRESS = 0x48
9
+ I2C_FREQUENCY = 400_000
10
+
7
11
  # Config register values on startup. MSB-first.
8
12
  # Matches datasheet, except MSB bit 7 unset to avoid conversion start.
9
13
  # Same as: [0x05, 0x83] or [5, 131]
@@ -19,42 +23,21 @@ module Denko
19
23
  CONFIG_ADDRESS = 0b01
20
24
  CONVERSION_ADDRESS = 0b00
21
25
 
22
- def before_initialize(options={})
23
- @i2c_address = 0x48
24
- @i2c_frequency = 400_000
25
- super(options)
26
- end
27
-
28
- def after_initialize(options={})
29
- super(options)
30
-
31
- # Mutex and variables for BoardProxy behavior.
32
- @mutex = Mutex.new
33
- @active_pin = nil
34
- @active_gain = nil
35
-
26
+ after_initialize do
36
27
  # Set register bytes to default and write to device.
37
- @config_register = CONFIG_STARTUP.dup
38
- i2c_write [CONFIG_ADDRESS] + @config_register
39
-
40
- # Enable BoardProxy callbacks.
28
+ i2c_write [CONFIG_ADDRESS] + config_register
41
29
  enable_proxy
42
30
  end
43
31
 
44
32
  def _read(config)
45
33
  # Write config register to start reading.
46
34
  i2c_write [CONFIG_ADDRESS] + config
47
-
35
+
48
36
  # Sleep the right amount of time for conversion, based on sample rate bits.
49
37
  sleep WAIT_TIMES[config[1] >> 5]
50
38
 
51
39
  # Read the result, triggering callbacks.
52
- i2c_read(CONVERSION_ADDRESS, 2)
53
- end
54
-
55
- # Readings are 2 bytes big-endian.
56
- def pre_callback_filter(bytes)
57
- bytes.pack("C*").unpack("s>")[0]
40
+ i2c_read(2, register: CONVERSION_ADDRESS)
58
41
  end
59
42
  end
60
43
  end
@@ -1,7 +1,8 @@
1
1
  module Denko
2
2
  module AnalogIO
3
3
  class ADS1118
4
- include SPI::Peripheral
4
+ include SPI::Peripheral::SinglePin
5
+ include Behaviors::Lifecycle
5
6
  include ADS111X
6
7
 
7
8
  # Config register values on startup. MSB-first.
@@ -15,29 +16,19 @@ module Denko
15
16
  BASE_MSB = 0b10000001
16
17
  BASE_LSB = 0b00001010
17
18
 
18
- def after_initialize(options={})
19
- super(options)
20
-
21
- # SPI mode 1 recommended.
22
- @spi_mode = options[:spi_mode] || 1
23
-
24
- # Mutex and variables for BoardProxy behavior.
25
- @mutex = Mutex.new
26
- @active_pin = nil
27
- @active_gain = nil
28
-
29
- # Set register bytes to default and write to device.
30
- @config_register = CONFIG_STARTUP.dup
31
- spi_write(@config_register)
19
+ def spi_mode
20
+ @spi_mode ||= params[:spi_mode] || 1
21
+ end
32
22
 
33
- # Enable BoardProxy callbacks.
23
+ after_initialize do
24
+ spi_write(config_register)
34
25
  enable_proxy
35
26
  end
36
27
 
37
28
  def _read(config)
38
29
  # Write config register to start reading.
39
30
  spi_write(config)
40
-
31
+
41
32
  # Sleep the right amount of time for conversion, based on sample rate bits.
42
33
  sleep WAIT_TIMES[config[1] >> 5]
43
34
 
@@ -45,22 +36,16 @@ module Denko
45
36
  spi_read(2)
46
37
  end
47
38
 
48
- # Pack the 2 bytes back into a string, then unpack as big-endian signed int16.
49
- def pre_callback_filter(message)
50
- bytes = message.split(",").map { |b| b.to_i }
51
- bytes.pack("C*").unpack("s>")[0]
52
- end
53
-
54
39
  def _temperature_read
55
40
  # Wrap in mutex to not interfere with other reads.
56
- @mutex.synchronize do
41
+ mutex.synchronize do
57
42
  _read([0b10000001, 0b10011011])
58
43
  end
59
44
  end
60
45
 
61
46
  def temperature_read(&block)
62
47
  reading = read_using -> { _temperature_read }
63
-
48
+
64
49
  # Temperature is shifted 2 bits left, and is 0.03125 degrees C per bit.
65
50
  temperature = (reading / 4) * 0.03125
66
51
 
@@ -5,6 +5,7 @@ module Denko
5
5
  # Functionality shared among the ADS111X class of ADC converters.
6
6
  #
7
7
  include Behaviors::Reader
8
+ attr_accessor :config_register, :active_pin, :active_gain
8
9
 
9
10
  PGA_SETTINGS = [ # Bitmask Full scale voltage
10
11
  0.0001875, # 0b000 6.144 V
@@ -55,38 +56,43 @@ module Denko
55
56
  def enable_proxy
56
57
  self.add_callback(:board_proxy) do |value|
57
58
  components.each do |component|
58
- if @active_pin == component.pin
59
- component.volts_per_bit = PGA_SETTINGS[@active_gain]
60
- component.update(value)
59
+ if active_pin == component.pin
60
+ component.volts_per_bit = PGA_SETTINGS[active_gain]
61
+ component.update(value)
61
62
  end
62
63
  end
63
64
  end
64
65
  end
65
66
 
67
+ def pre_callback_filter(bytes)
68
+ # Pack the 2 bytes into a string, then unpack as big-endian int16.
69
+ value = bytes.pack("C*").unpack("s>")[0]
70
+ end
71
+
66
72
  def analog_read(pin, negative_pin=nil, gain=nil, sample_rate=nil)
67
73
  # Wrap in mutex so calls and callbacks are atomic.
68
- @mutex.synchronize do
74
+ mutex.synchronize do
69
75
  # Default gain and sample rate.
70
76
  gain ||= 0b010
71
77
  sample_rate ||= 0b100
72
78
 
73
79
  # Set these for callbacks.
74
- @active_pin = pin
75
- @active_gain = gain
80
+ self.active_pin = pin
81
+ self.active_gain = gain
76
82
 
77
83
  # Set gain in upper config register.
78
84
  raise ArgumentError "wrong gain: #{gain.inspect} given for ADS111X" unless PGA_RANGE.include?(gain)
79
- @config_register[0] = self.class::BASE_MSB | (gain << 1)
85
+ config_register[0] = self.class::BASE_MSB | (gain << 1)
80
86
 
81
87
  # Set mux bits in upper config register.
82
88
  mux_bits = pins_to_mux_bits(pin, negative_pin)
83
- @config_register[0] = @config_register[0] | (mux_bits << 4)
89
+ config_register[0] = config_register[0] | (mux_bits << 4)
84
90
 
85
91
  # Set sample rate in lower config_register.
86
- raise ArgumentError "wrong sample_rate: #{sample_rate.inspect} given for ADS111X" unless SAMPLE_RATE_RANGE.include?(gain)
87
- @config_register[1] = self.class::BASE_LSB | (sample_rate << 5)
92
+ raise ArgumentError "wrong sample_rate: #{sample_rate.inspect} given for ADS111X" unless SAMPLE_RATE_RANGE.include?(sample_rate)
93
+ config_register[1] = self.class::BASE_LSB | (sample_rate << 5)
88
94
 
89
- read(@config_register)
95
+ read(config_register)
90
96
  end
91
97
  end
92
98
 
@@ -118,6 +124,14 @@ module Denko
118
124
 
119
125
  def stop_listener(pin)
120
126
  end
127
+
128
+ def mutex
129
+ @mutex ||= Mutex.new
130
+ end
131
+
132
+ def config_register
133
+ @config_register ||= self.class::CONFIG_STARTUP.dup
134
+ end
121
135
  end
122
136
  end
123
137
  end
@@ -2,77 +2,51 @@ module Denko
2
2
  module AnalogIO
3
3
  class Input
4
4
  include Behaviors::InputPin
5
- include Behaviors::Reader
6
5
  include Behaviors::Poller
7
6
  include Behaviors::Listener
8
-
9
- def before_initialize(options={})
10
- options[:board] = options[:adc] if options[:adc]
11
- options[:adc] = nil
12
- super(options)
7
+ include InputHelper
8
+ include Behaviors::Lifecycle
9
+
10
+ before_initialize do
11
+ # Allow giving ADC unit with multiple pins as a board proxy.
12
+ if params[:adc]
13
+ params[:board] = params[:adc]
14
+ params.delete(:adc)
15
+ end
13
16
  end
14
17
 
15
- def after_initialize(options={})
16
- super(options)
17
-
18
- # Default 16ms listener for analog inputs connected to a Board.
19
- @divider = 16
20
-
21
- # If using a negative input on a supported ADC, store the pin.
22
- @negative_pin = options[:negative_pin]
18
+ # Default 16ms listener for analog inputs connected to a Board.
19
+ def divider
20
+ @divider ||= params[:divider] || 16
21
+ end
23
22
 
24
- # If the ADC has a programmable amplifier, pass through its setting.
25
- @gain = options[:gain]
23
+ # Negative input on ADCs that support it.
24
+ def negative_pin
25
+ @negative_pin ||= params[:negative_pin]
26
+ end
26
27
 
27
- # If using a non-default sampling rate, store it.
28
- @sample_rate = options[:sample_rate]
28
+ # PGA gain for ADCs that support it
29
+ def gain
30
+ @gain ||= params[:gain]
31
+ end
29
32
 
30
- # Default to smoothing disabled.
31
- @smoothing = false
32
- @smoothing_set ||= []
33
+ # Sample rates for ADCs that support it.
34
+ def sample_rate
35
+ @sample_rate ||= params[:sample_rate]
33
36
  end
34
37
 
35
- attr_reader :negative_pin, :gain, :sample_rate
38
+ attr_writer :divider, :negative_pin, :gain, :sample_rate
36
39
 
37
- # ADCs can set this based on gain, so exact voltages can be calculated.
40
+ # Allow ADCs to set this, so exact voltages can be calculated.
38
41
  attr_accessor :volts_per_bit
39
42
 
40
43
  def _read
41
44
  board.analog_read(pin, negative_pin, gain, sample_rate)
42
45
  end
43
46
 
44
- def _listen(divider=nil)
45
- @divider = divider || @divider
46
- board.analog_listen(pin, @divider)
47
- end
48
-
49
- # Attach a callback that only fires when state changes.
50
- def on_change(&block)
51
- add_callback(:on_change) do |new_state|
52
- block.call(new_state) if new_state != self.state
53
- end
54
- end
55
-
56
- #
57
- # Smoothing features.
58
- # Does a moving average of the last 8 readings.
59
- #
60
- attr_accessor :smoothing
61
-
62
- def smooth_input(value)
63
- # Add new value, but limit to the 8 latest values.
64
- @smoothing_set << value
65
- @smoothing_set.shift if @smoothing_set.length > 8
66
-
67
- average = @smoothing_set.reduce(:+) / @smoothing_set.length.to_f
68
-
69
- # Round up or down based on previous state to reduce fluctuations.
70
- state && (state > average) ? average.ceil : average.floor
71
- end
72
-
73
- # Convert data to integer, or pass it through smoothing if enabled.
74
- def pre_callback_filter(value)
75
- smoothing ? smooth_input(value.to_i) : value.to_i
47
+ def _listen(div=nil)
48
+ self.divider = div if div
49
+ board.analog_listen(pin, divider)
76
50
  end
77
51
  end
78
52
  end
@@ -0,0 +1,42 @@
1
+ module Denko
2
+ module AnalogIO
3
+ module InputHelper
4
+ #
5
+ # Smoothing features.
6
+ # Does a moving average of the last smoothing_size readings.
7
+ #
8
+ attr_accessor :smoothing, :smoothing_size
9
+
10
+ def smoothing_size
11
+ @smoothing_size ||= 8
12
+ end
13
+
14
+ def smoothing_set
15
+ @smoothing_set ||= []
16
+ end
17
+
18
+ def smooth_input(value)
19
+ # Add new value, but limit to the 8 latest values.
20
+ smoothing_set << value
21
+ smoothing_set.shift while (smoothing_set.length > smoothing_size)
22
+
23
+ average = smoothing_set.reduce(:+) / smoothing_set.length.to_f
24
+
25
+ # Round up or down based on previous state to reduce fluctuations.
26
+ state && (state > average) ? average.ceil : average.floor
27
+ end
28
+
29
+ # Handle smoothing if enabled. Call super(value) after conversion in subclasses.
30
+ def pre_callback_filter(value)
31
+ smoothing ? smooth_input(value.to_i) : value.to_i
32
+ end
33
+
34
+ # Attach a callback that only fires when state changes.
35
+ def on_change(&block)
36
+ add_callback(:on_change) do |new_state|
37
+ block.call(new_state) if new_state != self.state
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -4,12 +4,12 @@ module Denko
4
4
  include Behaviors::OutputPin
5
5
  include Behaviors::Callbacks
6
6
  include Behaviors::Threaded
7
-
7
+ include Behaviors::Lifecycle
8
+
8
9
  interrupt_with :write
9
-
10
- def initialize_pins(options={})
11
- super(options)
12
- self.mode = :output_dac
10
+
11
+ before_initialize do
12
+ params[:mode] = :output_dac
13
13
  end
14
14
 
15
15
  def write(value)
@@ -1,14 +1,12 @@
1
1
  module Denko
2
2
  module AnalogIO
3
- class Potentiometer < Input
4
- def after_initialize(options={})
5
- super(options)
6
-
7
- # Enable smoothing.
8
- self.smoothing = true
3
+ class Potentiometer < Input
4
+ include Behaviors::Lifecycle
9
5
 
10
- # Start listening immediately. Read 2x as often as regular Input.
11
- listen(@divider = 8)
6
+ after_initialize do
7
+ # Enable smoothing and start listening immediately at ~125 Hz.
8
+ self.smoothing = true
9
+ listen(8)
12
10
  end
13
11
  end
14
12
  end
@@ -1,10 +1,11 @@
1
1
  module Denko
2
2
  module AnalogIO
3
+ autoload :InputHelper, "#{__dir__}/analog_io/input_helper"
3
4
  autoload :Input, "#{__dir__}/analog_io/input"
4
5
  autoload :Output, "#{__dir__}/analog_io/output"
5
6
  autoload :Potentiometer, "#{__dir__}/analog_io/potentiometer"
6
- autoload :Sensor, "#{__dir__}/analog_io/sensor"
7
7
  autoload :ADS111X, "#{__dir__}/analog_io/ads111x"
8
+ autoload :ADS1100, "#{__dir__}/analog_io/ads1100"
8
9
  autoload :ADS1115, "#{__dir__}/analog_io/ads1115"
9
10
  autoload :ADS1118, "#{__dir__}/analog_io/ads1118"
10
11
  end
@@ -11,11 +11,23 @@ module Denko
11
11
  0
12
12
  end
13
13
 
14
+ def analog_read_high
15
+ nil
16
+ end
17
+
18
+ def analog_write_high
19
+ nil
20
+ end
21
+
22
+ alias :pwm_high :analog_write_high
23
+ alias :dac_high :analog_write_high
24
+ alias :adc_high :analog_read_high
25
+
14
26
  def convert_pin(pin)
15
27
  pin.to_i
16
28
  end
17
29
 
18
- def set_pin_mode(pin, mode, pull=nil); end
30
+ def set_pin_mode(pin, mode, options={}); end
19
31
 
20
32
  def start_read; end
21
33
  end
@@ -1,6 +1,7 @@
1
1
  module Denko
2
2
  module Behaviors
3
3
  module BusController
4
+ include Component
4
5
  include Subcomponents
5
6
 
6
7
  def mutex
@@ -8,6 +8,7 @@ module Denko
8
8
  if addresses.include? component.address
9
9
  raise ArgumentError, "duplicate peripheral address for #{component}"
10
10
  end
11
+
11
12
  super(component)
12
13
  end
13
14
  end
@@ -2,13 +2,12 @@ module Denko
2
2
  module Behaviors
3
3
  module BusPeripheral
4
4
  include Component
5
+ include Lifecycle
5
6
 
6
- attr_reader :address
7
7
  alias :bus :board
8
8
 
9
- def before_initialize(options={})
10
- options[:board] ||= options[:bus]
11
- super(options)
9
+ before_initialize do
10
+ params[:board] ||= params[:bus]
12
11
  end
13
12
 
14
13
  def atomically(&block)