denko 0.13.6 → 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 (499) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/{build_avr.yml → build_atmega_avr.yml} +19 -18
  3. data/.github/workflows/{build_megaavr.yml → build_atmega_megaavr.yml} +19 -18
  4. data/.github/workflows/{build_sam3x.yml → build_atsam3x.yml} +18 -17
  5. data/.github/workflows/{build_samd.yml → build_atsamd21.yml} +19 -18
  6. data/.github/workflows/build_esp32.yml +19 -18
  7. data/.github/workflows/build_esp32c3.yml +58 -0
  8. data/.github/workflows/build_esp32c6.yml +59 -0
  9. data/.github/workflows/build_esp32h2.yml +58 -0
  10. data/.github/workflows/build_esp32s2.yml +59 -0
  11. data/.github/workflows/build_esp32s3.yml +59 -0
  12. data/.github/workflows/build_esp8266.yml +16 -15
  13. data/.github/workflows/build_ra4m1.yml +17 -16
  14. data/.github/workflows/build_rp2040.yml +19 -17
  15. data/.github/workflows/ruby.yml +20 -20
  16. data/CHANGELOG.md +398 -11
  17. data/DEPS_CLI.md +16 -16
  18. data/DEPS_IDE.md +39 -39
  19. data/MICROCONTROLLERS.md +103 -0
  20. data/PERIPHERALS.md +178 -0
  21. data/README.md +73 -58
  22. data/Rakefile +1 -1
  23. data/build +1 -1
  24. data/denko.gemspec +11 -3
  25. data/lib/denko/analog_io/ads1100.rb +127 -0
  26. data/lib/denko/analog_io/ads1115.rb +8 -25
  27. data/lib/denko/analog_io/ads1118.rb +12 -27
  28. data/lib/denko/analog_io/ads111x.rb +39 -21
  29. data/lib/denko/analog_io/input.rb +29 -55
  30. data/lib/denko/analog_io/input_helper.rb +42 -0
  31. data/lib/denko/analog_io/joystick.rb +87 -0
  32. data/lib/denko/analog_io/output.rb +5 -5
  33. data/lib/denko/analog_io/potentiometer.rb +3 -9
  34. data/lib/denko/analog_io.rb +22 -7
  35. data/lib/denko/behaviors/board_proxy.rb +13 -1
  36. data/lib/denko/behaviors/bus_controller.rb +3 -1
  37. data/lib/denko/behaviors/bus_controller_addressed.rb +1 -0
  38. data/lib/denko/behaviors/bus_peripheral.rb +3 -4
  39. data/lib/denko/behaviors/bus_peripheral_addressed.rb +8 -6
  40. data/lib/denko/behaviors/callbacks.rb +18 -14
  41. data/lib/denko/behaviors/component.rb +12 -14
  42. data/lib/denko/behaviors/input_pin.rb +14 -15
  43. data/lib/denko/behaviors/lifecycle.rb +51 -0
  44. data/lib/denko/behaviors/listener.rb +9 -3
  45. data/lib/denko/behaviors/multi_pin.rb +22 -20
  46. data/lib/denko/behaviors/output_pin.rb +9 -4
  47. data/lib/denko/behaviors/poller.rb +11 -2
  48. data/lib/denko/behaviors/reader.rb +109 -21
  49. data/lib/denko/behaviors/single_pin.rb +3 -4
  50. data/lib/denko/behaviors/state.rb +24 -13
  51. data/lib/denko/behaviors/subcomponents.rb +72 -12
  52. data/lib/denko/behaviors/threaded.rb +19 -8
  53. data/lib/denko/behaviors.rb +36 -22
  54. data/lib/denko/board/core.rb +36 -18
  55. data/lib/denko/board/eeprom.rb +1 -1
  56. data/lib/denko/board/i2c.rb +15 -15
  57. data/lib/denko/board/i2c_bit_bang.rb +53 -0
  58. data/lib/denko/board/infrared.rb +6 -6
  59. data/lib/denko/board/led_array.rb +6 -5
  60. data/lib/denko/board/map.rb +6 -2
  61. data/lib/denko/board/one_wire.rb +3 -3
  62. data/lib/denko/board/spi.rb +35 -30
  63. data/lib/denko/board/spi_bit_bang.rb +14 -15
  64. data/lib/denko/board.rb +41 -36
  65. data/lib/denko/connection/binary_echo.rb +17 -0
  66. data/lib/denko/connection/flow_control.rb +12 -16
  67. data/lib/denko/connection/handshake.rb +2 -0
  68. data/lib/denko/connection/serial.rb +5 -5
  69. data/lib/denko/digital_io/button.rb +4 -0
  70. data/lib/denko/digital_io/c_bit_bang.rb +15 -0
  71. data/lib/denko/digital_io/input.rb +4 -5
  72. data/lib/denko/digital_io/output.rb +19 -10
  73. data/lib/denko/digital_io/pcf8574.rb +114 -0
  74. data/lib/denko/digital_io/relay.rb +2 -0
  75. data/lib/denko/digital_io/rotary_encoder.rb +83 -61
  76. data/lib/denko/digital_io.rb +24 -5
  77. data/lib/denko/display/canvas.rb +350 -157
  78. data/lib/denko/display/font/bmp_5x7.rb +142 -0
  79. data/lib/denko/display/font/bmp_6x8.rb +142 -0
  80. data/lib/denko/display/font/bmp_8x16.rb +141 -0
  81. data/lib/denko/display/font.rb +22 -0
  82. data/lib/denko/display/hd44780.rb +152 -105
  83. data/lib/denko/display/il0373.rb +186 -0
  84. data/lib/denko/display/mono_oled.rb +193 -0
  85. data/lib/denko/display/pcd8544.rb +154 -0
  86. data/lib/denko/display/pixel_common.rb +83 -0
  87. data/lib/denko/display/sh1106.rb +38 -0
  88. data/lib/denko/display/sh1107.rb +10 -0
  89. data/lib/denko/display/spi_common.rb +35 -0
  90. data/lib/denko/display/spi_epaper_common.rb +30 -0
  91. data/lib/denko/display/ssd1306.rb +6 -168
  92. data/lib/denko/display/ssd1680.rb +14 -0
  93. data/lib/denko/display/ssd1681.rb +8 -0
  94. data/lib/denko/display/ssd168x.rb +227 -0
  95. data/lib/denko/display/st7302.rb +207 -0
  96. data/lib/denko/display/st7565.rb +166 -0
  97. data/lib/denko/display.rb +40 -3
  98. data/lib/denko/eeprom/at24c.rb +67 -0
  99. data/lib/denko/eeprom/board.rb +69 -0
  100. data/lib/denko/eeprom.rb +15 -1
  101. data/lib/denko/helpers/engine_check.rb +13 -0
  102. data/lib/denko/helpers/mutex_stub.rb +13 -0
  103. data/lib/denko/helpers.rb +6 -0
  104. data/lib/denko/i2c/bit_bang.rb +32 -0
  105. data/lib/denko/i2c/bus.rb +8 -36
  106. data/lib/denko/i2c/bus_common.rb +50 -0
  107. data/lib/denko/i2c/peripheral.rb +32 -19
  108. data/lib/denko/i2c.rb +17 -2
  109. data/lib/denko/led/apa102.rb +42 -30
  110. data/lib/denko/led/base.rb +13 -2
  111. data/lib/denko/led/rgb.rb +18 -14
  112. data/lib/denko/led/seven_segment.rb +24 -9
  113. data/lib/denko/led/ws2812.rb +10 -7
  114. data/lib/denko/led.rb +17 -8
  115. data/lib/denko/message.rb +5 -0
  116. data/lib/denko/motor/{stepper.rb → a3967.rb} +12 -15
  117. data/lib/denko/motor/l298.rb +11 -10
  118. data/lib/denko/motor/servo.rb +37 -15
  119. data/lib/denko/motor.rb +16 -3
  120. data/lib/denko/one_wire/bus.rb +31 -23
  121. data/lib/denko/one_wire/bus_enumerator.rb +25 -14
  122. data/lib/denko/one_wire/helper.rb +4 -2
  123. data/lib/denko/one_wire/peripheral.rb +0 -3
  124. data/lib/denko/one_wire.rb +18 -5
  125. data/lib/denko/pulse_io/buzzer.rb +11 -9
  126. data/lib/denko/pulse_io/{ir_transmitter.rb → ir_output.rb} +6 -5
  127. data/lib/denko/pulse_io/pwm_output.rb +94 -15
  128. data/lib/denko/pulse_io.rb +17 -3
  129. data/lib/denko/rtc/ds3231.rb +13 -14
  130. data/lib/denko/rtc.rb +14 -1
  131. data/lib/denko/sensor/aht.rb +35 -38
  132. data/lib/denko/sensor/bme280.rb +76 -92
  133. data/lib/denko/sensor/bmp180.rb +46 -48
  134. data/lib/denko/sensor/dht.rb +34 -7
  135. data/lib/denko/sensor/ds18b20.rb +41 -34
  136. data/lib/denko/sensor/hcsr04.rb +7 -5
  137. data/lib/denko/sensor/hdc1080.rb +174 -0
  138. data/lib/denko/sensor/helper.rb +37 -0
  139. data/lib/denko/sensor/htu21d.rb +57 -57
  140. data/lib/denko/sensor/htu31d.rb +36 -36
  141. data/lib/denko/sensor/jsnsr04t.rb +49 -0
  142. data/lib/denko/sensor/qmp6988.rb +34 -48
  143. data/lib/denko/sensor/rcwl9620.rb +3 -5
  144. data/lib/denko/sensor/sht3x.rb +27 -24
  145. data/lib/denko/sensor/sht4x.rb +125 -0
  146. data/lib/denko/sensor/vl53l0x.rb +58 -0
  147. data/lib/denko/sensor.rb +33 -16
  148. data/lib/denko/spi/base_register.rb +25 -21
  149. data/lib/denko/spi/bit_bang.rb +17 -51
  150. data/lib/denko/spi/bus.rb +15 -29
  151. data/lib/denko/spi/bus_common.rb +33 -0
  152. data/lib/denko/spi/input_register.rb +37 -31
  153. data/lib/denko/spi/output_register.rb +33 -39
  154. data/lib/denko/spi/peripheral.rb +81 -14
  155. data/lib/denko/spi.rb +21 -6
  156. data/lib/denko/uart/bit_bang.rb +7 -30
  157. data/lib/denko/uart/common.rb +33 -0
  158. data/lib/denko/uart/hardware.rb +10 -34
  159. data/lib/denko/uart.rb +16 -2
  160. data/lib/denko/version.rb +1 -1
  161. data/lib/denko.rb +23 -16
  162. data/lib/denko_cli/generator.rb +2 -2
  163. data/lib/denko_cli/packages.rb +8 -10
  164. data/lib/denko_cli/targets.rb +13 -13
  165. data/lib/denko_cli/targets.txt +23 -24
  166. data/lib/denko_cli/usage.txt +1 -1
  167. data/src/denko_ethernet.ino +0 -14
  168. data/src/denko_serial.ino +0 -14
  169. data/src/denko_wifi.ino +6 -15
  170. data/src/lib/Denko.cpp +65 -16
  171. data/src/lib/Denko.h +46 -30
  172. data/src/lib/DenkoCoreIO.cpp +57 -102
  173. data/src/lib/DenkoDefines.h +32 -46
  174. data/src/lib/DenkoI2C.cpp +54 -45
  175. data/src/lib/DenkoI2CBB.cpp +238 -0
  176. data/src/lib/DenkoIROut.cpp +12 -7
  177. data/src/lib/DenkoLEDArray.cpp +29 -13
  178. data/src/lib/DenkoSPI.cpp +36 -33
  179. data/src/lib/DenkoSPIBB.cpp +19 -20
  180. data/target.yml +37 -2
  181. data/test/analog_io/input_test.rb +1 -1
  182. data/test/analog_io/potentiometer_test.rb +12 -12
  183. data/test/behaviors/board_proxy_test.rb +1 -1
  184. data/test/behaviors/bus_peripheral_test.rb +4 -4
  185. data/test/behaviors/callbacks_test.rb +28 -10
  186. data/test/behaviors/component_test.rb +32 -14
  187. data/test/behaviors/input_pin_test.rb +14 -9
  188. data/test/behaviors/multi_pin_test.rb +14 -4
  189. data/test/behaviors/output_pin_test.rb +11 -8
  190. data/test/behaviors/poller_test.rb +1 -0
  191. data/test/behaviors/reader_test.rb +3 -2
  192. data/test/behaviors/subcomponents_test.rb +22 -2
  193. data/test/board/board_test.rb +9 -9
  194. data/test/board/core_test.rb +15 -11
  195. data/test/board/i2c_test.rb +39 -33
  196. data/test/board/infrared_test.rb +1 -1
  197. data/test/board/message_test.rb +17 -11
  198. data/test/board/one_wire_test.rb +25 -14
  199. data/test/board/spi_test.rb +45 -29
  200. data/test/digital_io/button_test.rb +15 -0
  201. data/test/digital_io/input_test.rb +2 -2
  202. data/test/digital_io/relay_test.rb +18 -0
  203. data/test/digital_io/rotary_encoder_test.rb +80 -60
  204. data/test/display/canvas_test.rb +306 -0
  205. data/test/display/hd44780_test.rb +34 -7
  206. data/test/eeprom/board_test.rb +45 -0
  207. data/test/helpers/mruby_minitest.rb +95 -0
  208. data/test/helpers/mruby_runner.rb +13 -0
  209. data/test/i2c/bus_test.rb +108 -29
  210. data/test/i2c/peripheral_test.rb +38 -19
  211. data/test/led/apa102_test.rb +24 -0
  212. data/test/led/base_test.rb +2 -1
  213. data/test/led/rgb_test.rb +9 -9
  214. data/test/led/seven_segment_test.rb +7 -7
  215. data/test/motor/{stepper_test.rb → a3967_test.rb} +4 -4
  216. data/test/motor/servo_test.rb +1 -1
  217. data/test/one_wire/bus_enumerator_test.rb +1 -1
  218. data/test/one_wire/bus_test.rb +43 -35
  219. data/test/one_wire/peripheral_test.rb +5 -17
  220. data/test/pulse_io/buzzer_test.rb +7 -4
  221. data/test/pulse_io/{ir_transmitter_test.rb → ir_output_test.rb} +15 -10
  222. data/test/pulse_io/pwm_output_test.rb +74 -18
  223. data/test/rtc/ds3231_test.rb +13 -14
  224. data/test/sensor/dht_test.rb +12 -12
  225. data/test/sensor/ds18b20_test.rb +4 -8
  226. data/test/spi/bitbang_test.rb +27 -0
  227. data/test/spi/bus_test.rb +24 -34
  228. data/test/spi/input_register_test.rb +17 -17
  229. data/test/spi/output_register_test.rb +10 -28
  230. data/test/spi/peripheral_test.rb +73 -0
  231. data/test/test_helper.rb +44 -121
  232. data/vendor/board-maps/BoardMap.h +678 -54
  233. data/vendor/board-maps/lib/header_parser.rb +12 -2
  234. data/vendor/board-maps/yaml/ADAFRUIT_CAMERA_ESP32S3.yml +2 -2
  235. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32C6.yml +15 -0
  236. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32_V2.yml +1 -1
  237. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_RP2040_ADALOGGER.yml +44 -0
  238. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32C3.yml +1 -0
  239. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S2.yml +1 -0
  240. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_N4R2.yml +1 -0
  241. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_NOPSRAM.yml +1 -0
  242. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32_PICO.yml +1 -0
  243. data/vendor/board-maps/yaml/ALFREDO_NOU3.yml +2 -0
  244. data/vendor/board-maps/yaml/AMKEN_BB.yml +48 -0
  245. data/vendor/board-maps/yaml/AMKEN_ES.yml +48 -0
  246. data/vendor/board-maps/yaml/AMKEN_REVELOP.yml +48 -0
  247. data/vendor/board-maps/yaml/AMKEN_REVELOP_PLUS.yml +48 -0
  248. data/vendor/board-maps/yaml/ASL_CAN_X2.yml +41 -0
  249. data/vendor/board-maps/yaml/ATD143_S3.yml +1 -0
  250. data/vendor/board-maps/yaml/BHARATPI_A7672S_4G.yml +14 -0
  251. data/vendor/board-maps/yaml/BHARATPI_LORA.yml +14 -0
  252. data/vendor/board-maps/yaml/BHARATPI_NODE_WIFI.yml +14 -0
  253. data/vendor/board-maps/yaml/BLING.yml +25 -0
  254. data/vendor/board-maps/yaml/BRIDGETEK_IDM2040_7A.yml +48 -0
  255. data/vendor/board-maps/yaml/Bee_Motion_Mini.yml +13 -1
  256. data/vendor/board-maps/yaml/Breadstick_Raspberry.yml +31 -0
  257. data/vendor/board-maps/yaml/CEZERIO_DEV_ESP32C6.yml +14 -0
  258. data/vendor/board-maps/yaml/CEZERIO_MINI_DEV_ESP32C6.yml +12 -0
  259. data/vendor/board-maps/yaml/CIRCUITART_ZERO_S3.yml +71 -0
  260. data/vendor/board-maps/yaml/CODECELLC3.yml +13 -0
  261. data/vendor/board-maps/yaml/CYOBOT_V2_ESP32S3.yml +7 -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/EDGES3D.yml +25 -0
  267. data/vendor/board-maps/yaml/ELECROW_CROWPANEL_7.yml +8 -0
  268. data/vendor/board-maps/yaml/ESP32C2_DEV.yml +12 -0
  269. data/vendor/board-maps/yaml/ESP32C3_DEVKIT_LIPO.yml +14 -0
  270. data/vendor/board-maps/yaml/ESP32C6_DEV.yml +14 -0
  271. data/vendor/board-maps/yaml/ESP32C6_EVB.yml +15 -0
  272. data/vendor/board-maps/yaml/ESP32C6_QWIIC_POCKET.yml +15 -0
  273. data/vendor/board-maps/yaml/ESP32C6_THING_PLUS.yml +14 -0
  274. data/vendor/board-maps/yaml/ESP32H2_DEV.yml +12 -0
  275. data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +12 -0
  276. data/vendor/board-maps/yaml/ESP32P4_DEV.yml +35 -0
  277. data/vendor/board-maps/yaml/{RMP.yml → ESP32S2_DEVKIT_LIPO.yml} +1 -1
  278. data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +43 -0
  279. data/vendor/board-maps/yaml/ESP32S3_DEVKIT_LIPO.yml +42 -0
  280. data/vendor/board-maps/yaml/ESP32S3_POWERFEATHER.yml +22 -0
  281. data/vendor/board-maps/yaml/ESP32_2432S028R.yml +14 -0
  282. data/vendor/board-maps/yaml/ESP32_SBC_FABGL.yml +35 -0
  283. data/vendor/board-maps/yaml/EVN_ALPHA.yml +48 -0
  284. data/vendor/board-maps/yaml/FEATHERS3.yml +1 -1
  285. data/vendor/board-maps/yaml/FEATHERS3NEO.yml +32 -0
  286. data/vendor/board-maps/yaml/FRI3D_2024_ESP32S3.yml +43 -0
  287. data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +13 -0
  288. data/vendor/board-maps/yaml/GEEKBLE_NANO_ESP32S3.yml +25 -0
  289. data/vendor/board-maps/yaml/HELTEC_CAPSULE_SENSOR_V3.yml +43 -0
  290. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E290.yml +41 -0
  291. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_E_213.yml +41 -0
  292. data/vendor/board-maps/yaml/HELTEC_VISION_MASTER_T190.yml +41 -0
  293. data/vendor/board-maps/yaml/HELTEC_WIFI_LORA_32_V3.yml +42 -0
  294. data/vendor/board-maps/yaml/HELTEC_WIRELESS_BRIDGE.yml +8 -0
  295. data/vendor/board-maps/yaml/HELTEC_WIRELESS_MINI_SHELL.yml +13 -0
  296. data/vendor/board-maps/yaml/HELTEC_WIRELESS_PAPER.yml +42 -0
  297. data/vendor/board-maps/yaml/HELTEC_WIRELESS_SHELL_V3.yml +42 -0
  298. data/vendor/board-maps/yaml/HELTEC_WIRELESS_STICK_LITE_V3.yml +30 -0
  299. data/vendor/board-maps/yaml/HELTEC_WIRELESS_TRACKER.yml +41 -0
  300. data/vendor/board-maps/yaml/HT_DE01.yml +42 -0
  301. data/vendor/board-maps/yaml/HUIDU_HD_WF2.yml +5 -0
  302. data/vendor/board-maps/yaml/HUIDU_HD_WF4.yml +1 -0
  303. data/vendor/board-maps/yaml/IMBRIOS_LOGSENS_V1P1.yml +1 -1
  304. data/vendor/board-maps/yaml/LILYGO_LORA_CC1101.yml +6 -0
  305. data/vendor/board-maps/yaml/LILYGO_LORA_LR1121.yml +6 -0
  306. data/vendor/board-maps/yaml/LILYGO_LORA_SI4432.yml +6 -0
  307. data/vendor/board-maps/yaml/LILYGO_LORA_SX1262.yml +6 -0
  308. data/vendor/board-maps/yaml/LILYGO_LORA_SX1280.yml +6 -0
  309. data/vendor/board-maps/yaml/LILYGO_T3S3_LR1121.yml +9 -0
  310. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1262.yml +9 -0
  311. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1276.yml +9 -0
  312. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1278.yml +9 -0
  313. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280.yml +9 -0
  314. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280PA.yml +8 -0
  315. data/vendor/board-maps/yaml/LILYGO_T_ETH_LITE.yml +21 -0
  316. data/vendor/board-maps/yaml/LOLIN_C3_MINI.yml +0 -1
  317. data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +13 -0
  318. data/vendor/board-maps/yaml/LOLIN_S3.yml +1 -0
  319. data/vendor/board-maps/yaml/LOLIN_S3_MINI_PRO.yml +40 -0
  320. data/vendor/board-maps/yaml/Lion_Bit_Dev_Board.yml +0 -2
  321. data/vendor/board-maps/yaml/M5STACK_CAPSULE.yml +8 -0
  322. data/vendor/board-maps/yaml/M5STACK_CARDPUTER.yml +8 -0
  323. data/vendor/board-maps/yaml/M5STACK_DIAL.yml +8 -0
  324. data/vendor/board-maps/yaml/M5STACK_DINMETER.yml +8 -0
  325. data/vendor/board-maps/yaml/M5STACK_FIRE.yml +1 -2
  326. data/vendor/board-maps/yaml/M5STACK_NANOC6.yml +17 -0
  327. data/vendor/board-maps/yaml/M5STACK_PAPER.yml +9 -0
  328. data/vendor/board-maps/yaml/M5STACK_POE_CAM.yml +5 -0
  329. data/vendor/board-maps/yaml/M5STACK_STAMP_C3.yml +13 -0
  330. data/vendor/board-maps/yaml/M5STACK_STAMP_S3.yml +4 -0
  331. data/vendor/board-maps/yaml/{M5Stick_C.yml → M5STACK_STICKC.yml} +0 -1
  332. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS.yml +9 -0
  333. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS2.yml +9 -0
  334. data/vendor/board-maps/yaml/M5STACK_TOUGH.yml +9 -0
  335. data/vendor/board-maps/yaml/M5STACK_UNIT_CAM.yml +10 -0
  336. data/vendor/board-maps/yaml/M5STACK_UNIT_CAMS3.yml +4 -0
  337. data/vendor/board-maps/yaml/M5Stack_ATOM.yml +0 -1
  338. data/vendor/board-maps/yaml/MAKERGO_C3_SUPERMINI.yml +14 -0
  339. data/vendor/board-maps/yaml/MARBLE_PICO.yml +48 -0
  340. data/vendor/board-maps/yaml/METEHOCA_AKANA_R1.yml +46 -0
  341. data/vendor/board-maps/yaml/NAMINO_BIANCO.yml +13 -0
  342. data/vendor/board-maps/yaml/NEBULAS3.yml +0 -1
  343. data/vendor/board-maps/yaml/NEWSAN_ARCHI.yml +48 -0
  344. data/vendor/board-maps/yaml/NOLOGO_ESP32C3_SUPER_MINI.yml +14 -0
  345. data/vendor/board-maps/yaml/NOLOGO_ESP32S3_PICO.yml +12 -0
  346. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_16MB.yml +48 -0
  347. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_2MB.yml +48 -0
  348. data/vendor/board-maps/yaml/OMGS3.yml +25 -0
  349. data/vendor/board-maps/yaml/OPTA_ANALOG.yml +7 -0
  350. data/vendor/board-maps/yaml/OPTA_DIGITAL.yml +5 -0
  351. data/vendor/board-maps/yaml/PCBCUPID_GLYPHC3.yml +23 -0
  352. data/vendor/board-maps/yaml/PCBCUPID_GLYPHC6.yml +32 -0
  353. data/vendor/board-maps/yaml/PCBCUPID_GLYPHH2.yml +24 -0
  354. data/vendor/board-maps/yaml/PINTRONIX_PINMAX.yml +42 -0
  355. data/vendor/board-maps/yaml/REDPILL_ESP32S3.yml +0 -1
  356. data/vendor/board-maps/yaml/SENSEBOX_MCU_ESP32S2.yml +12 -0
  357. data/vendor/board-maps/yaml/SPARKFUN_ESP32S3_THING_PLUS.yml +13 -0
  358. data/vendor/board-maps/yaml/SPARKFUN_MICROMOD_RP2040.yml +48 -0
  359. data/vendor/board-maps/yaml/SPARKFUN_PRO_MICRO_ESP32C3.yml +24 -0
  360. data/vendor/board-maps/yaml/SPARKLEMOTIONMINI_ESP32.yml +12 -0
  361. data/vendor/board-maps/yaml/SPARKLEMOTIONSTICK_ESP32.yml +11 -0
  362. data/vendor/board-maps/yaml/SPARKLEMOTION_ESP32.yml +12 -0
  363. data/vendor/board-maps/yaml/SQUIXL.yml +7 -0
  364. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER.yml +31 -0
  365. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +14 -0
  366. data/vendor/board-maps/yaml/TINYC6.yml +25 -0
  367. data/vendor/board-maps/yaml/T_LORA_PAGER.yml +6 -0
  368. data/vendor/board-maps/yaml/T_WATCH_S3.yml +7 -0
  369. data/vendor/board-maps/yaml/T_WATCH_S3_ULTRA.yml +6 -0
  370. data/vendor/board-maps/yaml/UPESY_EDU_ESP32.yml +28 -0
  371. data/vendor/board-maps/yaml/UPESY_ESP32C3_BASIC.yml +13 -0
  372. data/vendor/board-maps/yaml/UPESY_ESP32C3_MINI.yml +12 -0
  373. data/vendor/board-maps/yaml/UPESY_ESP32S3_BASIC.yml +42 -0
  374. data/vendor/board-maps/yaml/VIRALINK_GATE32_01.yml +6 -0
  375. data/vendor/board-maps/yaml/VIRALINK_GATE32_11.yml +7 -0
  376. data/vendor/board-maps/yaml/WAVESHARE_ESP32S3_TOUCH_LCD_128.yml +8 -0
  377. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_146.yml +41 -0
  378. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_147.yml +41 -0
  379. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_169.yml +38 -0
  380. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_LCD_185.yml +41 -0
  381. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_RELAY_6CH.yml +41 -0
  382. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_143.yml +7 -0
  383. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_164.yml +7 -0
  384. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_18.yml +38 -0
  385. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_191.yml +7 -0
  386. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_AMOLED_241.yml +7 -0
  387. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_146.yml +41 -0
  388. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_169.yml +38 -0
  389. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185.yml +41 -0
  390. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_185_BOX.yml +41 -0
  391. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_21.yml +41 -0
  392. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_28.yml +41 -0
  393. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_4.yml +36 -0
  394. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43.yml +38 -0
  395. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_43B.yml +38 -0
  396. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5.yml +38 -0
  397. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_5B.yml +38 -0
  398. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_TOUCH_LCD_7.yml +38 -0
  399. data/vendor/board-maps/yaml/WAVESHARE_ESP32_S3_ZERO.yml +36 -0
  400. data/vendor/board-maps/yaml/WAVESHARE_RP2040_MATRIX.yml +48 -0
  401. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ONE.yml +1 -0
  402. data/vendor/board-maps/yaml/WAVESHARE_RP2040_PIZERO.yml +47 -0
  403. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ZERO.yml +1 -0
  404. data/vendor/board-maps/yaml/WEACT_STUDIO_ESP32C3.yml +14 -0
  405. data/vendor/board-maps/yaml/WS_ESP32_S3_MATRIX.yml +38 -0
  406. data/vendor/board-maps/yaml/WT32_SC01_PLUS.yml +7 -0
  407. data/vendor/board-maps/yaml/WiFiduinoV2.yml +1 -0
  408. data/vendor/board-maps/yaml/XIAO_ESP32C3.yml +0 -1
  409. data/vendor/board-maps/yaml/XIAO_ESP32C6.yml +22 -0
  410. data/vendor/board-maps/yaml/XIAO_ESP32S3_PLUS.yml +46 -0
  411. data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V2.yml +28 -0
  412. data/vendor/board-maps/yaml/YB_ESP32S3_AMP_V3.yml +28 -0
  413. data/vendor/board-maps/yaml/YB_ESP32S3_ETH.yml +40 -0
  414. data/vendor/board-maps/yaml/mercury.yml +20 -0
  415. data/vendor/board-maps/yaml/unphone9.yml +8 -0
  416. metadata +259 -105
  417. data/.vscode/settings.json +0 -5
  418. data/.vscode/tasks.json +0 -20
  419. data/HARDWARE.md +0 -264
  420. data/benchmarks/i2c_ssd1306_refresh.rb +0 -84
  421. data/examples/advanced/m5_env.rb +0 -48
  422. data/examples/advanced/rotary_encoder_mac_volume.rb +0 -48
  423. data/examples/advanced/ssd1306_time_temp_rh.rb +0 -48
  424. data/examples/analog_io/ads1115.rb +0 -57
  425. data/examples/analog_io/ads1118.rb +0 -73
  426. data/examples/analog_io/dac_loopback.rb +0 -34
  427. data/examples/analog_io/input.rb +0 -55
  428. data/examples/connection/tcp.rb +0 -34
  429. data/examples/digital_io/button.rb +0 -13
  430. data/examples/digital_io/rotary_encoder.rb +0 -26
  431. data/examples/display/hd44780.png +0 -0
  432. data/examples/display/hd44780.rb +0 -39
  433. data/examples/display/ssd1306.rb +0 -40
  434. data/examples/display/ssd1306_s2_pico.rb +0 -29
  435. data/examples/eeprom/built_in.rb +0 -32
  436. data/examples/i2c/search.rb +0 -55
  437. data/examples/led/apa102_bounce.rb +0 -33
  438. data/examples/led/apa102_breathe.rb +0 -45
  439. data/examples/led/builtin_blink.rb +0 -12
  440. data/examples/led/seven_segment_char_echo.rb +0 -15
  441. data/examples/led/ws2812_bounce.rb +0 -32
  442. data/examples/led/ws2812_builtin_blink.rb +0 -21
  443. data/examples/motor/l298.rb +0 -43
  444. data/examples/motor/servo.rb +0 -16
  445. data/examples/motor/stepper.png +0 -0
  446. data/examples/motor/stepper.rb +0 -43
  447. data/examples/pulse_io/buzzer.rb +0 -30
  448. data/examples/pulse_io/ir_transmitter.rb +0 -55
  449. data/examples/rtc/ds3231.rb +0 -48
  450. data/examples/sensor/aht10.rb +0 -19
  451. data/examples/sensor/aht20.rb +0 -19
  452. data/examples/sensor/bme280.rb +0 -38
  453. data/examples/sensor/bmp180.rb +0 -22
  454. data/examples/sensor/dht.rb +0 -24
  455. data/examples/sensor/ds18b20.rb +0 -58
  456. data/examples/sensor/generic_pir.rb +0 -25
  457. data/examples/sensor/hcsr04.rb +0 -14
  458. data/examples/sensor/htu21d.rb +0 -54
  459. data/examples/sensor/htu31d.rb +0 -35
  460. data/examples/sensor/neat_tph_readings.rb +0 -26
  461. data/examples/sensor/qmp6988.rb +0 -53
  462. data/examples/sensor/rcwl9620.rb +0 -15
  463. data/examples/sensor/sht3x.rb +0 -34
  464. data/examples/spi/input_register.rb +0 -50
  465. data/examples/spi/output_register.rb +0 -49
  466. data/examples/spi/ssd_through_register.rb +0 -40
  467. data/examples/spi/two_registers.rb +0 -46
  468. data/examples/uart/bit_bang_read.rb +0 -16
  469. data/examples/uart/bit_bang_write.rb +0 -16
  470. data/examples/uart/board_passthrough.rb +0 -34
  471. data/examples/uart/hardware_loopback.rb +0 -16
  472. data/lib/denko/analog_io/sensor.rb +0 -6
  473. data/lib/denko/eeprom/built_in.rb +0 -69
  474. data/lib/denko/fonts.rb +0 -106
  475. data/lib/denko/sensor/virtual.rb +0 -42
  476. data/src/lib/DenkoIROutESP.cpp +0 -26
  477. data/test/eeprom/built_in_test.rb +0 -61
  478. data/tutorial/01-led/led.fzz +0 -0
  479. data/tutorial/01-led/led.pdf +0 -0
  480. data/tutorial/01-led/led.rb +0 -73
  481. data/tutorial/02-button/button.fzz +0 -0
  482. data/tutorial/02-button/button.pdf +0 -0
  483. data/tutorial/02-button/button.rb +0 -64
  484. data/tutorial/03-potentiometer/potentiometer.fzz +0 -0
  485. data/tutorial/03-potentiometer/potentiometer.pdf +0 -0
  486. data/tutorial/03-potentiometer/potentiometer.rb +0 -62
  487. data/tutorial/04-pwm_led/pwm_led.fzz +0 -0
  488. data/tutorial/04-pwm_led/pwm_led.pdf +0 -0
  489. data/tutorial/04-pwm_led/pwm_led.rb +0 -66
  490. data/tutorial/05-rgb_led/rgb_led.fzz +0 -0
  491. data/tutorial/05-rgb_led/rgb_led.pdf +0 -0
  492. data/tutorial/05-rgb_led/rgb_led.rb +0 -58
  493. data/tutorial/05-rgb_led/rgb_mapping.rb +0 -76
  494. data/vendor/board-maps/yaml/STAMP_S3.yml +0 -8
  495. /data/vendor/board-maps/yaml/{BRIDGETEK_IDM2040-7A.yml → BRIDGETEK_IDM2040_43A.yml} +0 -0
  496. /data/vendor/board-maps/yaml/{heltec_wifi_32_lora_V3.yml → HELTEC_WIRELESS_STICK_V3.yml} +0 -0
  497. /data/vendor/board-maps/yaml/{M5Stack_Core_ESP32.yml → M5STACK_CORE.yml} +0 -0
  498. /data/vendor/board-maps/yaml/{M5Stamp_Pico.yml → M5STACK_STAMP_PICO.yml} +0 -0
  499. /data/vendor/board-maps/yaml/{M5Stack-Timer-CAM.yml → M5STACK_TIMER_CAM.yml} +0 -0
