denko 0.13.6 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
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)