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
@@ -3,7 +3,13 @@ module Denko
3
3
  class BME280
4
4
  include I2C::Peripheral
5
5
  include Behaviors::Poller
6
-
6
+ include Behaviors::Lifecycle
7
+ include TemperatureHelper
8
+ include PressureHelper
9
+ include HumidityHelper
10
+
11
+ I2C_ADDRESS = 0x76
12
+
7
13
  # Reading Mode Settings
8
14
  SLEEP_MODE = 0b00
9
15
  ONESHOT_MODE = 0b01 # 0b10 is also valid. Called "forced mode" in datasheet.
@@ -38,8 +44,8 @@ module Denko
38
44
  8 => 0b100,
39
45
  16 => 0b101, # 0b110 and 0b111 are also valid for 16x.
40
46
  }
41
-
42
- # IIR Filter Coefficients
47
+
48
+ # IIR Filter Coefficients
43
49
  IIR_COEFFICIENTS = {
44
50
  0 => 0b000,
45
51
  2 => 0b001,
@@ -47,19 +53,8 @@ module Denko
47
53
  8 => 0b011,
48
54
  16 => 0b100, # 0b101, 0b110 and 0b111 are also valid for 16.
49
55
  }
50
-
51
- def before_initialize(options={})
52
- @i2c_address = 0x76
53
- super(options)
54
- end
55
-
56
- def after_initialize(options={})
57
- super(options)
58
-
59
- # Avoid repeated memory allocation for callback data and state.
60
- @reading = { temperature: nil, humidity: nil, pressure: nil }
61
- self.state = { temperature: nil, humidity: nil, pressure: nil }
62
56
 
57
+ after_initialize do
63
58
  #
64
59
  # Setup defaults for the config registers:
65
60
  # Oneshot reading mode
@@ -72,7 +67,7 @@ module Denko
72
67
  # Bits 2..4 control the pressure oversampling factor
73
68
  # Bits 5..7 control the temperature oversampling factor.
74
69
  f4: 0b00100110,
75
-
70
+
76
71
  # Bits 0..1 should always be 0.
77
72
  # Bits 2..4 control the IIR filter coefficient.
78
73
  # Bits 5..7 control the standby time when in continuous reading mode.
@@ -81,10 +76,18 @@ module Denko
81
76
  # Bits 0..2 control the humidity oversampling factor, on BME280 only.
82
77
  # Bits 3+ are unused.
83
78
  @registers.merge!(f2: 0b00000001) if humidity_available?
84
-
79
+
85
80
  @calibration_data_loaded = false
86
81
  end
87
82
 
83
+ def state
84
+ @state ||= { temperature: nil, humidity: nil, pressure: nil }
85
+ end
86
+
87
+ def reading
88
+ @reading ||= { temperature: nil, humidity: nil, pressure: nil }
89
+ end
90
+
88
91
  #
89
92
  # Configuration Methods
90
93
  #
@@ -94,7 +97,7 @@ module Denko
94
97
  end
95
98
 
96
99
  attr_reader :measurement_time
97
-
100
+
98
101
  def update_measurement_time
99
102
  t_oversampling = 2 ** (((@registers[:f4] & 0b11100000) >> 5) - 1)
100
103
  p_oversampling = 2 ** (((@registers[:f4] & 0b00011100) >> 2) - 1)
@@ -110,59 +113,59 @@ module Denko
110
113
  # Milliseconds to seconds
111
114
  @measurement_time = @measurement_time / 1000
112
115
  end
113
-
116
+
114
117
  def continuous_mode
115
118
  @registers[:f4] = (@registers[:f4] & 0b11111100) | CONTINUOUS_MODE
116
- write_settings
119
+ write_settings
117
120
  end
118
-
121
+
119
122
  def standby_time=(ms)
120
123
  raise ArgumentError, "invalid standby time: #{ms}" unless self.class::STANDBY_TIMES.keys.include? ms
121
124
 
122
125
  @registers[:f5] = (@registers[:f5] & 0b00011111) | (self.class::STANDBY_TIMES[ms] << 5)
123
126
  write_settings
124
127
  end
125
-
128
+
126
129
  def temperature_samples=(factor)
127
130
  raise ArgumentError, "invalid oversampling factor: #{factor}" unless OVERSAMPLE_FACTORS.keys.include? factor
128
131
  raise ArgumentError, "temperature must be read. Invalid oversampling factor: #{factor}" if factor == 0