@@ -1,19 +1,21 @@
1
1
  module Denko
2
2
  module Sensor
3
3
  class HCSR04
4
- # Speed of sound in meters per second.
5
- SPEED_OF_SOUND = 343.0
6
-
4
+ include Behaviors::Lifecycle
7
5
  include Behaviors::MultiPin
8
6
  include Behaviors::Poller
9
7
 
8
+ # Speed of sound in meters per second.
9
+ SPEED_OF_SOUND = 343.0
10
+
10
11
  def initialize_pins(options={})
11
12
  proxy_pin :trigger, DigitalIO::Output
12
13
  proxy_pin :echo, DigitalIO::Input
13
14
  end
14
15
 
15
- def after_initialize(options={})
16
- super(options)
16
+ after_initialize do
17
+ # Avoid generating extraneous alerts when used with Denko::PiBoard.
18
+ echo.stop
17
19
 
18
20
  # Receive values from echo pin.
19
21
  echo.add_callback { |data| self.update(data) }
@@ -0,0 +1,174 @@
1
+ module Denko
2
+ module Sensor
3
+ class HDC1080
4
+ include I2C::Peripheral
5
+ include Behaviors::Poller
6
+ include Behaviors::Lifecycle
7
+ include TemperatureHelper
8
+ include HumidityHelper
9
+
10
+ I2C_ADDRESS = 0x40
11
+
12
+ # Config Register
13
+ CONFIG_ADDRESS = 0x02
14
+ CONFIG_DEFAULT = 0x10
15
+ RESET_MASK = 0b10000000
16
+ HEATER_MASK = 0b00100000
17
+ BATTERY_MASK = 0b00001000
18
+
19
+ # Reading registers
20
+ TEMPERATURE_ADDRESS = 0x00
21
+ HUMIDITY_ADDRESS = 0x01
22
+
23
+ def state
24
+ @state ||= { temperature: nil, humidity: nil }
25
+ end
26
+
27
+ def reading
28
+ @reading ||= { temperature: nil, humidity: nil }
29
+ end
30
+
31
+ after_initialize do
32
+ reset
33
+ end
34
+
35
+ def reset
36
+ @config = CONFIG_DEFAULT
37
+ @temperature_resolution = 14
38
+ @humidity_resolution = 14
39
+ write_config(@config | RESET_MASK)
40
+ sleep 0.010
41
+ end
42
+
43
+ def write_config(config=@config)
44
+ # Actually 2 bytes, but 2nd byte is reserved and 0, so ignore it.
45
+ i2c_write [CONFIG_ADDRESS, config, 0]
46
+ end
47
+
48
+ def heater_on?
49
+ (@config & HEATER_MASK) > 0
50
+ end
51
+
52
+ def heater_off?
53
+ !heater_on?
54
+ end
55
+
56
+ def heater_on
57
+ @config |= HEATER_MASK
58
+ write_config
59
+ end
60
+
61
+ def heater_off
62
+ @config &= ~HEATER_MASK
63
+ write_config
64
+ end
65
+
66
+ def battery_low?
67
+ config = i2c_read_raw(2, register: CONFIG_ADDRESS)
68
+ (config[0] & BATTERY_MASK) > 0
69
+ end
70
+
71
+ # Conversion times from datasheet, but not really used.
72
+ TEMPERATURE_RESOLUTION_MASK = 0b00000100
73
+ TEMPERATURE_RESOLUTIONS = {
74
+ 14 => { bits: 0b0, conversion_time: 0.007 },
75
+ 11 => { bits: 0b1, conversion_time: 0.004 },
76
+ }
77
+
78
+ HUMIDITY_RESOLUTION_MASK = 0b00000011
79
+ HUMIDITY_RESOLUTIONS = {
80
+ 14 => { bits: 0b00, conversion_time: 0.007 },
81
+ 11 => { bits: 0b01, conversion_time: 0.004 },
82
+ 8 => { bits: 0b10, conversion_time: 0.003 },
83
+ }
84
+
85
+ attr_reader :temperature_resolution, :humidity_resolution
86
+
87
+ def temperature_resolution=(res)
88
+ raise ArgumentError, "wrong temperature resolution given: #{res}" unless TEMPERATURE_RESOLUTIONS.keys.include? res
89
+ @config &= ~TEMPERATURE_RESOLUTION_MASK
90
+ @config |= (TEMPERATURE_RESOLUTIONS[res][:bits] << 2)
91
+ write_config
92
+ @temperature_resolution = res
93
+ end
94
+
95
+ def humidity_resolution=(res)
96
+ raise ArgumentError, "wrong humidity resolution given: #{res}" unless HUMIDITY_RESOLUTIONS.keys.include? res
97
+ @config &= ~HUMIDITY_RESOLUTION_MASK
98
+ @config |= HUMIDITY_RESOLUTIONS[res][:bits]
99
+ write_config
100
+ @humidity_resolution = res
101
+ end
102
+
103
+ def serial_number
104
+ device_info[:serial_number]
105
+ end
106
+
107
+ def manufacturer_id
108
+ device_info[:manufacturer_id]
109
+ end
110
+
111
+ def device_id
112
+ device_info[:device_id]
113
+ end
114
+
115
+ def device_info
116
+ return @device_info if @device_info
117
+
118
+ man_id_bytes = i2c_read_raw(2, register: 0xFE)
119
+ dev_id_bytes = i2c_read_raw(2, register: 0xFF)
120
+ serial_l = i2c_read_raw(2, register: 0xFD)
121
+ serial_m = i2c_read_raw(2, register: 0xFC)
122
+ serial_h = i2c_read_raw(2, register: 0xFB)
123
+
124
+ @device_info = {
125
+ manufacturer_id: man_id_bytes[0] << 8 | man_id_bytes[1],
126
+ device_id: dev_id_bytes[0] << 8 | dev_id_bytes[1],
127
+ serial_number: serial_h[0] << 32 | serial_h[1] << 24 | serial_m[0] << 16 | serial_m[1] << 8 | serial_l[0],
128
+ }
129
+ end
130
+
131
+ def _read
132
+ _start_conversion
133
+ # This is way more than given conversion times, but unreliable without.
134
+ sleep 0.200
135
+ _read_values
136
+ end
137
+
138
+ def _start_conversion
139
+ # Writing to temperature register triggers both reads.
140
+ i2c_write [TEMPERATURE_ADDRESS]
141
+ end
142
+
143
+ def _read_values
144
+ # Read 2 bytes each for temperature and humidity.
145
+ i2c_read(4)
146
+ end
147
+
148
+ def pre_callback_filter(bytes)
149
+ raw_t = bytes[0] << 8 | bytes[1]
150
+ raw_h = bytes[2] << 8 | bytes[3]
151
+
152
+ reading[:temperature] = ((raw_t.to_f / 2 ** 16) * 165) - 40
153
+ reading[:humidity] = (raw_h.to_f / 2 ** 16) * 100
154
+
155
+ return nil unless (reading[:temperature] && reading[:humidity])
156
+
157
+ reading
158
+ end
159
+
160
+ def update_state(reading)
161
+ @state_mutex.lock
162
+ @state[:temperature] = reading[:temperature]
163
+ @state[:humidity] = reading[:humidity]
164
+ @state_mutex.unlock
165
+
166
+ # Reset so pre_callback_filter can check for both values.
167
+ reading[:temperature] = nil
168
+ reading[:humidity] = nil
169
+
170
+ @state
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,37 @@
1
+ module Denko
2
+ module Sensor
3
+ module TemperatureHelper
4
+ def temperature
5
+ state[:temperature]
6
+ end
7
+
8
+ def temperature_f
9
+ (temperature * 1.8 + 32).round(4)
10
+ end
11
+
12
+ def temperature_k
13
+ temperature + 273.15
14
+ end
15
+ end
16
+
17
+ module PressureHelper
18
+ def pressure
19
+ state[:pressure]
20
+ end
21
+
22
+ def pressure_atm
23
+ pressure / 101325.0
24
+ end
25
+
26
+ def pressure_bar
27
+ pressure / 100000.0
28
+ end
29
+ end
30
+
31
+ module HumidityHelper
32
+ def humidity
33
+ state[:humidity]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -2,7 +2,12 @@ module Denko
2
2
  module Sensor
