denko 0.13.6 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/{build_avr.yml → build_atmega_avr.yml} +18 -18
  3. data/.github/workflows/{build_megaavr.yml → build_atmega_megaavr.yml} +18 -18
  4. data/.github/workflows/{build_sam3x.yml → build_atsam3x.yml} +17 -17
  5. data/.github/workflows/{build_samd.yml → build_atsamd21.yml} +18 -18
  6. data/.github/workflows/build_esp32.yml +17 -18
  7. data/.github/workflows/build_esp32c3.yml +57 -0
  8. data/.github/workflows/build_esp32c6.yml +57 -0
  9. data/.github/workflows/build_esp32h2.yml +56 -0
  10. data/.github/workflows/build_esp32s2.yml +57 -0
  11. data/.github/workflows/build_esp32s3.yml +57 -0
  12. data/.github/workflows/build_esp8266.yml +15 -15
  13. data/.github/workflows/build_ra4m1.yml +16 -16
  14. data/.github/workflows/build_rp2040.yml +17 -16
  15. data/.github/workflows/ruby.yml +20 -20
  16. data/CHANGELOG.md +195 -11
  17. data/DEPS_CLI.md +9 -9
  18. data/DEPS_IDE.md +17 -18
  19. data/HARDWARE.md +50 -51
  20. data/README.md +61 -53
  21. data/Rakefile +1 -1
  22. data/benchmarks/analog_listen.rb +49 -0
  23. data/benchmarks/digital_write.rb +28 -0
  24. data/benchmarks/i2c_ssd1306_refresh.rb +13 -6
  25. data/build +1 -1
  26. data/denko.gemspec +5 -2
  27. data/examples/advanced/{m5_env.rb → m5_env3.rb} +12 -14
  28. data/examples/advanced/rotary_encoder_mac_volume.rb +18 -13
  29. data/examples/advanced/ssd1306_time_temp_rh.rb +8 -13
  30. data/examples/analog_io/ads1100.rb +48 -0
  31. data/examples/analog_io/ads1115.rb +2 -2
  32. data/examples/analog_io/ads1118.rb +3 -11
  33. data/examples/analog_io/input.rb +17 -16
  34. data/examples/analog_io/input_smoothing.rb +27 -0
  35. data/examples/analog_io/potentiometer.rb +31 -0
  36. data/examples/connection/binary_echo.rb +34 -0
  37. data/examples/connection/tcp.rb +12 -27
  38. data/examples/digital_io/button.rb +7 -3
  39. data/examples/digital_io/relay.rb +17 -0
  40. data/examples/digital_io/rotary_encoder.rb +21 -11
  41. data/examples/display/hd44780.rb +13 -5
  42. data/examples/display/ssd1306.rb +20 -17
  43. data/examples/display/ssd1306_s2_pico.rb +2 -2
  44. data/examples/i2c/search.rb +10 -26
  45. data/examples/led/apa102_bounce.rb +3 -4
  46. data/examples/led/apa102_fade.rb +44 -0
  47. data/examples/led/builtin_blink.rb +3 -1
  48. data/examples/led/builtin_fade.rb +19 -0
  49. data/examples/led/rgb_led.rb +31 -0
  50. data/examples/led/seven_segment_char_echo.rb +4 -2
  51. data/examples/led/ws2812_bounce.rb +5 -7
  52. data/examples/led/ws2812_builtin_blink.rb +3 -2
  53. data/examples/led/ws2812_fade.rb +43 -0
  54. data/examples/motor/l298.rb +10 -8
  55. data/examples/motor/servo.rb +4 -3
  56. data/examples/motor/stepper.rb +13 -13
  57. data/examples/one_wire/search.rb +32 -0
  58. data/examples/pulse_io/buzzer.rb +8 -3
  59. data/examples/pulse_io/ir_output.rb +51 -0
  60. data/examples/pulse_io/pwm_output.rb +30 -0
  61. data/examples/rtc/ds3231.rb +18 -35
  62. data/examples/sensor/aht10.rb +4 -6
  63. data/examples/sensor/aht20.rb +4 -6
  64. data/examples/sensor/bme280.rb +4 -4
  65. data/examples/sensor/bmp180.rb +9 -5
  66. data/examples/sensor/dht.rb +20 -15
  67. data/examples/sensor/ds18b20.rb +20 -21
  68. data/examples/sensor/generic_pir.rb +4 -2
  69. data/examples/sensor/hcsr04.rb +5 -2
  70. data/examples/sensor/htu21d.rb +9 -20
  71. data/examples/sensor/htu31d.rb +7 -9
  72. data/examples/sensor/neat_tph_readings.rb +15 -9
  73. data/examples/sensor/qmp6988.rb +5 -7
  74. data/examples/sensor/rcwl9620.rb +3 -3
  75. data/examples/sensor/sht3x.rb +4 -6
  76. data/examples/spi/bitbang_loopback.rb +46 -0
  77. data/examples/spi/input_register.rb +9 -19
  78. data/examples/spi/output_register.rb +9 -17
  79. data/examples/spi/ssd_through_registers.rb +28 -0
  80. data/examples/spi/two_registers.rb +18 -24
  81. data/examples/uart/bit_bang_demo.rb +25 -0
  82. data/examples/uart/board_passthrough.rb +19 -13
  83. data/examples/uart/hardware_loopback.rb +1 -1
  84. data/lib/denko/analog_io/ads1100.rb +127 -0
  85. data/lib/denko/analog_io/ads1115.rb +8 -25
  86. data/lib/denko/analog_io/ads1118.rb +10 -25
  87. data/lib/denko/analog_io/ads111x.rb +25 -11
  88. data/lib/denko/analog_io/input.rb +29 -55
  89. data/lib/denko/analog_io/input_helper.rb +42 -0
  90. data/lib/denko/analog_io/output.rb +5 -5
  91. data/lib/denko/analog_io/potentiometer.rb +6 -8
  92. data/lib/denko/analog_io.rb +2 -1
  93. data/lib/denko/behaviors/board_proxy.rb +13 -1
  94. data/lib/denko/behaviors/bus_controller.rb +1 -0
  95. data/lib/denko/behaviors/bus_controller_addressed.rb +1 -0
  96. data/lib/denko/behaviors/bus_peripheral.rb +3 -4
  97. data/lib/denko/behaviors/bus_peripheral_addressed.rb +8 -6
  98. data/lib/denko/behaviors/callbacks.rb +9 -7
  99. data/lib/denko/behaviors/component.rb +16 -14
  100. data/lib/denko/behaviors/input_pin.rb +14 -15
  101. data/lib/denko/behaviors/lifecycle.rb +51 -0
  102. data/lib/denko/behaviors/multi_pin.rb +22 -18
  103. data/lib/denko/behaviors/output_pin.rb +9 -4
  104. data/lib/denko/behaviors/single_pin.rb +1 -0
  105. data/lib/denko/behaviors/state.rb +15 -9
  106. data/lib/denko/behaviors/subcomponents.rb +72 -12
  107. data/lib/denko/behaviors.rb +2 -1
  108. data/lib/denko/board/core.rb +36 -18
  109. data/lib/denko/board/i2c.rb +14 -14
  110. data/lib/denko/board/i2c_bit_bang.rb +49 -0
  111. data/lib/denko/board/infrared.rb +6 -6
  112. data/lib/denko/board/led_array.rb +6 -5
  113. data/lib/denko/board/spi.rb +15 -10
  114. data/lib/denko/board/spi_bit_bang.rb +9 -7
  115. data/lib/denko/board.rb +35 -33
  116. data/lib/denko/connection/binary_echo.rb +17 -0
  117. data/lib/denko/connection/flow_control.rb +11 -15
  118. data/lib/denko/connection/handshake.rb +2 -0
  119. data/lib/denko/digital_io/button.rb +4 -0
  120. data/lib/denko/digital_io/c_bit_bang.rb +15 -0
  121. data/lib/denko/digital_io/input.rb +4 -5
  122. data/lib/denko/digital_io/output.rb +7 -6
  123. data/lib/denko/digital_io/relay.rb +2 -0
  124. data/lib/denko/digital_io/rotary_encoder.rb +78 -60
  125. data/lib/denko/digital_io.rb +1 -0
  126. data/lib/denko/display/hd44780.rb +136 -93
  127. data/lib/denko/display/sh1106.rb +42 -0
  128. data/lib/denko/display/ssd1306.rb +105 -45
  129. data/lib/denko/display.rb +1 -0
  130. data/lib/denko/eeprom/built_in.rb +19 -16
  131. data/lib/denko/i2c/bit_bang.rb +31 -0
  132. data/lib/denko/i2c/bus.rb +8 -36
  133. data/lib/denko/i2c/bus_common.rb +45 -0
  134. data/lib/denko/i2c/peripheral.rb +28 -19
  135. data/lib/denko/i2c.rb +2 -0
  136. data/lib/denko/led/apa102.rb +43 -29
  137. data/lib/denko/led/base.rb +8 -2
  138. data/lib/denko/led/rgb.rb +5 -7
  139. data/lib/denko/led/seven_segment.rb +24 -9
  140. data/lib/denko/led/ws2812.rb +10 -7
  141. data/lib/denko/message.rb +5 -0
  142. data/lib/denko/motor/l298.rb +11 -10
  143. data/lib/denko/motor/servo.rb +22 -10
  144. data/lib/denko/motor/stepper.rb +11 -14
  145. data/lib/denko/mutex_stub.rb +7 -0
  146. data/lib/denko/one_wire/bus.rb +9 -5
  147. data/lib/denko/one_wire/peripheral.rb +0 -3
  148. data/lib/denko/pulse_io/buzzer.rb +9 -3
  149. data/lib/denko/pulse_io/{ir_transmitter.rb → ir_output.rb} +9 -4
  150. data/lib/denko/pulse_io/pwm_output.rb +69 -15
  151. data/lib/denko/pulse_io.rb +3 -3
  152. data/lib/denko/rtc/ds3231.rb +11 -13
  153. data/lib/denko/sensor/aht.rb +22 -21
  154. data/lib/denko/sensor/bme280.rb +60 -63
  155. data/lib/denko/sensor/bmp180.rb +41 -38
  156. data/lib/denko/sensor/dht.rb +22 -5
  157. data/lib/denko/sensor/ds18b20.rb +40 -34
  158. data/lib/denko/sensor/hcsr04.rb +7 -5
  159. data/lib/denko/sensor/helper.rb +37 -0
  160. data/lib/denko/sensor/htu21d.rb +44 -55
  161. data/lib/denko/sensor/htu31d.rb +32 -33
  162. data/lib/denko/sensor/qmp6988.rb +25 -23
  163. data/lib/denko/sensor/rcwl9620.rb +2 -5
  164. data/lib/denko/sensor/sht3x.rb +23 -21
  165. data/lib/denko/sensor.rb +1 -2
  166. data/lib/denko/spi/base_register.rb +22 -22
  167. data/lib/denko/spi/bit_bang.rb +17 -51
  168. data/lib/denko/spi/bus.rb +15 -29
  169. data/lib/denko/spi/bus_common.rb +36 -0
  170. data/lib/denko/spi/input_register.rb +36 -30
  171. data/lib/denko/spi/output_register.rb +25 -40
  172. data/lib/denko/spi/peripheral.rb +93 -24
  173. data/lib/denko/spi.rb +6 -1
  174. data/lib/denko/uart/bit_bang.rb +5 -3
  175. data/lib/denko/uart/hardware.rb +9 -8
  176. data/lib/denko/version.rb +1 -1
  177. data/lib/denko.rb +10 -0
  178. data/lib/denko_cli/generator.rb +2 -2
  179. data/lib/denko_cli/packages.rb +8 -10
  180. data/lib/denko_cli/targets.rb +8 -8
  181. data/lib/denko_cli/targets.txt +4 -4
  182. data/lib/denko_cli/usage.txt +1 -1
  183. data/src/denko_ethernet.ino +0 -14
  184. data/src/denko_serial.ino +0 -14
  185. data/src/denko_wifi.ino +6 -15
  186. data/src/lib/Denko.cpp +39 -3
  187. data/src/lib/Denko.h +42 -26
  188. data/src/lib/DenkoCoreIO.cpp +57 -102
  189. data/src/lib/DenkoDefines.h +36 -31
  190. data/src/lib/DenkoI2C.cpp +54 -45
  191. data/src/lib/DenkoI2CBB.cpp +238 -0
  192. data/src/lib/DenkoIROut.cpp +12 -7
  193. data/src/lib/DenkoLEDArray.cpp +36 -13
  194. data/src/lib/DenkoSPI.cpp +6 -5
  195. data/src/lib/DenkoSPIBB.cpp +7 -6
  196. data/target.yml +37 -2
  197. data/test/analog_io/potentiometer_test.rb +10 -10
  198. data/test/behaviors/board_proxy_test.rb +1 -1
  199. data/test/behaviors/callbacks_test.rb +11 -3
  200. data/test/behaviors/component_test.rb +17 -9
  201. data/test/behaviors/input_pin_test.rb +14 -9
  202. data/test/behaviors/multi_pin_test.rb +14 -4
  203. data/test/behaviors/output_pin_test.rb +11 -8
  204. data/test/behaviors/poller_test.rb +1 -0
  205. data/test/behaviors/reader_test.rb +3 -2
  206. data/test/behaviors/subcomponents_test.rb +22 -2
  207. data/test/board/core_test.rb +15 -11
  208. data/test/board/i2c_test.rb +39 -33
  209. data/test/board/infrared_test.rb +1 -1
  210. data/test/board/message_test.rb +17 -11
  211. data/test/board/spi_test.rb +21 -21
  212. data/test/digital_io/button_test.rb +15 -0
  213. data/test/digital_io/relay_test.rb +18 -0
  214. data/test/digital_io/rotary_encoder_test.rb +80 -60
  215. data/test/eeprom/built_in_test.rb +9 -9
  216. data/test/i2c/bus_test.rb +30 -14
  217. data/test/i2c/peripheral_test.rb +36 -17
  218. data/test/led/base_test.rb +2 -1
  219. data/test/led/rgb_test.rb +6 -6
  220. data/test/led/seven_segment_test.rb +7 -7
  221. data/test/motor/servo_test.rb +1 -1
  222. data/test/motor/stepper_test.rb +2 -2
  223. data/test/one_wire/bus_test.rb +1 -0
  224. data/test/pulse_io/buzzer_test.rb +7 -4
  225. data/test/pulse_io/{ir_transmitter_test.rb → ir_output_test.rb} +10 -10
  226. data/test/pulse_io/pwm_output_test.rb +74 -18
  227. data/test/rtc/ds3231_test.rb +11 -13
  228. data/test/sensor/dht_test.rb +1 -1
  229. data/test/sensor/ds18b20_test.rb +4 -8
  230. data/test/spi/bus_test.rb +7 -7
  231. data/test/spi/input_register_test.rb +15 -15
  232. data/test/spi/output_register_test.rb +10 -28
  233. data/test/spi/peripheral_multi_pin_test.rb +53 -0
  234. data/test/spi/peripheral_single_pin_test.rb +48 -0
  235. data/test/test_helper.rb +36 -33
  236. data/tutorial/02-button/button.rb +5 -4
  237. data/tutorial/03-potentiometer/potentiometer.rb +9 -5
  238. data/tutorial/04-pwm_led/pwm_led.rb +14 -16
  239. data/tutorial/05-rgb_led/rgb_led.rb +6 -6
  240. data/tutorial/05-rgb_led/rgb_mapping.rb +11 -11
  241. data/vendor/board-maps/BoardMap.h +416 -56
  242. data/vendor/board-maps/lib/header_parser.rb +12 -2
  243. data/vendor/board-maps/yaml/ADAFRUIT_CAMERA_ESP32S3.yml +2 -2
  244. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32C6.yml +15 -0
  245. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32_V2.yml +1 -1
  246. data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_RP2040_ADALOGGER.yml +44 -0
  247. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32C3.yml +1 -0
  248. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S2.yml +1 -0
  249. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_N4R2.yml +1 -0
  250. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_NOPSRAM.yml +1 -0
  251. data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32_PICO.yml +1 -0
  252. data/vendor/board-maps/yaml/AMKEN_BB.yml +48 -0
  253. data/vendor/board-maps/yaml/AMKEN_ES.yml +48 -0
  254. data/vendor/board-maps/yaml/AMKEN_REVELOP.yml +48 -0
  255. data/vendor/board-maps/yaml/AMKEN_REVELOP_PLUS.yml +48 -0
  256. data/vendor/board-maps/yaml/ASL_CAN_X2.yml +41 -0
  257. data/vendor/board-maps/yaml/BLING.yml +25 -0
  258. data/vendor/board-maps/yaml/BPI_LEAF_S3.yml +1 -0
  259. data/vendor/board-maps/yaml/BRIDGETEK_IDM2040_7A.yml +48 -0
  260. data/vendor/board-maps/yaml/Bee_Motion_Mini.yml +13 -1
  261. data/vendor/board-maps/yaml/Breadstick_Raspberry.yml +31 -0
  262. data/vendor/board-maps/yaml/DFROBOT_BEETLE_ESP32C6.yml +8 -0
  263. data/vendor/board-maps/yaml/DFROBOT_FIREBEETLE_2_ESP32C6.yml +20 -0
  264. data/vendor/board-maps/yaml/DFROBOT_FIREBEETLE_ESP32.yml +46 -0
  265. data/vendor/board-maps/yaml/DPTECHNICS_WALTER.yml +39 -0
  266. data/vendor/board-maps/yaml/ELECROW_CROWPANEL_7.yml +8 -0
  267. data/vendor/board-maps/yaml/ESP32C2_DEV.yml +12 -0
  268. data/vendor/board-maps/yaml/ESP32C3_DEVKIT_LIPO.yml +14 -0
  269. data/vendor/board-maps/yaml/ESP32C6_DEV.yml +15 -0
  270. data/vendor/board-maps/yaml/ESP32C6_EVB.yml +15 -0
  271. data/vendor/board-maps/yaml/ESP32C6_QWIIC_POCKET.yml +15 -0
  272. data/vendor/board-maps/yaml/ESP32C6_THING_PLUS.yml +15 -0
  273. data/vendor/board-maps/yaml/ESP32H2_DEV.yml +13 -0
  274. data/vendor/board-maps/yaml/ESP32H2_DEVKIT_LIPO.yml +13 -0
  275. data/vendor/board-maps/yaml/ESP32S2_DEV.yml +1 -0
  276. data/vendor/board-maps/yaml/{RMP.yml → ESP32S2_DEVKIT_LIPO.yml} +2 -1
  277. data/vendor/board-maps/yaml/ESP32S2_DEVKIT_LIPO_USB.yml +44 -0
  278. data/vendor/board-maps/yaml/ESP32S3_DEVKIT_LIPO.yml +42 -0
  279. data/vendor/board-maps/yaml/ESP32S3_POWERFEATHER.yml +22 -0
  280. data/vendor/board-maps/yaml/ESP32_SBC_FABGL.yml +35 -0
  281. data/vendor/board-maps/yaml/EVN_ALPHA.yml +48 -0
  282. data/vendor/board-maps/yaml/FEATHERS3NEO.yml +32 -0
  283. data/vendor/board-maps/yaml/GEEKBLE_ESP32C3.yml +14 -0
  284. data/vendor/board-maps/yaml/HELTEC_CAPSULE_SENSOR_V3.yml +43 -0
  285. data/vendor/board-maps/yaml/HELTEC_WIFI_LORA_32_V3.yml +42 -0
  286. data/vendor/board-maps/yaml/HELTEC_WIRELESS_BRIDGE.yml +8 -0
  287. data/vendor/board-maps/yaml/HELTEC_WIRELESS_MINI_SHELL.yml +13 -0
  288. data/vendor/board-maps/yaml/HELTEC_WIRELESS_PAPER.yml +42 -0
  289. data/vendor/board-maps/yaml/HELTEC_WIRELESS_SHELL_V3.yml +42 -0
  290. data/vendor/board-maps/yaml/HELTEC_WIRELESS_STICK_LITE_V3.yml +30 -0
  291. data/vendor/board-maps/yaml/HELTEC_WIRELESS_TRACKER.yml +41 -0
  292. data/vendor/board-maps/yaml/HT_DE01.yml +42 -0
  293. data/vendor/board-maps/yaml/IMBRIOS_LOGSENS_V1P1.yml +1 -1
  294. data/vendor/board-maps/yaml/LILYGO_T3S3_LR1121.yml +9 -0
  295. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1262.yml +9 -0
  296. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1276.yml +9 -0
  297. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1278.yml +9 -0
  298. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280.yml +9 -0
  299. data/vendor/board-maps/yaml/LILYGO_T3S3_SX1280PA.yml +8 -0
  300. data/vendor/board-maps/yaml/LILYGO_T_ETH_LITE.yml +21 -0
  301. data/vendor/board-maps/yaml/LOLIN_C3_PICO.yml +14 -0
  302. data/vendor/board-maps/yaml/LOLIN_S3.yml +1 -0
  303. data/vendor/board-maps/yaml/LOLIN_S3_MINI_PRO.yml +40 -0
  304. data/vendor/board-maps/yaml/Lion_Bit_Dev_Board.yml +0 -2
  305. data/vendor/board-maps/yaml/LoPy.yml +1 -0
  306. data/vendor/board-maps/yaml/LoPy4.yml +1 -0
  307. data/vendor/board-maps/yaml/M5STACK_CAPSULE.yml +8 -0
  308. data/vendor/board-maps/yaml/M5STACK_CARDPUTER.yml +8 -0
  309. data/vendor/board-maps/yaml/M5STACK_DIAL.yml +8 -0
  310. data/vendor/board-maps/yaml/M5STACK_FIRE.yml +0 -1
  311. data/vendor/board-maps/yaml/M5STACK_NANOC6.yml +17 -0
  312. data/vendor/board-maps/yaml/M5STACK_PAPER.yml +9 -0
  313. data/vendor/board-maps/yaml/M5STACK_POE_CAM.yml +5 -0
  314. data/vendor/board-maps/yaml/M5STACK_STAMP_C3.yml +13 -0
  315. data/vendor/board-maps/yaml/M5STACK_STAMP_S3.yml +4 -0
  316. data/vendor/board-maps/yaml/{M5Stick_C.yml → M5STACK_STICKC.yml} +0 -1
  317. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS.yml +9 -0
  318. data/vendor/board-maps/yaml/M5STACK_STICKC_PLUS2.yml +9 -0
  319. data/vendor/board-maps/yaml/M5STACK_TOUGH.yml +9 -0
  320. data/vendor/board-maps/yaml/M5STACK_UNIT_CAM.yml +10 -0
  321. data/vendor/board-maps/yaml/M5STACK_UNIT_CAMS3.yml +4 -0
  322. data/vendor/board-maps/yaml/M5Stack_ATOM.yml +0 -1
  323. data/vendor/board-maps/yaml/MAKERGO_C3_SUPERMINI.yml +14 -0
  324. data/vendor/board-maps/yaml/MARBLE_PICO.yml +48 -0
  325. data/vendor/board-maps/yaml/METEHOCA_AKANA_R1.yml +46 -0
  326. data/vendor/board-maps/yaml/NAMINO_BIANCO.yml +13 -0
  327. data/vendor/board-maps/yaml/NEBULAS3.yml +0 -1
  328. data/vendor/board-maps/yaml/NEWSAN_ARCHI.yml +48 -0
  329. data/vendor/board-maps/yaml/NOLOGO_ESP32C3_SUPER_MINI.yml +14 -0
  330. data/vendor/board-maps/yaml/NOLOGO_ESP32S3_PICO.yml +12 -0
  331. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_16MB.yml +48 -0
  332. data/vendor/board-maps/yaml/OLIMEX_RP2040_PICO30_2MB.yml +48 -0
  333. data/vendor/board-maps/yaml/OPTA_ANALOG.yml +7 -0
  334. data/vendor/board-maps/yaml/OPTA_DIGITAL.yml +5 -0
  335. data/vendor/board-maps/yaml/PINTRONIX_PINMAX.yml +42 -0
  336. data/vendor/board-maps/yaml/PYCOM_GPY.yml +1 -0
  337. data/vendor/board-maps/yaml/REDPILL_ESP32S3.yml +0 -1
  338. data/vendor/board-maps/yaml/SENSEBOX_MCU_ESP32S2.yml +12 -0
  339. data/vendor/board-maps/yaml/SPARKFUN_MICROMOD_RP2040.yml +48 -0
  340. data/vendor/board-maps/yaml/SPARKFUN_PRO_MICRO_ESP32C3.yml +24 -0
  341. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER.yml +31 -0
  342. data/vendor/board-maps/yaml/THINGPULSE_EPULSE_FEATHER_C6.yml +15 -0
  343. data/vendor/board-maps/yaml/TINYC6.yml +25 -0
  344. data/vendor/board-maps/yaml/UPESY_EDU_ESP32.yml +28 -0
  345. data/vendor/board-maps/yaml/UPESY_ESP32C3_BASIC.yml +13 -0
  346. data/vendor/board-maps/yaml/UPESY_ESP32C3_MINI.yml +12 -0
  347. data/vendor/board-maps/yaml/UPESY_ESP32S3_BASIC.yml +42 -0
  348. data/vendor/board-maps/yaml/VIRALINK_GATE32_01.yml +6 -0
  349. data/vendor/board-maps/yaml/VIRALINK_GATE32_11.yml +7 -0
  350. data/vendor/board-maps/yaml/WAVESHARE_ESP32S3_TOUCH_LCD_128.yml +8 -0
  351. data/vendor/board-maps/yaml/WAVESHARE_RP2040_MATRIX.yml +48 -0
  352. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ONE.yml +1 -0
  353. data/vendor/board-maps/yaml/WAVESHARE_RP2040_PIZERO.yml +47 -0
  354. data/vendor/board-maps/yaml/WAVESHARE_RP2040_ZERO.yml +1 -0
  355. data/vendor/board-maps/yaml/WEACT_STUDIO_ESP32C3.yml +14 -0
  356. data/vendor/board-maps/yaml/WIPY3.yml +1 -0
  357. data/vendor/board-maps/yaml/WT32_SC01_PLUS.yml +7 -0
  358. data/vendor/board-maps/yaml/WiFiduinoV2.yml +1 -0
  359. data/vendor/board-maps/yaml/XIAO_ESP32C3.yml +0 -1
  360. data/vendor/board-maps/yaml/XIAO_ESP32C6.yml +22 -0
  361. data/vendor/board-maps/yaml/unphone9.yml +8 -0
  362. metadata +169 -30
  363. data/examples/led/apa102_breathe.rb +0 -45
  364. data/examples/pulse_io/ir_transmitter.rb +0 -55
  365. data/examples/spi/ssd_through_register.rb +0 -40
  366. data/examples/uart/bit_bang_read.rb +0 -16
  367. data/examples/uart/bit_bang_write.rb +0 -16
  368. data/lib/denko/analog_io/sensor.rb +0 -6
  369. data/lib/denko/sensor/virtual.rb +0 -42
  370. data/src/lib/DenkoIROutESP.cpp +0 -26
  371. data/vendor/board-maps/yaml/STAMP_S3.yml +0 -8
  372. /data/vendor/board-maps/yaml/{BRIDGETEK_IDM2040-7A.yml → BRIDGETEK_IDM2040_43A.yml} +0 -0
  373. /data/vendor/board-maps/yaml/{heltec_wifi_32_lora_V3.yml → HELTEC_WIRELESS_STICK_V3.yml} +0 -0
  374. /data/vendor/board-maps/yaml/{M5Stack_Core_ESP32.yml → M5STACK_CORE.yml} +0 -0
  375. /data/vendor/board-maps/yaml/{M5Stamp_Pico.yml → M5STACK_STAMP_PICO.yml} +0 -0
  376. /data/vendor/board-maps/yaml/{M5Stack-Timer-CAM.yml → M5STACK_TIMER_CAM.yml} +0 -0