129
-
132
+
130
133
  @registers[:f4] = (@registers[:f4] & 0b00011111) | (OVERSAMPLE_FACTORS[factor] << 5)
131
134
  write_settings
132
135
  end
133
-
136
+
134
137
  def pressure_samples=(factor)
135
138
  raise ArgumentError, "invalid oversampling factor: #{factor}" unless OVERSAMPLE_FACTORS.keys.include? factor
136
-
139
+
137
140
  @registers[:f4] = (@registers[:f4] & 0b11100011) | (OVERSAMPLE_FACTORS[factor] << 2)
138
141
  write_settings
139
142
  end
140
-
143
+
141
144
  def humidity_samples=(factor)
142
145
  raise ArgumentError, "invalid oversampling factor: #{factor}" unless OVERSAMPLE_FACTORS.keys.include? factor
143
-
146
+
144
147
  @registers[:f2] = (@registers[:f2] & 0b11111000) | OVERSAMPLE_FACTORS[factor]
145
148
  write_settings
146
149
  end
147
-
150
+
148
151
  def iir_coefficient=(coeff)
149
152
  raise ArgumentError, "invalid IIR coefficient: #{coeff}" unless IIR_COEFFICIENTS.keys.include? coeff
150
-
153
+
151
154
  @registers[:f5] = (@registers[:f5] & 0b11100011) | (IIR_COEFFICIENTS[coeff] << 2)
152
155
  write_settings
153
156
  end
154
-
157
+
155
158
  def write_settings
156
159
  if humidity_available?
157
- i2c_write [0xF2, @registers[:f2], 0xF4, @registers[:f4], 0xF5, @registers[:f5]]
160
+ i2c_write [0xF2, @registers[:f2], 0xF4, @registers[:f4], 0xF5, @registers[:f5]]
158
161
  else
159
162
  i2c_write [0xF4, @registers[:f4], 0xF5, @registers[:f5]]
160
163
  end
161
164
  update_measurement_time
162
165
  end
163
-
166
+
164
167
  def config_register_bits
165
- str = ""
168
+ str = String.new
166
169
  @registers.each_key do |key|
167
170
  str << "0x#{key.upcase}: #{@registers[key].to_s(2).rjust(8, '0')}\n"
168
171
  end
@@ -171,64 +174,43 @@ module Denko
171
174
 
172
175
  #
173
176
  # Reading Methods
174
- #
177
+ #
175
178
  def _read
176
179
  get_calibration_data unless calibration_data_loaded
177
180
  write_settings
178
- i2c_read 0xF7, 8
181
+ i2c_read 8, register: 0xF7
179
182
  end
180
-
181
- def pre_callback_filter(data)
182
- if data.length == 8
183
- return decode_reading(data)
184
- elsif data.length == 26
185
- process_calibration_a(data)
186
- return nil
187
- elsif data.length == 7
188
- process_calibration_b(data)
189
- return nil
190
- else
191
- # Ignores readings that aren't 8 bytes.
192
- return nil
193
- end
183
+
184
+ def pre_callback_filter(bytes)
185
+ return nil unless bytes.length == 8
186
+
187
+ # Always read temperature since t_fine is needed to calibrate other values.
188
+ temperature, t_fine = decode_temperature(bytes)
189
+ reading[:temperature] = temperature
190
+
191
+ # Pressure and humidity are optional. Humidity is not available on the BMP280.
192
+ reading[:pressure] = decode_pressure(bytes, t_fine) if reading_pressure?
193
+ reading[:humidity] = decode_humidity(bytes, t_fine) if reading_humidity?
194
+
195
+ reading
194
196
  end
195
-
197
+
196
198
  def update_state(reading)
197
- # Checking for Hash ignores calibration data and nil.
198
- if reading.class == Hash
199
- @state_mutex.synchronize do
200
- @state[:temperature] = reading[:temperature]
201
- @state[:pressure] = reading[:pressure]
202
- @state[:humidity] = reading[:humidity]
203
- end
204
- end
199
+ @state_mutex.lock
200
+ @state[:temperature] = reading[:temperature]
201
+ @state[:pressure] = reading[:pressure]
202
+ @state[:humidity] = reading[:humidity]
203
+ @state_mutex.unlock
204
+ @state
205
205
  end
206
206
 
207
- def [](key)
208
- @state_mutex.synchronize do
209
- return @state[key]
210
- end
211
- end
212
-
213
207
  #