3
3
  class HTU21D
4
4
  include I2C::Peripheral
5
- include Behaviors::Reader
5
+ include Behaviors::Poller
6
+ include Behaviors::Lifecycle
7
+ include TemperatureHelper
8
+ include HumidityHelper
9
+
10
+ I2C_ADDRESS = 0x40
6
11
 
7
12
  # Commands
8
13
  SOFT_RESET = 0xFE
@@ -15,39 +20,27 @@ module Denko
15
20
  HEATER_MASK = 0b00000100
16
21
  RESOLUTION_MASK = 0b10000001
17
22
 
18
- attr_reader :temperature, :humidity
19
-
20
- def before_initialize(options={})
21
- @i2c_address = 0x40
22
- super(options)
23
- end
24
-
25
- def after_initialize(options={})
26
- super(options)
27
-
28
- # Avoid repeated memory allocation for callback data and state.
29
- @reading = [:temperatue, 0.0]
30
- self.state = { temperature: nil, humidity: nil }
31
- @mutex = Mutex.new
32
-
33
- # Temperature and humidity objects, to treat this like 2 sensors.
34
- @temperature = Temperature.new(self)
35
- @humidity = Humidity.new(self)
36
-
23
+ after_initialize do
37
24
  @config = CONFIG_DEFAULT