@@ -0,0 +1,49 @@
1
+ module Denko
2
+ class Board
3
+ # CMD = 30
4
+ def i2c_bb_search(scl, sda)
5
+ write Message.encode command: 30,
6
+ pin: scl,
7
+ value: sda
8
+ end
9
+
10
+ # CMD = 31
11
+ def i2c_bb_write(scl, sda, address, bytes, repeated_start=false)
12
+ bytes = [bytes] unless bytes.class == Array
13
+
14
+ # Use top bit of address to select stop condition (1), or repated start (0).
15
+ send_stop = repeated_start ? 0 : 1
16
+
17
+ write Message.encode command: 31,
18
+ pin: scl,
19
+ value: sda,
20
+ aux_message: pack(:uint8, 0x00) +
21
+ pack(:uint8, address | (send_stop << 7)) +
22
+ pack(:uint8, bytes.length) +
23
+ pack(:uint8, bytes)
24
+ end
25
+
26
+ # CMD = 32
27
+ def i2c_bb_read(scl, sda, address, register, read_length, repeated_start=false)
28
+ # Use top bit of address to select stop condition (1), or repated start (0).
29
+ send_stop = repeated_start ? 0 : 1
30
+
31
+ # A register address starting register address can be given (up to 4 bytes)
32
+ if register
33
+ register = [register].flatten
34
+ raise ArgumentError, 'maximum 4 byte register address for I2C read' if register.length > 4
35
+ register_packed = pack(:uint8, [register.length] + register)
36
+ else
37
+ register_packed = pack(:uint8, [0])
38
+ end
39
+
40
+ write Message.encode command: 32,
41
+ pin: scl,
42
+ value: sda,
43
+ aux_message: pack(:uint8, 0x00) +
44
+ pack(:uint8, address | (send_stop << 7)) +
45
+ pack(:uint8, read_length) +
46
+ register_packed
47
+ end
48
+ end
49
+ end
@@ -2,17 +2,17 @@ module Denko
2
2
  class Board