214
208
  # Decoding Methods
215
209
  #
216
- def decode_reading(bytes)
217
- # Always read temperature since t_fine is needed to calibrate other values.
218
- temperature, t_fine = decode_temperature(bytes)
219
- @reading[:temperature] = temperature
220
-
221
- # Pressure and humidity are optional. Humidity is not available on the BMP280.
222
- @reading[:pressure] = decode_pressure(bytes, t_fine) if reading_pressure?
223
- @reading[:humidity] = decode_humidity(bytes, t_fine) if reading_humidity?
224
-
225
- @reading
226
- end
227
-
228
210
  def decode_temperature(bytes)
229
211
  # Reformat raw temeprature bytes (20-bits in 24) to uint32.
230
212
  adc_t = ((bytes[3] << 16) | (bytes[4] << 8) | (bytes[5])) >> 4
231
-
213
+
232
214
  # Floating point temperature calculation from datasheet. Result in degrees Celsius.
233
215
  var1 = (adc_t / 16384.0 - @calibration[:t1] / 1024.0) * @calibration[:t2]
234
216
  var2 = (adc_t / 131072.0 - @calibration[:t1] / 8192.0) ** 2 * @calibration[:t3]
@@ -236,11 +218,11 @@ module Denko
236
218
  temperature = (var1 + var2) / 5120.0
237
219
  [temperature, t_fine]
238
220
  end
239
-
221
+
240
222
  def decode_pressure(bytes, t_fine)
241
223
  # Reformat raw pressure bytes (20-bits in 24) to uint32.
242
224
  adc_p = ((bytes[0] << 16) | (bytes[1] << 8) | (bytes[2])) >> 4
243
-
225
+
244
226
  # Floating point pressure calculation from datasheet. Result in Pascals.
245
227
  var1 = (t_fine / 2.0) - 64000.0
246
228
  var2 = var1 * var1 * @calibration[:p6] / 32768.0
@@ -259,11 +241,11 @@ module Denko
259
241
  end
260
242
  pressure
261
243
  end
262
-
244
+
263
245
  def decode_humidity(bytes, t_fine)
264
246
  # Raw data for humidity is big-endian uint16.
265
247
  adc_h = (bytes[6] << 8) | bytes[7]
266
-
248
+
267
249
  # Floating point humidity calculation from datasheet. Result in % RH.
268
250
  humidity = t_fine - 76800.0
269
251
  humidity = (adc_h - (@calibration[:h4] * 64.0 + @calibration[:h5] / 16384.0 * humidity)) *
@@ -278,30 +260,32 @@ module Denko
278
260
  # Bits 2..4 of 0xF4 register must not be 0.
279
261
  (@registers[:f4] >> 2 & 0b111) != OVERSAMPLE_FACTORS[0]
280
262
  end
281
-
263
+
282
264
  def reading_humidity?
283
265
  return false unless humidity_available?
284
266
  # Lowest 3 bits of 0xF2 register must not be 0.
285
267
  (@registers[:f2] & 0b111) != OVERSAMPLE_FACTORS[0]
286
268
  end
287
-
269
+
288
270
  # No humidity on the BMP280.
289
271
  def humidity_available?
290
- !self.class.to_s.match(/bmp/i)
272
+ self.class.name.split('::').last.downcase.start_with? "bme"
291
273
  end
292
-
274
+
293
275
  #
294
276
  # Calibration Methods
295
277
  #
296
278
  attr_reader :calibration_data_loaded
297
-
298
- def get_calibration_data
299
- # First group of calibration bytes, sent to #process_calibration_a.
300
- read_using -> { i2c_read(0x88, 26) }
301
279
 
302
- # Second group of calibration bytes, only on BME280, sent to #process_calibration_b.
280
+ def get_calibration_data
281
+ # Calibration A
282
+ cal_a_bytes = i2c_read_raw(26, register: 0x88)
283
+ process_calibration_a(cal_a_bytes) if cal_a_bytes
284
+
285
+ # Calibration B, only on BME280.
303
286
  if humidity_available?
304
- read_using -> { i2c_read 0xE1, 7 }
287
+ cal_b_bytes = i2c_read_raw(7, register: 0xE1)
288
+ process_calibration_b(cal_b_bytes) if cal_b_bytes
305
289
  end
306
290
 