38
25
  reset
39
26
  heater_off
40
27
  end
41
28
 
29
+ def state
30
+ @state ||= { temperature: nil, humidity: nil }
31
+ end
32
+
33
+ def reading
34
+ @reading ||= { temperature: nil, humidity: nil }
35
+ end
36
+
42
37
  def reset
43
38
  i2c_write [SOFT_RESET]
44
39
  sleep 0.015
45
40
  end
46
41
 
47
42
  def write_config
48
- @mutex.synchronize do
49
- i2c_write [WRITE_CONFIG, @config]
50
- end
43
+ i2c_write [WRITE_CONFIG, @config]
51
44
  end
52
45
 
53
46
  def heater_on?
@@ -80,7 +73,7 @@ module Denko
80
73
  }
81
74
 
82
75
  def resolution=(setting)
83
- raise ArgumentError, "wrong resolution setting given: #{mask}" unless RESOLUTIONS.keys.include? setting
76
+ raise ArgumentError, "wrong resolution setting given: #{setting}" unless RESOLUTIONS.keys.include? setting
84
77
  @config &= ~RESOLUTION_MASK
85
78
  @config |= setting
86
79
  write_config
@@ -92,61 +85,68 @@ module Denko
92
85
  RESOLUTIONS[resolution_bits]