3
3
  def infrared_emit(pin, frequency, pulses)
4
4
  #
5
- # Limit to 255 marks/spaces (not pairs) for now.
5
+ # Limit to 255 marks/spaces (not pairs).
6
6
  #
7
- # Length must be 1-byte long, not literally 1
7
+ # Make length uint16 as well, for aligned memory access on ESP8266.
8
8
  # Pulses max is 2x255 bytes long since each is 2 bytes.
9
- length = pack :uint8, pulses.length, max: 1
9
+ length = pack :uint16, pulses.length, max: 2
10
10
  bytes = pack :uint16, pulses, min: 1, max: 510
11
11
 
12
12
  write Message.encode command: 16,
13
- pin: pin,
14
- value: frequency,
15
- aux_message: length + bytes
13
+ pin: pin,
14
+ value: frequency,
15
+ aux_message: length + bytes
16
16
  end
17
17
  end
18
18
  end
@@ -1,15 +1,16 @@
1
1
  module Denko
2
2
  class Board
3
3
  def show_ws2812(pin, pixel_buffer)
4
- # Settings are blank for now.
5
- settings = pack :uint8, [0, 0, 0, 0]
6
-
7
- packed_pixels = pack :uint8, pixel_buffer
4
+ # ALWAYS have first 4 bytes set to 0. ESP32 crashes without this!
5
+ # Last 4 bytes will be settings, but not yet. Just 24-bit 800 kHz for now.
6
+ settings = pack :uint8, [0, 0, 0, 0, 0, 0, 0, 0]
7
+
8
+ pixel_bytes = pack :uint8, pixel_buffer
8
9
 