307
291
  if (@calibration[:cal_a] && @calibration[:cal_b]) || (@calibration[:cal_a] && !humidity_available?)
@@ -345,7 +329,7 @@ module Denko
345
329
  end
346
330
  end
347
331
  end
348
-
332
+
349
333
  #
350
334
  # BMP280 is mostly compatible with BME280, except for a few changes.
351
335
  #
@@ -3,7 +3,12 @@ module Denko
3
3
  class BMP180
4
4
  include I2C::Peripheral
5
5
  include Behaviors::Poller
6
-
6
+ include Behaviors::Lifecycle
7
+ include TemperatureHelper
8
+ include PressureHelper
9
+
10
+ I2C_ADDRESS = 0x77
11
+
7
12
  # Write this to register 0xE0 for soft reset
8
13
  SOFT_RESET = 0xB6
9
14
 
@@ -20,18 +25,7 @@ module Denko
20
25
  8 => 0b11,
21
26
  }
22
27
 
23
- def before_initialize(options={})
24
- @i2c_address = 0x77
25
- super(options)
26
- end
27
-
28
- def after_initialize(options={})
29
- super(options)
30
-
31
- # Avoid repeated memory allocation for callback data and state.
32
- @reading = { temperature: nil, pressure: nil }
33
- self.state = { temperature: nil, pressure: nil }
34
-
28
+ after_initialize do
35
29
  # Default to start conversion off, reading temperature, no pressure oversampling.
36
30
  @register = 0b00001110
37
31
  @calibration_data_loaded = false
@@ -43,6 +37,14 @@ module Denko
43
37
  soft_reset
44
38
  end
45
39
 
40
+ def state
41
+ @state ||= { temperature: nil, pressure: nil }
42
+ end
43
+
44
+ def reading
45
+ @reading ||= { temperature: nil, pressure: nil }
46
+ end
47
+
46
48
  #
47
49
  # Configuration Methods
48
50
  #
@@ -51,7 +53,7 @@ module Denko
51
53
  end
52
54
 
53
55
  attr_reader :measurement_time
54
-
56
+
55
57
  def update_measurement_time
56
58
  # Get oversample bits from current register setting.
57
59
  oversample_exponent = (@register & 0b11000000) >> 6
@@ -69,7 +71,7 @@ module Denko
69
71
  raise ArgumentError, "invalid oversampling factor: #{factor}" unless OVERSAMPLE_FACTORS.keys.include? factor
70
72
  @oss = OVERSAMPLE_FACTORS[factor]
71
73
  end
72
-
74
+
73
75
  def write_settings
74
76
  update_measurement_time
75
77
  i2c_write [0xF4, @register]
@@ -78,26 +80,33 @@ module Denko
78
80
  #
79
81
  # Reading Methods
80
82
  #
81
- def _start_read_temperature
83
+ def _read_temperature
82
84
  @register = 0x2E
83
85
  write_settings
86
+ sleep(@measurement_time)
87
+ i2c_read(2, register: 0xF6)
84
88
  end
85
89
 
86
- def _start_read_pressure
90
+ def _read_pressure
87
91
  @register = 0x34 | (@oss << 6)
88
92
  write_settings
93
+ sleep(@measurement_time)
94
+ i2c_read(3, register: 0xF6)
89
95
  end
90
96
 
91
- def _read
97
+ # Workaround for :read callbacks getting automatically removed on first reading.
98
+ def read(*args, **kwargs, &block)
92
99
  get_calibration_data unless calibration_data_loaded
93
100
 
94
- _start_read_temperature
95
- sleep(@measurement_time)
96
- i2c_read 0xF6, 2
101
+ read_using(self.method(:_read_temperature), *args, **kwargs)
102
+ read_using(self.method(:_read_pressure), *args, **kwargs, &block)
103
+ end
97
104
 
98
- _start_read_pressure
99
- sleep(@measurement_time)
100
- i2c_read 0xF6, 3
105
+ def _read
106
+ get_calibration_data unless calibration_data_loaded
107
+
108
+ _read_temperature
109
+ _read_pressure
101
110
  end
102
111
 
103
112
  def pre_callback_filter(data)
@@ -111,9 +120,6 @@ module Denko
111
120
  @raw_bytes[3] = data[1]
112
121
  @raw_bytes[4] = data[2]
113
122
  return decode_reading(@raw_bytes)
114
- # Calibration data is 22 bytes.
115
- elsif data.length == 22
116
- process_calibration(data)
117
123
  end