93
86
  end
94
87
 
95
- def [](key)
96
- @state_mutex.synchronize do
97
- return @state[key]
98
- end
88
+ def temperature_resolution
89
+ resolution[:temperature]
99
90
  end
100
-
101
- def read_temperature
102
- @mutex.synchronize do
103
- result = read_using -> { i2c_read(READ_TEMPERATURE_BLOCKING, 3) }
104
- result[1] if result
105
- end
91
+
92
+ def humidity_resolution
93
+ resolution[:humidity]
106
94
  end
107
95
 
108
- def read_humidity
109
- @mutex.synchronize do
110
- result = read_using -> { i2c_read(READ_HUMIDITY_BLOCKING, 3) }
111
- result[1] if result
112
- end
96
+ # Workaround for :read callbacks getting automatically removed on first reading.
97
+ def read(*args, **kwargs, &block)
98
+ read_using(self.method(:_read_temperature), *args, **kwargs)
99
+ read_using(self.method(:_read_humidity), *args, **kwargs, &block)
100
+ end
101
+
102
+ def _read
103
+ _read_temperature
104
+ _read_humidity
105
+ end
106
+
107
+ def _read_temperature
108
+ i2c_read(3, register: READ_TEMPERATURE_BLOCKING)
109
+ end
110
+
111
+ def _read_humidity
112
+ i2c_read(3, register: READ_HUMIDITY_BLOCKING)
113
113
  end
