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
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env rake
1
+ #!/usr/bin/env ruby
2
2
  require "bundler/gem_tasks"
3
3
  require 'rake/testtask'
4
4
 
data/build CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!ruby
2
2
  # encoding: UTF-8
3
3
 
4
4
  require "pathname"
data/denko.gemspec CHANGED
@@ -4,12 +4,17 @@ require File.expand_path('../lib/denko/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["vickash, Austinbv"]
6
6
  gem.email = ["mail@vickash.com"]
7
- gem.description = %q{GPIO library for Ruby}
8
- gem.summary = %q{Use GPIO, I2C, SPI, UART and more on a connected microcontroller}
7
+ gem.description = %q{Electronics programming in Ruby}
8
+ gem.summary = %q{Use GPIO, PWM, I2C, SPI, and more, on a connected microcontroller, or single-board-computer}
9
9
  gem.homepage = 'https://github.com/denko-rb/denko'
10
- gem.files = `git ls-files`.split($\)
11
10
  gem.licenses = ['MIT']
12
11
 
12
+ # Exclude benchmarks, examples, images and tutorial to keep gem size down.
13
+ `git ls-files`.split($\).each do |filename|
14
+ next if filename.start_with?('benchmarks/', 'examples/', 'images/', 'tutorial/')
15
+ gem.files << "#{filename}"
16
+ end
17
+
13
18
  # Copy full submodule contents into the gem when building.
14
19
  # Credit:
15
20
  # https://gist.github.com/mattconnolly/5875987#file-gem-with-git-submodules-gemspec
@@ -38,6 +43,9 @@ Gem::Specification.new do |gem|
38
43
  gem.version = Denko::VERSION
39
44
  gem.executables = ["denko"]
40
45
 
46
+ gem.required_ruby_version = '>=2.7.8'
47
+
48
+ gem.add_dependency 'observer', '~> 0.1.2'
41
49
  gem.add_dependency 'rubyserial', '~> 0.6'
42
50
  gem.add_dependency 'bcd', '~> 1'
43
51
 
@@ -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
@@ -2,6 +2,7 @@ module Denko
2
2
  module AnalogIO
3
3
  class ADS1118
4
4
  include SPI::Peripheral
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
- # Wrap in mutex to not interfere with other reads.
56
- @mutex.synchronize do
57
- _read([0b10000001, 0b10011011])
58
- end
40
+ # Don't interfere with subcomponent reads.
41
+ mutex.lock
42
+ _read([0b10000001, 0b10011011])
43
+ mutex.unlock
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,39 +56,47 @@ 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
69
- # Default gain and sample rate.
70
- gain ||= 0b010
71
- sample_rate ||= 0b100
74
+ mutex.lock
72
75
 
73
- # Set these for callbacks.
74
- @active_pin = pin
75
- @active_gain = gain
76
+ # Default gain and sample rate.
77
+ gain ||= 0b010
78
+ sample_rate ||= 0b100
76
79
 
77
- # Set gain in upper config register.
78
- raise ArgumentError "wrong gain: #{gain.inspect} given for ADS111X" unless PGA_RANGE.include?(gain)
79
- @config_register[0] = self.class::BASE_MSB | (gain << 1)
80
+ # Set these for callbacks.
81
+ self.active_pin = pin
82
+ self.active_gain = gain
80
83
 
81
- # Set mux bits in upper config register.
82
- mux_bits = pins_to_mux_bits(pin, negative_pin)
83
- @config_register[0] = @config_register[0] | (mux_bits << 4)
84
+ # Set gain in upper config register.
85
+ raise ArgumentError "wrong gain: #{gain.inspect} given for ADS111X" unless PGA_RANGE.include?(gain)
86
+ config_register[0] = self.class::BASE_MSB | (gain << 1)
84
87
 
85
- # 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)
88
+ # Set mux bits in upper config register.
89
+ mux_bits = pins_to_mux_bits(pin, negative_pin)
90
+ config_register[0] = config_register[0] | (mux_bits << 4)
88
91
 
89
- read(@config_register)
90
- end
92
+ # Set sample rate in lower config_register.
93
+ raise ArgumentError "wrong sample_rate: #{sample_rate.inspect} given for ADS111X" unless SAMPLE_RATE_RANGE.include?(sample_rate)
94
+ config_register[1] = self.class::BASE_LSB | (sample_rate << 5)
95
+
96
+ result = read(config_register)
97
+ mutex.unlock
98
+
99
+ result
91
100
  end
92
101
 
93
102
  def pins_to_mux_bits(pin, negative_pin)
@@ -118,6 +127,15 @@ module Denko
118
127
 
119
128
  def stop_listener(pin)
120
129
  end
130
+
131
+ def mutex
132
+ # mruby doesn't have Thread or Mutex, so only stub there.
133
+ @mutex ||= Denko.mruby? ? Denko::MutexStub.new : Mutex.new
134
+ end
135
+
136
+ def config_register
137
+ @config_register ||= self.class::CONFIG_STARTUP.dup
138
+ end
121
139
  end
122
140
  end
123
141
  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
@@ -0,0 +1,87 @@
1
+ module Denko
2
+ module AnalogIO
3
+ class Joystick
4
+ include Behaviors::MultiPin
5
+ include Behaviors::Lifecycle
6
+
7
+ def initialize_pins(options={})
8
+ proxy_pin(:x, AnalogIO::Input)
9
+ proxy_pin(:y, AnalogIO::Input)
10
+ end
11
+
12
+ after_initialize do
13
+ # Midpoint as float
14
+ @mid = board.adc_high / 2.0
15
+
16
+ # Invert settings as +1 or -1 multipliers
17
+ @invert_x = params[:invert_x] ? -1 : 1
18
+ @invert_y = params[:invert_y] ? -1 : 1
19
+
20
+ # Swap axes if neeeded
21
+ @x_key = :x
22
+ @y_key = :y
23
+ swap_axes if params[:swap_axes]
24
+
25
+ # Deadzones as percentages
26
+ @deadzone = 0
27
+ @maxzone = @mid
28
+ @deadzone = ((params[:deadzone] * @mid) / 100).round if params[:deadzone]
29
+ @maxzone = ((params[:maxzone] * @mid) / 100).round if params[:maxzone]
30
+
31
+ # Per axis callbacks
32
+ x.on_data { |value| state[@x_key] = raw_to_percent(value, @invert_x) }
33
+ y.on_data { |value| state[@y_key] = raw_to_percent(value, @invert_y) }
34
+ end
35
+
36
+ def swap_axes
37
+ if @x_key == :x
38
+ @x_key = :y
39
+ @y_key = :x
40
+ else
41
+ @x_key = :x
42
+ @y_key = :y
43
+ end
44
+ end
45
+
46
+ def invert_x
47
+ @invert_x = @invert_x * -1
48
+ end
49
+
50
+ def invert_y
51
+ @invert_y = @invert_y * -1
52
+ end
53
+
54
+ def state
55
+ @state ||= { x: nil, y: nil }
56
+ end
57
+
58
+ def raw_to_percent(value, invert)
59
+ float = (value - @mid) * invert
60
+ abs = float.abs
61
+ if abs < @deadzone
62
+ return 0
63
+ elsif abs > @maxzone
64
+ return (float > 0) ? 100 : -100
65
+ else
66
+ return ((float * 100) / @mid).round
67
+ end
68
+ end
69
+
70
+ def read
71
+ x.read
72
+ y.read
73
+ state
74
+ end
75
+
76
+ def listen(divider=16)
77
+ x.listen(divider)
78
+ y.listen(divider)
79
+ end
80
+
81
+ def stop
82
+ x.stop
83
+ y.stop
84
+ end
85
+ end
86
+ end
87
+ 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,8 @@
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
9
-
10
- # Start listening immediately. Read 2x as often as regular Input.
11
- listen(@divider = 8)
3
+ class Potentiometer < Input
4
+ after_initialize do
5
+ @divider ||= params[:divider] || 8
12
6
  end
13
7
  end
14
8
  end