118
124
 
119
125
  # Anything other than pressure avoids callbacks.
@@ -121,29 +127,21 @@ module Denko
121
127
  end
122
128
 
123
129
  def update_state(reading)
124
- # Checking for Hash ignores calibration data and nil.
125
- if reading.class == Hash
126
- @state_mutex.synchronize do
127
- @state[:temperature] = reading[:temperature]
128
- @state[:pressure] = reading[:pressure]
129
- end
130
- end
130
+ @state_mutex.lock
131
+ @state[:temperature] = reading[:temperature]
132
+ @state[:pressure] = reading[:pressure]
133
+ @state_mutex.unlock
134
+ @state
131
135
  end
132
136
 
133
- def [](key)
134
- @state_mutex.synchronize do
135
- return @state[key]
136
- end
137
- end
138
-
139
137
  #
140
138
  # Decoding Methods
141
139
  #
142
140
  def decode_reading(bytes)
143
141
  temperature, b5 = decode_temperature(bytes)
144
- @reading[:temperature] = temperature
145
- @reading[:pressure] = decode_pressure(bytes, b5)
146
- @reading
142
+ reading[:temperature] = temperature
143
+ reading[:pressure] = decode_pressure(bytes, b5)
144
+ reading
147
145
  end
148
146
 
149
147
  def decode_temperature(bytes)
@@ -162,7 +160,7 @@ module Denko
162
160
  # Return temperature and b5 for pressure calculation.
163
161
  [temperature, b5]
164
162
  end
165
-
163
+
166
164
  def decode_pressure(bytes, b5)
167
165
  # Pressure is bytes [2..3], MSB first.
168
166
  up = ((bytes[2] << 16) | (bytes[3] << 8) | (bytes[4])) >> (8 - @oss)
@@ -194,10 +192,10 @@ module Denko
194
192
  # Calibration Methods
195
193
  #
196
194
  attr_reader :calibration_data_loaded
197
-
198
- def get_calibration_data
199
- # Calibration data is 22 bytes starting at address 0xAA.
200
- read_using -> { i2c_read(0xAA, 22) }
195
+
196
+ def get_calibration_data
197
+ bytes = i2c_read_raw(22, register: 0xAA)
198
+ process_calibration(bytes) if bytes
201
199
  end
202
200
 
203
201
  def process_calibration(bytes)
@@ -1,15 +1,35 @@
1
1
  module Denko
2
2
  module Sensor
3
3
  class DHT
4
- include Behaviors::SinglePin
4
+ include Behaviors::InputPin
5
5
  include Behaviors::Poller
6
+ include Behaviors::Lifecycle
7
+ include TemperatureHelper
8
+ include HumidityHelper
9
+
10
+ after_initialize do
11
+ # Small delay on startup to prevent Linux from reading too early.
12
+ sleep 0.100
13
+ end
14
+
15
+ def state
16
+ @state ||= { temperature: nil, humidity: nil }
17
+ end
18
+
19
+ def reading
20
+ @reading ||= { temperature: nil, humidity: nil }
21
+ end
6
22
 
7
23
  def _read
8
- board.pulse_read(pin, reset: board.low, reset_time: 20000, pulse_limit: 84, timeout: 100)
24
+ board.pulse_read(pin, reset: board.low, reset_time: 10_000, pulse_limit: 84, timeout: 100)
9
25
  end
10
26
 
11
27
  def pre_callback_filter(data)
12
- decode(data.split(",").map(&:to_i))
28
+ if data.class == String
29
+ decode(data.split(",").map(&:to_i))
30
+ else
31
+ decode(data)
32
+ end
13
33
  end
14
34
 
15
35
  def decode(data)
@@ -28,11 +48,18 @@ module Denko
28
48
  end
29
49
  return { error: 'CRC failure' } unless crc(bytes)
30
50
 
31
- celsius = ((bytes[2] << 8) | bytes[3]).to_f / 10
32
- humidity = ((bytes[0] << 8) | bytes[1]).to_f / 10
33
- fahrenheit = (celsius * 1.8 + 32).round(1)
51
+ reading[:temperature] = ((bytes[2] << 8) | bytes[3]).to_f / 10
52
+ reading[:humidity] = ((bytes[0] << 8) | bytes[1]).to_f / 10
53
+
54
+ reading
55
+ end
34
56
 