114
114
 
115
115
  def pre_callback_filter(bytes)
116
116
  # Raw value is first 2 bytes big-endian.
117
117
  raw_value = (bytes[0] << 8) | bytes[1]
118
-
119
- # Quietly ignore readings with bad CRC.
120
- unless calculate_crc(raw_value) == bytes[2]
121
- @humidity.update(nil)
122
- @temperature.update(nil)
123
- return nil
124
- end
118
+ return { error: 'CRC failure' } unless calculate_crc(raw_value) == bytes[2]
125
119
 
126
120
  # Lowest 2 bits must be zeroed before conversion.
127
121
  raw_value = raw_value & 0xFFFC
128
122
 
129
- # Bit 1 of LSB determines type of reading; 0 for temperature, 1 for humidity.
123
+ # Bit 1 of LS byte determines type of reading; 0 for temperature, 1 for humidity.
130
124
  if (bytes[1] & 0b00000010) > 0
131
125
  # Calculate humidity and limit within 0-100 range.
132
126
  humidity = (raw_value.to_f / 524.288) - 6
133
127
  humidity = 0.0 if humidity < 0.0
134
128
  humidity = 100.0 if humidity > 100.0
135
- @reading[0] = :humidity
136
- @reading[1] = humidity
137
- @humidity.update(@reading[1])
129
+ reading[:humidity] = humidity
138
130
  else