9
10
  write_and_halt Message.encode command: 19,
10
11
  pin: pin,
11
12
  value: pixel_buffer.length,
12
- aux_message: settings + packed_pixels
13
+ aux_message: settings + pixel_bytes
13
14
  end
14
15
  end
15
16
  end
@@ -1,6 +1,6 @@
1
1
  module Denko
2
2
  class Board
3
- def spi_header_generic(write, read, mode, bit_order)
3
+ def spi_header_generic(select_pin, write, read, mode, bit_order)
4
4
  # Defaults.
5
5
  mode ||= 0
6
6
  bit_order ||= :msbfrst
@@ -14,32 +14,36 @@ module Denko
14
14
  raise ArgumentError, "invalid SPI mode: #{settings.inspect}. Must be 0, 1, 2, or 3"
15
15
  end
16
16
 
17
+ # Bit 6 of settings indicates wiether a select pin needs to be toggled.
18
+ settings |= 0b01000000 if select_pin
19
+
17
20
  # Bit 7 of settings toggles MSBFIRST (1) or LSBFIRST (0) for both read and write.
18
- settings = settings | 0b10000000 unless bit_order == :lsbfirst
21
+ settings |= 0b10000000 unless bit_order == :lsbfirst
19
22
 
20
23
  # Return generic portion of header (used by both hardware and bit bang SPI).