35
- { celsius: celsius, fahrenheit: fahrenheit, humidity: humidity }
57
+ def update_state(reading)
58
+ @state_mutex.lock
59
+ @state[:temperature] = reading[:temperature]
60
+ @state[:humidity] = reading[:humidity]
61
+ @state_mutex.unlock
62
+ @state
36
63
  end
37
64
 
38
65
  def crc(bytes)
@@ -1,36 +1,24 @@
1
1
  module Denko
2
2
  module Sensor
3
3
  class DS18B20 < OneWire::Peripheral
4
+ include Behaviors::Lifecycle
5
+ include TemperatureHelper
4
6
  FAMILY_CODE = 0x28
5
7
 
6
- def scratch
7
- @state ? @state[:raw] : read_scratch(9)
8
+ def state
9
+ @state ||= { temperature: nil }
8
10
  end
9
11
 
10
- def resolution
11
- @resolution ||= decode_resolution(scratch)
12
+ def reading
13
+ @reading ||= { temperature: nil }
12
14
  end
13
15
 
14
- def resolution=(bits)
15
- unless (9..12).include?(bits)
16
- raise ArgumentError, 'Invalid DS18B20 resolution, expected 9 to 12'
17
- end
18
-
19
- return bits if decode_resolution(scratch) == bits
20
-
21
- eeprom = scratch[2..4]
22
- eeprom[2] = 0b00011111 | ((bits - 9) << 5)
23
- write_scratch(eeprom)
24
- copy_scratch
25
- @resolution = bits
26
- end
27
-
28
- def set_convert_time
29
- @convert_time = 0.75 / (2 ** (12 - @resolution))
16
+ def _read
17
+ convert
18
+ read_scratch(9) { |data| self.update(data) }
30
19
  end
31
20
 
32
21
  def convert
33
- @resolution ||= 12
34
22
  set_convert_time
35
23
 
36
24
  atomically do
@@ -41,16 +29,30 @@ module Denko
41
29
  sleep @convert_time unless bus.parasite_power
42
30
  end
43
31
 
44
- def _read
45
- convert
46
- read_scratch(9) { |data| self.update(data) }
32
+ def set_convert_time
33
+ @convert_time = 0.75 / (2 ** (12 - (@resolution || 12)))
47
34
  end
48
35
 
49
36
  def pre_callback_filter(bytes)
50
37
  return { crc_error: true } unless OneWire::Helper.crc(bytes)
51
- @resolution = decode_resolution(bytes)
52
38
 
53
- decode_temperature(bytes).merge(raw: bytes)
39
+ @resolution ||= decode_resolution(bytes)
40
+ reading[:temperature] = decode_temperature(bytes)
41
+
42
+ reading
43
+ end
44
+
45
+ def update_state(reading)
46
+ @state_mutex.lock
47
+ @state[:temperature] = reading[:temperature]
48
+ @state_mutex.unlock
49
+ @state
50
+ end
51
+
52
+ def decode_resolution(bytes)
53
+ config_byte = bytes[4]
54
+ offset = config_byte >> 5
55
+ offset + 9
54
56
  end
55
57
 
56
58
  #
@@ -58,16 +60,21 @@ module Denko
58
60
  # It's a signed, 2's complement, little-endian decimal. LSB = 2 ^ -4.
59
61
  #
60
62
  def decode_temperature(bytes)
61
- celsius = bytes[0..1].pack('C*').unpack('s<')[0] * (2.0 ** -4)
62
- fahrenheit = (celsius * 1.8 + 32).round(4)
63
-
64
- {celsius: celsius, fahrenheit: fahrenheit}
63
+ bytes[0..1].pack('C*').unpack('s<')[0] * (2.0 ** -4)
65
64
  end
66
65
 
67
- def decode_resolution(bytes)
68
- config_byte = bytes[4]
69
- offset = config_byte >> 5
70
- offset + 9
66
+ attr_reader :resolution
67
+
68
+ def resolution=(bits)
69
+ unless (9..12).include?(bits)
70
+ raise ArgumentError, 'Invalid DS18B20 resolution, expected 9 to 12'
71
+ end
72
+
73
+ eeprom = read_scratch(9)[2..4]
74
+ eeprom[2] = 0b00011111 | ((bits - 9) << 5)
75
+ write_scratch(eeprom)
76
+ copy_scratch
77
+ @resolution = bits
71
78
  end
72
79
  end
73
80
  end