139
- @reading[0] = :temperature
140
- @reading[1] = (175.72 * raw_value.to_f / 65536) - 46.8
141
- @temperature.update(@reading[1])
131
+ reading[:temperature] = (175.72 * raw_value.to_f / 65536) - 46.8
142
132
  end
143
- @reading
133
+
134
+ return nil unless (reading[:temperature] && reading[:humidity])
135
+
136
+ reading
144
137
  end
145
138
 
146
139
  def update_state(reading)
147
- @state_mutex.synchronize do
148
- @state[reading[0]] = reading[1]
149
- end
140
+ @state_mutex.lock
141
+ @state[:temperature] = reading[:temperature]
142
+ @state[:humidity] = reading[:humidity]
143
+ @state_mutex.unlock
144
+
145
+ # Reset so pre_callback_filter can check for both values.
146
+ reading[:temperature] = nil
147
+ reading[:humidity] = nil
148
+
149
+ @state
150
150
  end
151
151
 
152
152
  #
@@ -3,6 +3,11 @@ module Denko
3
3
  class HTU31D
4
4
  include I2C::Peripheral
5
5
  include Behaviors::Poller
6
+ include Behaviors::Lifecycle
7
+ include TemperatureHelper
8
+ include HumidityHelper
9
+
10
+ I2C_ADDRESS = 0x40
6
11
 