21
24
  pack(:uint8, [settings, read, write.length])
22
25
  end
23
26
 
24
- def spi_header(write, read, frequency, mode, bit_order)
27
+ def spi_header(select_pin, write, read, frequency, mode, bit_order)
25
28
  # Set default frequency and validate.
26
29
  frequency ||= 1000000
27
30
  unless [Integer, Float].include? frequency.class
28
31
  raise ArgumentError, "error in SPI frequency: #{frequency.inspect}"
29
32
  end
30
33
 
31
- # Get the generic part of the SPI header.
32
- header = spi_header_generic(write, read, mode, bit_order)
34
+ # Get the generic part of the SPI header.
35
+ header = spi_header_generic(select_pin, write, read, mode, bit_order)
33
36
 
34
37
  # Generic header + packed frequency = hardware SPI header.
35
38
  header + pack(:uint32, frequency)
36
39
  end
37
40
 
38
41
  # CMD = 26
39
- def spi_transfer(select_pin, write: [], read: 0, frequency: nil, mode: nil, bit_order: nil)
42
+ def spi_transfer(spi_index, select_pin, write: [], read: 0, frequency: nil, mode: nil, bit_order: nil)
40
43
  raise ArgumentError, "no bytes given to read or write" if (read == 0) && (write.empty?)
44
+ raise ArgumentError, "select_pin cannot be nil when reading or listening" if (read != 0) && (select_pin == nil)
41
45
 
42
- header = spi_header(write, read, frequency, mode, bit_order)
46
+ header = spi_header(select_pin, write, read, frequency, mode, bit_order)
43
47
 
44
48
  self.write Message.encode command: 26,
45
49
  pin: select_pin,
@@ -47,11 +51,12 @@ module Denko
47
51
  end
48
52
 
49
53
  # CMD = 27
50
- def spi_listen(select_pin, read: 0, frequency: nil, mode: nil, bit_order: nil)
54
+ def spi_listen(spi_index, select_pin, read: 0, frequency: nil, mode: nil, bit_order: nil)
51
55
  raise ArgumentError, 'no bytes to read. Give read: argument > 0' unless (read > 0)
56
+ raise ArgumentError, "select_pin cannot be nil when reading or listening" if (select_pin == nil)
57
+
58
+ header = spi_header(select_pin, [], read, frequency, mode, bit_order)
52
59
 
53
- header = spi_header([], read, frequency, mode, bit_order)
54
-
55
60
  self.write Message.encode command: 27,
56
61
  pin: select_pin,
57
62
  aux_message: header
@@ -1,16 +1,16 @@
1
1
  module Denko
2
2
  class Board
3
- def spi_bb_header(clock, input, output, write, read, mode, bit_order)
3
+ def spi_bb_header(clock, input, output, select_pin, write, read, mode, bit_order)
4
4
  # Validate clock and data pins
5
- raise ArgumentError, "no clock pin given" unless clock
6
- raise ArgumentError, "no input or output pin given. Require either or both" unless(input || output)
5
+ raise ArgumentError, "either output or input pin required" unless(input || output)
6
+ raise ArgumentError, "clock pin required" unless clock
7
7
 
8
8
  # Set the other to disabled if only one given.
9
9
  input ||= 255
10
- ouptut ||= 255
10
+ output ||= 255
11
11
 
12
12
  # Get the generic part of the SPI header.
13
- header = spi_header_generic(write, read, mode, bit_order)
13
+ header = spi_header_generic(select_pin, write, read, mode, bit_order)
14
14
 
15
15
  # Generic header + packed pins + empty byte = bit bang SPI bheader.
16
16
  header = header + pack(:uint8, [clock, input, output, 0])
@@ -19,8 +19,9 @@ module Denko
19
19
  # CMD = 21
20
20
  def spi_bb_transfer(select_pin, clock: nil, output: nil, input: nil, write: [], read: 0, frequency: nil, mode: nil, bit_order: nil)
21
21
  raise ArgumentError, "no bytes given to read or write" if (read == 0) && (write.empty?)
22
+ raise ArgumentError, "select_pin cannot be nil when reading or listening" if (read != 0) && (select_pin == nil)
22
23
 
23
- header = spi_bb_header(clock, input, output, write, read, mode, bit_order)
24
+ header = spi_bb_header(clock, input, output, select_pin, write, read, mode, bit_order)
24
25
 
25
26
  self.write Message.encode command: 21,