7
12
  # Commands
8
13
  RESET = 0x1E
@@ -53,20 +58,20 @@ module Denko
53
58
  3 => 0.01198 * CONVERSION_SAFETY_FACTOR,
54
59
  }
55
60
 
56
- def before_initialize(options={})
57
- @i2c_address = 0x40
58
- super(options)
61
+ def resolutions
62
+ @resolutions ||= { temperature: 0, humidity: 0 }
59
63
  end
60
64
 
61
- def after_initialize(options={})
62
- super(options)
65
+ after_initialize do
66
+ reset
67
+ end
63
68
 
64
- # Avoid repeated memory allocation for callback data and state.
65
- @reading = { temperature: nil, humidity: nil }
66
- self.state = { temperature: nil, humidity: nil }
67
- @resolutions = { temperature: 0, humidity: 0 }
69
+ def state
70
+ @state ||= { temperature: nil, humidity: nil }
71
+ end
68
72
 
69
- reset
73
+ def reading
74
+ @reading ||= { temperature: nil, humidity: nil }
70
75
  end
71
76
 
72
77
  def reset
@@ -82,7 +87,7 @@ module Denko
82
87
  def heater_off?
83
88
  !@heater_on
84
89
  end
85
-
90
+
86
91
  def heater_on
87
92
  i2c_write [HEATER_ON]
88
93
  @heater_on = true
@@ -92,31 +97,25 @@ module Denko
92
97
  i2c_write [HEATER_OFF]
93
98
  @heater_on = false
94
99
  end
95
-
100
+
96
101
  def temperature_resolution
97
- @resolutions[:temperature]
102
+ resolutions[:temperature]
98
103
  end
99
104
 
100
105
  def temperature_resolution=(setting)
101
106
  raise ArgumentError, "wrong resolution given: #{setting}. Must be in range 0..3" unless (0..3).include?(setting)
102
- @resolutions[:temperature] = setting
107
+ resolutions[:temperature] = setting
103
108
  end
104
-
109
+
105
110
  def humidity_resolution
106
- @resolutions[:humidity]
111
+ resolutions[:humidity]
107
112
  end
108
-
113
+
109
114
  def humidity_resolution=(setting)
110
115
  raise ArgumentError, "wrong resolution given: #{setting}. Must be in range 0..3" unless (0..3).include?(setting)
111
- @resolutions[:humidity] = setting
116
+ resolutions[:humidity] = setting
112
117
  end
113
118
 
114
- def [](key)
115
- @state_mutex.synchronize do
116
- return @state[key]
117
- end
118
- end
119
-
120
119
  def _read
121
120
  # Calculate total conversion time.
122
121
  conversion_time = T_CONVERSION_TIMES[temperature_resolution] +
@@ -130,7 +129,7 @@ module Denko
130
129
  sleep conversion_time
131
130
 
132
131
  # Write the read command and read back 6 bytes.
133
- i2c_read(READ_T_AND_H, 6)
132
+ i2c_read(6, register: READ_T_AND_H)
134
133
  end
135
134
 
136
135
  def pre_callback_filter(bytes)
@@ -139,29 +138,30 @@ module Denko
139
138
  # Temperature
140
139
  t_raw = (bytes[0] << 8) | bytes[1]
141
140
  if calculate_crc(t_raw) != bytes[2]
142
- @reading[:temperature] = nil
141
+ reading[:temperature] = nil
143
142
  else
144
- @reading[:temperature] = (165 * t_raw.to_f / 65535) - 40
143
+ reading[:temperature] = (165 * t_raw.to_f / 65535) - 40
145
144
  end
146
145
 
147
146
  # Humidity
148
147
  h_raw = (bytes[3] << 8) | bytes[4]
149
148
  if calculate_crc(h_raw) != bytes[5]
150
- @reading[:humidity] = nil
149
+ reading[:humidity] = nil
151
150
  else
152
- @reading[:humidity] = h_raw.to_f / 655.35
151
+ reading[:humidity] = h_raw.to_f / 655.35
153
152
  end
154
153
 
155
154
  # Ignore entire reading if either CRC failed.
156
- return nil unless (@reading[:temperature] && @reading[:humidity])
157
- @reading
155
+ return nil unless (reading[:temperature] && reading[:humidity])
156
+ reading
158
157
  end
159
-
158
+
160
159
  def update_state(reading)
161
- @state_mutex.synchronize do
162
- @state[:temperature] = reading[:temperature]
163
- @state[:humidity] = reading[:humidity]
164
- end
160
+ @state_mutex.lock
161
+ @state[:temperature] = reading[:temperature]
162
+ @state[:humidity] = reading[:humidity]
163
+ @state_mutex.unlock
164
+ @state
165
165
  end
166
166
 
167
167
  #
@@ -0,0 +1,49 @@
1
+ module Denko
2
+ module Sensor
3
+ #
4
+ # For JSN-SR04T sensor in mode 2 ONLY.
5
+ #
6
+ class JSNSR04T
7
+ include Behaviors::Component
8
+ include Behaviors::Lifecycle
9
+ include Behaviors::Poller
10
+
11
+ UART_CLASSES = [Denko::UART::Hardware, Denko::UART::BitBang]
12
+ TIMEOUT = 0.500
13
+
14
+ attr_reader :uart
15
+
16
+ after_initialize do
17
+ unless params[:uart] && UART_CLASSES.include?(params[:uart].class)
18
+ raise ArgumentError, "JSN-SR04T driver only works in mode 2, and expects a UART in the :uart key"
19
+ end
20
+
21
+ raise StandardError, "UART baud must be 9600 for JSN-SR04T" unless params[:uart].baud == 9600
22
+
23
+ @uart = params[:uart]
24
+ end
25
+
26
+ def _read
27
+ # Trigger read
28
+ uart.write("U")
29
+
30
+ # Get line from UART
31
+ start = Time.now
32
+ line = nil
33
+ until line || (Time.now - start > TIMEOUT)
34
+ line = uart.gets
35
+ sleep 0.010
36
+ end
37
+
38
+ # Extract mm as integer
39
+ if line && line.strip.end_with?("mm")
40
+ value = line.gsub("mm").strip.to_i
41
+ self.update(value)
42
+ return value
43
+ end
44
+
45
+ return nil
46
+ end
47
+ end
48
+ end
49
+ end