26
27
  pin: select_pin,
@@ -30,8 +31,9 @@ module Denko
30
31
  # CMD = 22
31
32
  def spi_bb_listen(select_pin, clock: nil, input: nil, read: 0, frequency: nil, mode: nil, bit_order: nil)
32
33
  raise ArgumentError, 'no bytes to read. Give read: argument > 0' unless (read > 0)
34
+ raise ArgumentError, "select_pin cannot be nil when reading or listening" if (select_pin == nil)
33
35
 
34
- header = spi_bb_header(clock, input, nil, [], read, mode, bit_order)
36
+ header = spi_bb_header(clock, input, nil, select_pin, [], read, mode, bit_order)
35
37
 
36
38
  self.write Message.encode command: 22,
37
39
  pin: select_pin,
data/lib/denko/board.rb CHANGED
@@ -3,21 +3,21 @@ Dir["#{Denko.root}/lib/denko/board/*.rb"].each { |file| require file }
3
3
 
4
4
  module Denko
5
5
  class Board
6
- attr_reader :name, :version, :serial_buffer_size, :aux_limit, :eeprom_length
7
- attr_reader :low, :high, :analog_write_high, :analog_read_high
6
+ attr_reader :name, :version, :serial_buffer_size, :aux_limit, :eeprom_length, :i2c_limit
7
+ attr_reader :low, :high, :analog_write_resolution, :analog_read_resolution, :analog_write_high, :analog_read_high
8
8
 
9
- def initialize(transport, options={})
9
+ def initialize(connection, options={})
10
10
  # Shake hands
11
- @transport = transport
12
- ack = transport.handshake
11
+ @connection = connection
12
+ ack = connection.handshake
13
13
 
14
14
  # Split handshake acknowledgement into separate values.
15
15
  @name, @version, @serial_buffer_size, @aux_limit, @eeprom_length, @i2c_limit = ack.split(",")
16
16
 
17
- # Tell transport how much serial buffer the board has, for flow control.
17
+ # Tell connection how much serial buffer the board has, for flow control.
18
18
  @serial_buffer_size = @serial_buffer_size.to_i
19
19
  raise StandardError, "no serial buffer size given in handshake" if @serial_buffer_size < 1
20
- @transport.remote_buffer_size = @serial_buffer_size
20
+ @connection.remote_buffer_size = @serial_buffer_size
21
21
 
22
22
  # Load board map by name.
23
23
  @name = nil if @name.empty?
@@ -35,62 +35,54 @@ module Denko
35
35
  @version = nil if @version.empty?
36
36
  @eeprom_length = @eeprom_length.to_i
37
37
 
38
- # Transport calls #update on board when data is received.
39
- transport.add_observer(self)
40
-
38
+ # connection calls #update on board when data is received.
39
+ connection.add_observer(self)
40
+
41
41
  # Set digital and analog IO levels.
42
42
  @low = 0
43
43
  @high = 1
44
44
  self.analog_write_resolution = options[:write_bits] || 8
45
45
  self.analog_read_resolution = options[:read_bits] || 10
46
46
  end
47
-
47
+
48
48
  def finish_write
49
- sleep 0.001 while @transport.writing?
49
+ sleep 0.001 while @connection.writing?
50
50
  write "\n91\n"
51
- sleep 0.001 while @transport.writing?
51
+ sleep 0.001 while @connection.writing?
52
52
  end
53
-
53
+
54
54
  def analog_write_resolution=(value)
55
55
  set_analog_write_resolution(value)
56
- @write_bits = value
57
- @analog_write_high = (2 ** @write_bits) - 1
56
+ @analog_write_resolution = value
57
+ @analog_write_high = (2 ** @analog_write_resolution) - 1
58
58
  end
59
-
59
+
60
60
  def analog_read_resolution=(value)
61
61
  set_analog_read_resolution(value)
62
- @read_bits = value
63
- @analog_read_high = (2 ** @read_bits) - 1
64
- end
65
-
66
- def analog_write_resolution
67
- @write_bits
62
+ @analog_read_resolution = value
63
+ @analog_read_high = (2 ** @analog_read_resolution) - 1
68
64
  end
69
65
 
70
- def analog_read_resolution
71
- @read_bits
72
- end
73
-
74
66
  alias :pwm_high :analog_write_high
75
67
  alias :dac_high :analog_write_high
76
68
  alias :adc_high :analog_read_high
77
-
69
+
78
70
  def write(msg)
79
- @transport.write(msg)
71
+ @connection.write(msg)
80
72
  end
81
73
 
82
74
  #
83
75
  # Use Board#write_and_halt to call C++ board functions that disable interrupts
84
76
  # for a long time. "Long" being more than 1 serial character (~85us for 115200 baud).
85
77
  #
86
- # The "halt" part tells the TxRx to halt transmission to the board after this message.
78
+ # The "halt" part tells the Connection to halt transmission to the board after this message.
87
79
  # Since it expects interrupts to be disabled, any data sent could be lost.
88
- #
80
+ #
89
81
  # When the board function has re-enabled interrupts, it should call sendReady(). That
90
- # signal is read by the TxRx, telling it to resume transmisison.
82
+ # signal is read by the Connection, telling it to resume transmisison.
91
83
  #
92
84
  def write_and_halt(msg)
93
- @transport.write(msg, true)
85
+ @connection.write(msg, true)
94
86
  end
95
87
 
96
88
  #
@@ -100,6 +92,16 @@ module Denko
100
92
 
101
93
  def update(line)
102
94
  pin, message = line.split(":", 2)
95
+
96
+ # Handle messages from hardware I2C buses.
97
+ match = pin.match /\AI2C(\d*)/
98
+ if match
99
+ dev_index = match[1].to_i
100
+ dev = hw_i2c_comps[dev_index]
101
+ dev.update(message) if dev
102
+ return
103
+ end
104
+
103
105
  pin = pin.to_i
104
106
  if single_pin_components[pin]
105
107
  single_pin_components[pin].update(message)
@@ -0,0 +1,17 @@
1
+ module Denko
2
+ module Connection
3
+ class BinaryEcho
4
+ include Behaviors::SinglePin
5
+ include Behaviors::Reader
6
+
7
+ def test_range(min:0, max:255)
8
+ bytes = (min..max).to_a
9
+ board.binary_echo(pin, bytes)
10
+ end
11
+
12
+ def test_array(arr)
13
+ board.binary_echo(pin, arr)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -8,8 +8,8 @@ module Denko
8
8
  @transit_mutex.synchronize { @remote_buffer_size = size }
9
9
  end
10
10
 
11
- def initialize(*args)
12
- super(*args)
11
+ def initialize(*args, **kwargs)
12
+ super(*args, **kwargs)
13
13
  # Start with minimum known buffer size. Board will update after handshake.
14
14
  # WARNING: If not updated, and ack threshold on the board is > minimum,
15
15
  # FlowControl will stop sending data, and appear to hang. Fix this.
@@ -27,7 +27,7 @@ module Denko
27
27
  @tx_halt_points << @write_buffer.length if tx_halt_after
28
28
  end
29
29
  end
30
-
30
+
31
31
  def writing?
32
32
  @write_buffer_mutex.synchronize { !@write_buffer.empty? }
33
33
  end
@@ -45,13 +45,12 @@ module Denko
45
45
  @tx_halt_points = []
46
46
  end
47
47
  end
48
-
48
+
49
49
  def write_from_buffer
50
50
  fragment = nil
51
51
  halt_after_fragment = false
52
52
 
53
53
  @write_buffer_mutex.synchronize do
54
- # Nothing to write.
55
54
  break if @write_buffer.empty?
56
55
 
57
56
  # Try to send the entire buffer unless a halt point is coming up.
@@ -80,12 +79,10 @@ module Denko
80
79
  end
81
80
  end
82
81
 
83
- # If no fragment, wait.
84
82
  return wait unless fragment
85
83
 
86
- # If fragment, write it.
87
84
  loop do
88
- # Write and end loop if the board is ready.
85
+ # Write fragment if @tx_ready.
89
86
  @tx_ready_mutex.synchronize do
90
87
  if @tx_ready
91
88
  _write fragment
@@ -110,7 +107,7 @@ module Denko
110
107
 
111
108
  def read
112
109
  line = _read
113
-
110
+
114
111
  if line
115
112
  case line[0..2]
116
113
  # Board read (freed) this many bytes from its input buffer.
@@ -142,19 +139,18 @@ module Denko
142
139
  end
143
140
 
144
141
  def tx_halt
145
- @tx_ready_mutex.synchronize { @tx_ready = false }
142
+ @tx_ready_mutex.synchronize { @tx_ready = false }
146
143
  end
147
144
 
148
145
  def tx_resume
149
146
  @tx_ready_mutex.synchronize { @tx_ready = true }
150
147
  end
151
148
 
152
- def add_transit_bytes(value)
153
- @transit_mutex.synchronize { @transit_bytes = @transit_bytes + value }
154
- end
155
-
156
149
  def remove_transit_bytes(value)
157
- @transit_mutex.synchronize { @transit_bytes = @transit_bytes - value }
150
+ @transit_mutex.synchronize do
151
+ @transit_bytes = @transit_bytes - value
152
+ @transit_bytes = 0 if @transit_bytes < 0
153
+ end
158
154
  end
159
155
  end
160
156
  end
@@ -22,7 +22,9 @@ module Denko
22
22
  HANDSHAKE_TIMEOUT = 2
23
23
 
24
24
  def handshake
25
+ _write Message.encode(command: 90)
25
26
  io_reset
27
+
26
28
  HANDSHAKE_TRIES.times do |retries|
27
29
  begin
28
30
  print "Sending handshake to: #{self.to_s}... "
@@ -1,6 +1,10 @@
1
1
  module Denko
2
2
  module DigitalIO
3
3
  class Button < Input
4
+ before_initialize do
5
+ params[:divider] = 1
6
+ end
7
+
4
8
  alias :down :on_low
5
9
  alias :up :on_high
6
10
  end
@@ -0,0 +1,15 @@
1
+ module Denko
2
+ module DigitalIO
3
+ class CBitBang
4
+ include Behaviors::SinglePin
5
+ include Behaviors::Callbacks
6
+ include Behaviors::Lifecycle
7
+
8
+ # This is purely to force initialize validation for any pins
9
+ # being used by C libraries that bit-bang.
10
+ before_initialize do
11
+ params[:mode] ||= :input
12
+ end
13
+ end
14
+ end
15
+ end
@@ -5,11 +5,10 @@ module Denko
5
5
  include Behaviors::Reader
6
6
  include Behaviors::Poller
7
7
  include Behaviors::Listener
8
+ include Behaviors::Lifecycle
8
9
 
9
- def after_initialize(options={})
10
- super(options)
11
- @divider = 4
12
- _listen
10
+ after_initialize do
11
+ _listen(params[:divider] || 4)
13
12
  end
14
13
 
15
14
  def _read
@@ -32,7 +31,7 @@ module Denko
32
31
  block.call(data) if data.to_i == board.low
33
32
  end
34
33
  end
35
-
34
+
36
35
  def pre_callback_filter(value)
37
36
  value.to_i
38
37
  end
@@ -4,10 +4,11 @@ module Denko
4
4
  include Behaviors::OutputPin
5
5
  include Behaviors::Callbacks
6
6
  include Behaviors::Threaded
7
+ include Behaviors::Lifecycle
8
+
7
9
  interrupt_with :digital_write
8
10
 
9
- def after_initialize(options={})
10
- super(options)
11
+ after_initialize do
11
12
  board.digital_read(pin)
12
13
  end
13
14
 
@@ -19,7 +20,7 @@ module Denko
19
20
  @board.digital_write(@pin, value)
20
21
  self.state = value
21
22
  end
22
-
23
+
23
24
  alias :write :digital_write
24
25
 
25
26
  def low
@@ -33,13 +34,13 @@ module Denko
33
34
  def toggle
34
35
  state == board.low ? high : low
35
36
  end
36
-
37
+
37
38
  alias :off :low
38
39
  alias :on :high
39
-
40
+
40
41
  def high?; state == board.high end
41
42
  def low?; state == board.low end
42
-
43
+
43
44
  alias :on? :high?
44
45
  alias :off? :low?
45
46
  end
@@ -1,6 +1,8 @@
1
1
  module Denko
2
2
  module DigitalIO
3
3
  class Relay < Output
4
+ alias :open :off
5
+ alias :close :on
4
6
  end
5
7
  end
6
8
  end