denko 0.13.0 → 0.13.2
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.
- checksums.yaml +4 -4
- data/.github/workflows/build_avr.yml +2 -4
- data/.github/workflows/build_esp32.yml +2 -3
- data/.github/workflows/build_esp8266.yml +2 -3
- data/.github/workflows/build_megaavr.yml +2 -4
- data/.github/workflows/build_ra4m1.yml +57 -0
- data/.github/workflows/build_rp2040.yml +2 -4
- data/.github/workflows/build_sam3x.yml +1 -3
- data/.github/workflows/build_samd.yml +2 -4
- data/CHANGELOG.md +60 -0
- data/DEPS_CLI.md +8 -6
- data/DEPS_IDE.md +9 -7
- data/HARDWARE.md +98 -75
- data/README.md +48 -59
- data/benchmarks/i2c_ssd1306_refresh.rb +74 -0
- data/examples/analog_io/ads1115.rb +57 -0
- data/examples/analog_io/ads1118.rb +8 -9
- data/examples/analog_io/dac_loopback.rb +6 -4
- data/examples/analog_io/input.rb +39 -36
- data/examples/connection/tcp.rb +1 -1
- data/examples/display/hd44780.rb +3 -3
- data/examples/display/ssd1306.rb +1 -1
- data/examples/pulse_io/buzzer.rb +40 -0
- data/examples/sensor/aht20.rb +1 -1
- data/lib/denko/analog_io/ads1115.rb +61 -0
- data/lib/denko/analog_io/ads1118.rb +10 -120
- data/lib/denko/analog_io/ads111x.rb +123 -0
- data/lib/denko/analog_io/output.rb +2 -1
- data/lib/denko/analog_io.rb +2 -0
- data/lib/denko/behaviors/bus_peripheral_addressed.rb +1 -1
- data/lib/denko/behaviors/component.rb +1 -1
- data/lib/denko/behaviors/input_pin.rb +3 -0
- data/lib/denko/behaviors/reader.rb +14 -13
- data/lib/denko/behaviors/single_pin.rb +1 -3
- data/lib/denko/behaviors/state.rb +1 -0
- data/lib/denko/behaviors/subcomponents.rb +2 -2
- data/lib/denko/board/core.rb +1 -1
- data/lib/denko/board/i2c.rb +1 -4
- data/lib/denko/board/map.rb +9 -0
- data/lib/denko/board/servo.rb +2 -6
- data/lib/denko/board.rb +32 -20
- data/lib/denko/connection/board_uart.rb +3 -3
- data/lib/denko/connection/flow_control.rb +10 -2
- data/lib/denko/digital_io/output.rb +1 -1
- data/lib/denko/display/hd44780.rb +18 -18
- data/lib/denko/led/seven_segment.rb +18 -19
- data/lib/denko/message.rb +6 -14
- data/lib/denko/one_wire/bus.rb +1 -1
- data/lib/denko/one_wire/{bus_enumeration.rb → bus_enumerator.rb} +16 -8
- data/lib/denko/one_wire/helper.rb +1 -1
- data/lib/denko/one_wire.rb +1 -1
- data/lib/denko/pulse_io/ir_transmitter.rb +1 -2
- data/lib/denko/sensor/ds18b20.rb +1 -1
- data/lib/denko/version.rb +1 -1
- data/lib/denko_cli/packages.rb +7 -1
- data/lib/denko_cli/targets.rb +8 -5
- data/lib/denko_cli/usage.txt +8 -4
- data/src/denko_ethernet.ino +15 -23
- data/src/denko_serial.ino +3 -14
- data/src/denko_wifi.ino +35 -50
- data/src/lib/Denko.cpp +23 -6
- data/src/lib/Denko.h +6 -16
- data/src/lib/DenkoCoreIO.cpp +3 -3
- data/src/lib/DenkoDefines.h +62 -16
- data/src/lib/DenkoEEPROM.cpp +9 -1
- data/src/lib/DenkoI2C.cpp +11 -9
- data/src/lib/DenkoLEDArray.cpp +1 -1
- data/target.yml +35 -1
- data/test/behaviors/reader_test.rb +8 -1
- data/test/board/helper_test.rb +0 -4
- data/test/display/hd44780_test.rb +10 -0
- data/test/led/seven_segment_test.rb +30 -8
- data/test/one_wire/bus_enumerator_test.rb +4 -0
- data/test/one_wire/helper_test.rb +5 -5
- data/test/sensor/ds18b20_test.rb +10 -0
- data/test/test_helper.rb +17 -2
- data/vendor/board-maps/.gitmodules +3 -0
- data/vendor/board-maps/BoardMap.h +40 -12
- data/vendor/board-maps/README.md +1 -0
- data/vendor/board-maps/lib/header_parser.rb +30 -5
- data/vendor/board-maps/run.rb +11 -1
- data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32S3.yml +6 -1
- data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32S3_NOPSRAM.yml +6 -1
- data/vendor/board-maps/yaml/ADAFRUIT_FEATHER_ESP32_V2.yml +5 -1
- data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32S3_N4R2.yml +20 -0
- data/vendor/board-maps/yaml/ADAFRUIT_QTPY_ESP32_PICO.yml +2 -1
- data/vendor/board-maps/yaml/ARTRONSHOP_RP2_NANO.yml +32 -0
- data/vendor/board-maps/yaml/AVR_CIRCUITPLAY.yml +1 -1
- data/vendor/board-maps/yaml/AVR_ESPLORA.yml +1 -1
- data/vendor/board-maps/yaml/AVR_INDUSTRIAL101.yml +1 -1
- data/vendor/board-maps/yaml/AVR_LEONARDO.yml +1 -1
- data/vendor/board-maps/yaml/AVR_LEONARDO_ETH.yml +1 -1
- data/vendor/board-maps/yaml/AVR_LILYPAD_USB.yml +1 -1
- data/vendor/board-maps/yaml/AVR_LININO_ONE.yml +1 -1
- data/vendor/board-maps/yaml/AVR_MICRO.yml +1 -1
- data/vendor/board-maps/yaml/AVR_ROBOT_CONTROL.yml +1 -1
- data/vendor/board-maps/yaml/AVR_ROBOT_MOTOR.yml +1 -1
- data/vendor/board-maps/yaml/AVR_YUN.yml +1 -1
- data/vendor/board-maps/yaml/AVR_YUNMINI.yml +1 -1
- data/vendor/board-maps/yaml/BPI_LEAF_S3.yml +11 -1
- data/vendor/board-maps/yaml/BeeMotionS3.yml +6 -1
- data/vendor/board-maps/yaml/Bee_Motion.yml +3 -0
- data/vendor/board-maps/yaml/Bee_S3.yml +1 -1
- data/vendor/board-maps/yaml/CHALLENGER_2040_WIFI6_BLE_RP2040.yml +42 -0
- data/vendor/board-maps/yaml/CYTRON_MAKER_FEATHER_AIOT_S3.yml +4 -1
- data/vendor/board-maps/yaml/CoreESP32.yml +5 -1
- data/vendor/board-maps/yaml/D1_MINI32.yml +10 -1
- data/vendor/board-maps/yaml/DENKY.yml +10 -1
- data/vendor/board-maps/yaml/DENKY_PICOV3.yml +10 -1
- data/vendor/board-maps/yaml/DENKY_WROOM32.yml +10 -1
- data/vendor/board-maps/yaml/DFROBOT_FIREBEETLE_2_ESP32E.yml +6 -1
- data/vendor/board-maps/yaml/DPU_ESP32.yml +10 -1
- data/vendor/board-maps/yaml/D_Duino_32.yml +9 -1
- data/vendor/board-maps/yaml/ESP32S2_DEV.yml +11 -1
- data/vendor/board-maps/yaml/ESP32S2_THING_PLUS.yml +11 -1
- data/vendor/board-maps/yaml/ESP32S2_USB.yml +11 -1
- data/vendor/board-maps/yaml/ESP32_DEV.yml +10 -1
- data/vendor/board-maps/yaml/ESP32_DEVKIT_LIPO.yml +10 -1
- data/vendor/board-maps/yaml/ESP32_IOT_REDBOARD.yml +10 -1
- data/vendor/board-maps/yaml/ESP32_PICO.yml +10 -1
- data/vendor/board-maps/yaml/ESP32_S3_BOX.yml +4 -1
- data/vendor/board-maps/yaml/ESP32_THING.yml +10 -1
- data/vendor/board-maps/yaml/ESP32_THING_PLUS.yml +4 -1
- data/vendor/board-maps/yaml/ESP32_THING_PLUS_C.yml +4 -1
- data/vendor/board-maps/yaml/ESP32_WROOM_DA.yml +10 -1
- data/vendor/board-maps/yaml/ESP32_WROVER_KIT.yml +10 -1
- data/vendor/board-maps/yaml/ESPECTRO32.yml +10 -1
- data/vendor/board-maps/yaml/ESPea32.yml +10 -1
- data/vendor/board-maps/yaml/ESPino32.yml +10 -1
- data/vendor/board-maps/yaml/FEATHERS2.yml +11 -1
- data/vendor/board-maps/yaml/FEATHERS2NEO.yml +2 -1
- data/vendor/board-maps/yaml/FEATHERS3.yml +3 -0
- data/vendor/board-maps/yaml/FEATHER_ESP32.yml +5 -1
- data/vendor/board-maps/yaml/FRANZININHO_WIFI.yml +11 -1
- data/vendor/board-maps/yaml/FRANZININHO_WIFI_MSC.yml +11 -1
- data/vendor/board-maps/yaml/FROG_ESP32.yml +10 -1
- data/vendor/board-maps/yaml/HEALTHYPI_4.yml +10 -1
- data/vendor/board-maps/yaml/HONEYLEMON.yml +10 -1
- data/vendor/board-maps/yaml/HORNBILL_ESP32_DEV.yml +10 -1
- data/vendor/board-maps/yaml/HORNBILL_ESP32_MINIMA.yml +4 -1
- data/vendor/board-maps/yaml/IMBRIOS_LOGSENS_V1P1.yml +5 -1
- data/vendor/board-maps/yaml/LILYGO_T_DISPLAY_S3.yml +7 -1
- data/vendor/board-maps/yaml/LOLIN32.yml +10 -1
- data/vendor/board-maps/yaml/LOLIN32_LITE.yml +10 -1
- data/vendor/board-maps/yaml/LOLIN_D32.yml +10 -1
- data/vendor/board-maps/yaml/LOLIN_D32_PRO.yml +10 -1
- data/vendor/board-maps/yaml/LOLIN_S2_MINI.yml +11 -1
- data/vendor/board-maps/yaml/LOLIN_S2_PICO.yml +11 -1
- data/vendor/board-maps/yaml/LOLIN_S3.yml +9 -1
- data/vendor/board-maps/yaml/LOLIN_S3_MINI.yml +9 -1
- data/vendor/board-maps/yaml/LOLIN_S3_PRO.yml +9 -1
- data/vendor/board-maps/yaml/LoPy.yml +11 -1
- data/vendor/board-maps/yaml/LoPy4.yml +11 -1
- data/vendor/board-maps/yaml/MAGTAG29_ESP32S2.yml +11 -1
- data/vendor/board-maps/yaml/METRO_ESP32S2.yml +11 -1
- data/vendor/board-maps/yaml/MGBOT_IOTIK32A.yml +10 -1
- data/vendor/board-maps/yaml/MGBOT_IOTIK32B.yml +10 -1
- data/vendor/board-maps/yaml/MH_ET_LIVE_ESP32DEVKIT.yml +10 -1
- data/vendor/board-maps/yaml/MH_ET_LIVE_ESP32MINIKIT.yml +10 -1
- data/vendor/board-maps/yaml/MICROS2.yml +11 -1
- data/vendor/board-maps/yaml/MINIMA.yml +15 -0
- data/vendor/board-maps/yaml/NANO32.yml +10 -1
- data/vendor/board-maps/yaml/Node32s.yml +10 -1
- data/vendor/board-maps/yaml/NodeMCU_32S.yml +10 -1
- data/vendor/board-maps/yaml/ONEHORSE_ESP32_DEV.yml +11 -1
- data/vendor/board-maps/yaml/PIMORONI_PLASMA2040.yml +29 -0
- data/vendor/board-maps/yaml/PORTENTA_C33.yml +28 -0
- data/vendor/board-maps/yaml/PROS3.yml +6 -1
- data/vendor/board-maps/yaml/PYCOM_GPY.yml +11 -1
- data/vendor/board-maps/yaml/Piranha.yml +7 -1
- data/vendor/board-maps/yaml/Pocket32.yml +10 -1
- data/vendor/board-maps/yaml/QUANTUM.yml +10 -1
- data/vendor/board-maps/yaml/REDPILL_ESP32S3.yml +11 -1
- data/vendor/board-maps/yaml/RMP.yml +11 -1
- data/vendor/board-maps/yaml/SAMD_CIRCUITPLAYGROUND_EXPRESS.yml +0 -1
- data/vendor/board-maps/yaml/SAM_DUE.yml +3 -1
- data/vendor/board-maps/yaml/SONOFF_DUALR3.yml +10 -1
- data/vendor/board-maps/yaml/TAMC_TERMOD_S3.yml +11 -1
- data/vendor/board-maps/yaml/TBEAM_USE_RADIO_SX1262.yml +6 -1
- data/vendor/board-maps/yaml/TBEAM_USE_RADIO_SX1268.yml +6 -1
- data/vendor/board-maps/yaml/TBEAM_USE_RADIO_SX1276.yml +6 -1
- data/vendor/board-maps/yaml/TBEAM_USE_RADIO_SX1278.yml +6 -1
- data/vendor/board-maps/yaml/TBEAM_USE_RADIO_SX1280.yml +6 -1
- data/vendor/board-maps/yaml/TBeam.yml +6 -1
- data/vendor/board-maps/yaml/TINYPICO.yml +10 -1
- data/vendor/board-maps/yaml/TINYS2.yml +11 -1
- data/vendor/board-maps/yaml/TTGO_LoRa32_V1.yml +11 -1
- data/vendor/board-maps/yaml/TTGO_LoRa32_V2.yml +11 -1
- data/vendor/board-maps/yaml/TTGO_LoRa32_v21new.yml +11 -1
- data/vendor/board-maps/yaml/TTGO_T1.yml +10 -1
- data/vendor/board-maps/yaml/TTGO_T7_V13_Mini32.yml +10 -1
- data/vendor/board-maps/yaml/TTGO_T7_V14_Mini32.yml +10 -1
- data/vendor/board-maps/yaml/TWATCH_2020_V1.yml +0 -1
- data/vendor/board-maps/yaml/TWATCH_2020_V2.yml +0 -1
- data/vendor/board-maps/yaml/TWATCH_2020_V3.yml +0 -1
- data/vendor/board-maps/yaml/TWATCH_BASE.yml +0 -1
- data/vendor/board-maps/yaml/TWatch.yml +0 -1
- data/vendor/board-maps/yaml/UBLOX_NINA_W10.yml +10 -1
- data/vendor/board-maps/yaml/UNOWIFIR4.yml +17 -0
- data/vendor/board-maps/yaml/WIPY3.yml +11 -1
- data/vendor/board-maps/yaml/XIAO_ESP32S3.yml +2 -1
- data/vendor/board-maps/yaml/connaxio_espoir.yml +7 -1
- data/vendor/board-maps/yaml/esp32vn_iot_uno.yml +10 -1
- data/vendor/board-maps/yaml/heltec_wifi_32_lora_V3.yml +11 -1
- data/vendor/board-maps/yaml/heltec_wifi_kit_32.yml +11 -1
- data/vendor/board-maps/yaml/heltec_wifi_kit_32_V3.yml +11 -1
- data/vendor/board-maps/yaml/heltec_wifi_lora_32.yml +10 -1
- data/vendor/board-maps/yaml/heltec_wifi_lora_32_V2.yml +10 -1
- data/vendor/board-maps/yaml/heltec_wireless_stick.yml +10 -1
- data/vendor/board-maps/yaml/heltec_wireless_stick_LITE.yml +10 -1
- data/vendor/board-maps/yaml/openkb.yml +11 -1
- data/vendor/board-maps/yaml/roboheart_hercules.yml +10 -1
- data/vendor/board-maps/yaml/sensesiot_weizen.yml +10 -1
- data/vendor/board-maps/yaml/uPesy_WROOM.yml +10 -1
- data/vendor/board-maps/yaml/uPesy_WROVER.yml +10 -1
- data/vendor/board-maps/yaml/unphone8.yml +11 -1
- data/vendor/board-maps/yaml/unphone9.yml +11 -1
- metadata +15 -3
@@ -14,12 +14,12 @@ bus = Denko::SPI::Bus.new(board: board)
|
|
14
14
|
# bus = Denko::SPI::BitBang.new(board: board, pins: SPI_BIT_BANG_PINS)
|
15
15
|
|
16
16
|
# Connect chip select/enable pin of the ADS1118 to pin 9.
|
17
|
-
|
17
|
+
ads = Denko::AnalogIO::ADS1118.new(bus: bus, pin: 9)
|
18
18
|
|
19
19
|
# Helper method so readings look nice.
|
20
20
|
def print_reading(name, raw, voltage)
|
21
21
|
print "#{Time.now.strftime '%Y-%m-%d %H:%M:%S'} - "
|
22
|
-
print "#{name.rjust(
|
22
|
+
print "#{name.rjust(18, " ")} | "
|
23
23
|
print "Raw: #{raw.to_s.rjust(6, " ")} | "
|
24
24
|
print "Voltage: "
|
25
25
|
print ("%.10f" % voltage).rjust(13, " ")
|
@@ -30,7 +30,7 @@ end
|
|
30
30
|
# Read the ADS1118 internal temperature sensor.
|
31
31
|
# This always uses the 128 SPS mode, and there is no polling method for it.
|
32
32
|
#
|
33
|
-
temperature =
|
33
|
+
temperature = ads.temperature_read
|
34
34
|
puts "ADS1118 Temperature: #{temperature} \xC2\xB0C"
|
35
35
|
puts
|
36
36
|
|
@@ -41,7 +41,7 @@ puts
|
|
41
41
|
#
|
42
42
|
# Note: This is the only way to use continuous mode. Subcomponents always use one-shot.
|
43
43
|
#
|
44
|
-
|
44
|
+
ads.read([0b10000001, 0b10001011]) do |reading|
|
45
45
|
voltage = reading * 0.0001875
|
46
46
|
print_reading("Direct", reading, voltage)
|
47
47
|
end
|
@@ -49,26 +49,25 @@ end
|
|
49
49
|
#
|
50
50
|
# Or use its BoardProxy interface, adding subcomponents as if it were a Board.
|
51
51
|
# The key adc: can substitute for board: when intializing AnalogIO::Input.
|
52
|
-
#
|
53
52
|
# Gain and sample rate bitmasks can be found in the datasheet.
|
54
53
|
#
|
55
54
|
# Input on pin 0, with pin 1 as differential negative input, and 6.144 V full range.
|
56
|
-
diff_input = Denko::AnalogIO::Input.new(adc:
|
55
|
+
diff_input = Denko::AnalogIO::Input.new(adc: ads, pin: 0, negative_pin: 1, gain: 0b000)
|
57
56
|
|
58
57
|
# Input on pin 2 with no negative input (single ended), and 1.024V full range.
|
59
58
|
# Ths one uses a 8 SPS rate, essentially 16x oversampling compared to the default 128.
|
60
|
-
single_input = Denko::AnalogIO::Input.new(adc:
|
59
|
+
single_input = Denko::AnalogIO::Input.new(adc: ads, pin: 2, gain: 0b011, sample_rate: 0b000)
|
61
60
|
|
62
61
|
# Poll the differential input every second.
|
63
62
|
diff_input.poll(1) do |reading|
|
64
63
|
voltage = reading * diff_input.volts_per_bit
|
65
|
-
print_reading("Differential", reading, voltage)
|
64
|
+
print_reading("Differential A1-A0", reading, voltage)
|
66
65
|
end
|
67
66
|
|
68
67
|
# Poll the single ended input every 2 seconds.
|
69
68
|
single_input.poll(2) do |reading|
|
70
69
|
voltage = reading * single_input.volts_per_bit
|
71
|
-
print_reading("Single", reading, voltage)
|
70
|
+
print_reading("Single A2-GN", reading, voltage)
|
72
71
|
end
|
73
72
|
|
74
73
|
sleep
|
@@ -5,13 +5,15 @@ require 'bundler/setup'
|
|
5
5
|
require 'denko'
|
6
6
|
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# Arduino Zero: :DAC0 is :A0 is GPIO14
|
9
|
+
# Arduino UNO R4: :DAC is :A0 is GPIO14
|
10
|
+
# ESP32 V1: :DAC0 is GPIO25, :DAC1 is GPIO26, :A4 is GPIO32
|
11
|
+
# ESP32-S2: :DAC0 is GPIO17, :DAC1 is GPIO18, :A4 is GPIO5
|
10
12
|
#
|
11
13
|
# Connect DAC_PIN TO ADC_PIN with a jumper to test.
|
12
14
|
#
|
13
|
-
DAC_PIN =
|
14
|
-
ADC_PIN =
|
15
|
+
DAC_PIN = :DAC0
|
16
|
+
ADC_PIN = :A4
|
15
17
|
|
16
18
|
board = Denko::Board.new(Denko::Connection::Serial.new)
|
17
19
|
dac = Denko::AnalogIO::Output.new(pin: DAC_PIN, board: board)
|
data/examples/analog_io/input.rb
CHANGED
@@ -1,52 +1,55 @@
|
|
1
1
|
#
|
2
|
-
# This
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
2
|
+
# This example shows how to use your board's analog-to-digital-converter(ADC) pins,
|
3
|
+
# through the AnalogIO::Input class. ADC inputs can be connected to sensors
|
4
|
+
# which produce a variable output voltage, such as light dependent resistors,
|
5
|
+
# or a simple temperature sensor like the TMP36.
|
6
6
|
#
|
7
7
|
require 'bundler/setup'
|
8
8
|
require 'denko'
|
9
9
|
|
10
10
|
board = Denko::Board.new(Denko::Connection::Serial.new)
|
11
|
-
|
12
|
-
|
13
|
-
# Single read
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
11
|
+
input = Denko::AnalogIO::Input.new(pin: :A0, board: board)
|
12
|
+
|
13
|
+
# Single read that blocks the main thread. When a value is received, the given
|
14
|
+
# code block runs only once, and then the main thread continues.
|
15
|
+
input.read { |value| puts "#{Time.now} Single read #1: #{value}" }
|
16
|
+
|
17
|
+
# Read (poll) the input every half second. This happens in a separate thread,
|
18
|
+
# so sleep the main thread for a while to get some values.
|
19
|
+
# Given code block is added as a callback, and runs every time a value is received.
|
20
|
+
input.poll(0.5) { |value| puts "#{Time.now} Polling: #{value}" }
|
21
|
+
sleep 3
|
22
|
+
|
23
|
+
# Stop polling. Automatically removes the #poll callback.
|
24
|
+
input.stop
|
25
|
+
|
26
|
+
# Listening is similar to polling. The board reads the input and sends the value
|
27
|
+
# every time interval, except it's keeping time. We only send the initial command,
|
28
|
+
# not one for each read. Smaller intervals like 32 milliseconds are possible.
|
29
|
+
# Powers of 2 from 1 to 128 are supported for listener intervals.
|
30
|
+
input.listen(32) { |value| puts "#{Time.now} Listening: #{value}" }
|
27
31
|
sleep 0.5
|
28
32
|
|
29
|
-
# Stop listening. Automatically removes the
|
30
|
-
|
31
|
-
|
32
|
-
# Add a persistent callback.
|
33
|
-
sensor.on_data { |value| puts "#{Time.now} Persistent callback: #{value}" }
|
33
|
+
# Stop listening. Automatically removes the #listen callback.
|
34
|
+
input.stop
|
34
35
|
|
35
|
-
#
|
36
|
-
|
36
|
+
# This adds a persistent callback, which runs no matter how a read happens.
|
37
|
+
# It will not be removed by #stop.
|
38
|
+
input.on_data { |value| puts "#{Time.now} Persistent callback: #{value}" }
|
37
39
|
|
38
|
-
#
|
39
|
-
|
40
|
+
# This is a persistent callback with a custom key.
|
41
|
+
input.on_data(:test) { |value| puts "#{Time.now} Keyed callback: #{value}"}
|
40
42
|
|
41
|
-
#
|
42
|
-
|
43
|
-
sleep 0.5
|
43
|
+
# If we do a single read, the two persistent callbacks, and the block given, should run once each.
|
44
|
+
input.read { |value| puts "#{Time.now} Single read #2: #{value}" }
|
44
45
|
|
45
|
-
#
|
46
|
-
|
46
|
+
# If we listen, the two persistent callbacks, and the block given should run many times.
|
47
|
+
input.listen(8) { |value| puts "#{Time.now } Listening again: #{value}" }
|
48
|
+
sleep 0.125
|
49
|
+
input.stop
|
47
50
|
|
48
51
|
# Remove callbacks keyed with :test.
|
49
|
-
|
52
|
+
input.remove_callbacks(:test)
|
50
53
|
|
51
54
|
# Remove all callbacks.
|
52
|
-
|
55
|
+
input.remove_callbacks
|
data/examples/connection/tcp.rb
CHANGED
@@ -11,7 +11,7 @@ connection = Denko::Connection::TCP.new("192.168.0.77", 3466)
|
|
11
11
|
# connection = Denko::Connection::TCP.new("192.168.1.2", 3466)
|
12
12
|
#
|
13
13
|
board = Denko::Board.new(connection)
|
14
|
-
led = Denko::
|
14
|
+
led = Denko::LED.new(board: board, pin: :LED_BUILTIN)
|
15
15
|
|
16
16
|
[:on, :off].cycle do |switch|
|
17
17
|
led.send(switch)
|
data/examples/display/hd44780.rb
CHANGED
@@ -6,9 +6,9 @@ require 'denko'
|
|
6
6
|
|
7
7
|
board = Denko::Board.new(Denko::Connection::Serial.new)
|
8
8
|
lcd = Denko::Display::HD44780.new board: board,
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
pins: { rs: 8, enable: 9, d4: 4, d5: 5, d6: 6, d7: 7 },
|
10
|
+
cols: 16,
|
11
|
+
rows: 2
|
12
12
|
|
13
13
|
# Bitmap for a custom character. 5 bits wide x 8 high.
|
14
14
|
# Useful for generating these: https://omerk.github.io/lcdchargen/
|
data/examples/display/ssd1306.rb
CHANGED
@@ -21,7 +21,7 @@ board = Denko::Board.new(Denko::Connection::Serial.new)
|
|
21
21
|
# Only give the SDA pin of the I2C bus. SCL (clock) pin must be
|
22
22
|
# connected for it to work, but we don't need to control it.
|
23
23
|
#
|
24
|
-
bus = Denko::I2C::Bus.new(board: board, pin:
|
24
|
+
bus = Denko::I2C::Bus.new(board: board, pin: :SDA)
|
25
25
|
oled = Denko::Display::SSD1306.new(bus: bus, rotate: true)
|
26
26
|
canvas = oled.canvas
|
27
27
|
|
data/examples/pulse_io/buzzer.rb
CHANGED
@@ -7,6 +7,7 @@ require 'denko'
|
|
7
7
|
board = Denko::Board.new(Denko::Connection::Serial.new)
|
8
8
|
buzzer = Denko::PulseIO::Buzzer.new(board: board, pin: 9)
|
9
9
|
|
10
|
+
=begin
|
10
11
|
C4 = 262
|
11
12
|
D4 = 294
|
12
13
|
E4 = 330
|
@@ -28,3 +29,42 @@ end
|
|
28
29
|
|
29
30
|
buzzer.stop
|
30
31
|
board.finish_write
|
32
|
+
=end
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
AS3 = 233
|
37
|
+
BN3 = 257
|
38
|
+
DS4 = 311
|
39
|
+
FN4 = 349
|
40
|
+
FS4 = 370
|
41
|
+
GS4 = 415
|
42
|
+
|
43
|
+
notes = [
|
44
|
+
[AS3, 1], [AS3, 1], [AS3, 1], [AS3, 1],
|
45
|
+
[AS3, 0.75], [BN3, 0.75], [DS4, 0.5], [AS3, 1], [AS3, 0.5], [nil, 0.5],
|
46
|
+
[AS3, 0.75], [BN3, 0.75], [DS4, 0.5], [AS3, 1], [AS3, 0.5], [nil, 0.5],
|
47
|
+
[AS3, 0.75], [BN3, 0.75], [DS4, 0.5], [FN4, 1], [FN4, 0.5], [nil, 0.5],
|
48
|
+
[GS4, 0.75], [FS4, 0.75], [FN4, 0.5], [DS4, 1], [DS4, 0.5], [nil, 0.5],
|
49
|
+
[GS4, 0.75], [FS4, 0.75], [FN4, 0.5], [DS4, 1], [DS4, 0.5], [nil, 0.5],
|
50
|
+
[AS3, 0.75], [BN3, 0.75], [DS4, 0.5], [AS3, 1], [AS3, 0.5], [nil, 0.5],
|
51
|
+
[AS3, 0.75], [BN3, 0.75], [DS4, 0.5], [AS3, 1], [AS3, 0.5], [nil, 0.5],
|
52
|
+
]
|
53
|
+
|
54
|
+
bpm = 135
|
55
|
+
beat_time = 60.to_f / bpm
|
56
|
+
|
57
|
+
notes.each do |note|
|
58
|
+
if note[0]
|
59
|
+
buzzer.tone(note[0])
|
60
|
+
sleep(note[1] * beat_time)
|
61
|
+
else
|
62
|
+
buzzer.stop
|
63
|
+
sleep((note[1] * beat_time))
|
64
|
+
end
|
65
|
+
buzzer.stop
|
66
|
+
buzzer.micro_delay(5)
|
67
|
+
end
|
68
|
+
|
69
|
+
buzzer.stop
|
70
|
+
board.finish_write
|
data/examples/sensor/aht20.rb
CHANGED
@@ -5,7 +5,7 @@ require 'bundler/setup'
|
|
5
5
|
require 'denko'
|
6
6
|
|
7
7
|
board = Denko::Board.new(Denko::Connection::Serial.new)
|
8
|
-
bus = Denko::I2C::Bus.new(board: board, pin: :
|
8
|
+
bus = Denko::I2C::Bus.new(board: board, pin: :SDA)
|
9
9
|
aht20 = Denko::Sensor::AHT20.new(bus: bus)
|
10
10
|
|
11
11
|
aht20.poll(2) do |reading|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Denko
|
2
|
+
module AnalogIO
|
3
|
+
class ADS1115
|
4
|
+
include I2C::Peripheral
|
5
|
+
include ADS111X
|
6
|
+
|
7
|
+
# Config register values on startup. MSB-first.
|
8
|
+
# Matches datasheet, except MSB bit 7 unset to avoid conversion start.
|
9
|
+
# Same as: [0x05, 0x83] or [5, 131]
|
10
|
+
CONFIG_STARTUP = [0b00000101, 0b10000011]
|
11
|
+
|
12
|
+
# Base config bytes to mask settings into. Not same as startup config.
|
13
|
+
# MSB bits 0 and 7 set to enable single-shot mode.
|
14
|
+
# LSB bits 0 and 1 set to disable comparator.
|
15
|
+
BASE_MSB = 0b10000001
|
16
|
+
BASE_LSB = 0b00000011
|
17
|
+
|
18
|
+
# Register addresses.
|
19
|
+
CONFIG_ADDRESS = 0b01
|
20
|
+
CONVERSION_ADDRESS = 0b00
|
21
|
+
|
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
|
+
|
36
|
+
# 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.
|
41
|
+
enable_proxy
|
42
|
+
end
|
43
|
+
|
44
|
+
def _read(config)
|
45
|
+
# Write config register to start reading.
|
46
|
+
i2c_write [CONFIG_ADDRESS] + config
|
47
|
+
|
48
|
+
# Sleep the right amount of time for conversion, based on sample rate bits.
|
49
|
+
sleep WAIT_TIMES[config[1] >> 5]
|
50
|
+
|
51
|
+
# 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]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -2,55 +2,18 @@ module Denko
|
|
2
2
|
module AnalogIO
|
3
3
|
class ADS1118
|
4
4
|
include SPI::Peripheral
|
5
|
-
include
|
6
|
-
include Behaviors::Threaded
|
5
|
+
include ADS111X
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
0.0000625, # 0b010 2.048 V (default)
|
12
|
-
0.00003125, # 0b011 1.024 V
|
13
|
-
0.000015625, # 0b100 0.512 V
|
14
|
-
0.0000078125, # 0b101 0.256 V
|
15
|
-
0.0000078125, # 0b110 0.256 V
|
16
|
-
0.0000078125, # 0b111 0.256 V
|
17
|
-
]
|
18
|
-
PGA_RANGE = (0..7).to_a
|
19
|
-
|
20
|
-
# Sample rate bitmask maps to sample time in seconds.
|
21
|
-
SAMPLE_TIMES = [ # Bitmask
|
22
|
-
0.125, # 0b000
|
23
|
-
0.0625, # 0b001
|
24
|
-
0.03125, # 0b010
|
25
|
-
0.015625, # 0b011
|
26
|
-
0.0078125, # 0b100 (default)
|
27
|
-
0.004, # 0b101
|
28
|
-
0.002105263, # 0b110
|
29
|
-
0.00116279, # 0b111
|
30
|
-
]
|
31
|
-
SAMPLE_RATE_RANGE = (0..7).to_a
|
32
|
-
|
33
|
-
# Wait times need to be slightly longer than the actual sample times.
|
34
|
-
WAIT_TIMES = SAMPLE_TIMES.map { |time| time + 0.0005 }
|
35
|
-
|
36
|
-
# Mux bits map to array of form [positive input, negative input].
|
37
|
-
MUX_SETTINGS = {
|
38
|
-
0b000 => [0, 1],
|
39
|
-
0b001 => [0, 3],
|
40
|
-
0b010 => [1, 3],
|
41
|
-
0b011 => [2, 3],
|
42
|
-
0b100 => [0, nil],
|
43
|
-
0b101 => [1, nil],
|
44
|
-
0b110 => [2, nil],
|
45
|
-
0b111 => [3, nil],
|
46
|
-
}
|
47
|
-
|
48
|
-
# Config register values on startup.
|
49
|
-
CONFIG_DEFAULT = [0x05, 0x8B]
|
7
|
+
# Config register values on startup. MSB-first.
|
8
|
+
# Matches datasheet. Same as: [0x05, 0x8B] or [5, 139]
|
9
|
+
CONFIG_STARTUP = [0b00000101, 0b10001011]
|
50
10
|
|
51
11
|
# Base config bytes to mask settings into. Not same as default.
|
12
|
+
# MSB bits 0 and 7 set to enable single-shot mode.
|
13
|
+
# LSB bit 3 set to enable pullup resistor on MISO pin.
|
14
|
+
# LSB bit 1 set to flag valid data in the NOP bits.
|
52
15
|
BASE_MSB = 0b10000001
|
53
|
-
BASE_LSB =
|
16
|
+
BASE_LSB = 0b00001010
|
54
17
|
|
55
18
|
def after_initialize(options={})
|
56
19
|
super(options)
|
@@ -64,7 +27,7 @@ module Denko
|
|
64
27
|
@active_gain = nil
|
65
28
|
|
66
29
|
# Set register bytes to default and write to device.
|
67
|
-
@config_register =
|
30
|
+
@config_register = CONFIG_STARTUP.dup
|
68
31
|
spi_write(@config_register)
|
69
32
|
|
70
33
|
# Enable BoardProxy callbacks.
|
@@ -82,7 +45,7 @@ module Denko
|
|
82
45
|
spi_read(2)
|
83
46
|
end
|
84
47
|
|
85
|
-
# Pack the 2 bytes back into a string, then unpack as big-endian int16.
|
48
|
+
# Pack the 2 bytes back into a string, then unpack as big-endian signed int16.
|
86
49
|
def pre_callback_filter(message)
|
87
50
|
bytes = message.split(",").map { |b| b.to_i }
|
88
51
|
bytes.pack("C*").unpack("s>")[0]
|
@@ -104,79 +67,6 @@ module Denko
|
|
104
67
|
block.call(temperature) if block_given?
|
105
68
|
return temperature
|
106
69
|
end
|
107
|
-
|
108
|
-
#
|
109
|
-
# BoardProxy behavior so AnalogIO classes can use this as a Board.
|
110
|
-
#
|
111
|
-
include Behaviors::BoardProxy
|
112
|
-
|
113
|
-
# Mimic Board#update, but inside a callback, wrapped by #update.
|
114
|
-
def enable_proxy
|
115
|
-
self.add_callback(:board_proxy) do |value|
|
116
|
-
components.each do |component|
|
117
|
-
if @active_pin == component.pin
|
118
|
-
component.volts_per_bit = PGA_SETTINGS[@active_gain]
|
119
|
-
component.update(value)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def analog_read(pin, negative_pin=nil, gain=nil, sample_rate=nil)
|
126
|
-
# Wrap in mutex so calls and callbacks are atomic.
|
127
|
-
@mutex.synchronize do
|
128
|
-
# Default gain and sample rate.
|
129
|
-
gain ||= 0b010
|
130
|
-
sample_rate ||= 0b100
|
131
|
-
|
132
|
-
# Set these for callbacks.
|
133
|
-
@active_pin = pin
|
134
|
-
@active_gain = gain
|
135
|
-
|
136
|
-
# Set gain in upper config register.
|
137
|
-
raise ArgumentError "wrong gain: #{gain.inspect} given for ADS1118" unless PGA_RANGE.include?(gain)
|
138
|
-
@config_register[0] = BASE_MSB | (gain << 1)
|
139
|
-
|
140
|
-
# Set mux bits in upper config register.
|
141
|
-
mux_bits = pins_to_mux_bits(pin, negative_pin)
|
142
|
-
@config_register[0] = @config_register[0] | (mux_bits << 4)
|
143
|
-
|
144
|
-
# Set sample rate in lower config_register.
|
145
|
-
raise ArgumentError "wrong sample_rate: #{sample_rate.inspect} given for ADS1118" unless SAMPLE_RATE_RANGE.include?(gain)
|
146
|
-
@config_register[1] = BASE_LSB | (sample_rate << 5)
|
147
|
-
|
148
|
-
read(@config_register)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def pins_to_mux_bits(pin, negative_pin)
|
153
|
-
# Pin 1 is negative input. Only pin 0 can be read.
|
154
|
-
if negative_pin == 1
|
155
|
-
raise ArgumentError, "given pin: #{pin.inspect} cannot be used when pin 1 is negative input, only 0" unless pin == 0
|
156
|
-
return 0b000
|
157
|
-
end
|
158
|
-
|
159
|
-
# Pin 3 is negative input. Pins 0..2 can be read.
|
160
|
-
if negative_pin == 3
|
161
|
-
raise ArgumentError, "given pin: #{pin.inspect} cannot be used when pin 3 is negative input, only 0..2" unless [0,1,2].include? pin
|
162
|
-
return 0b001 + pin
|
163
|
-
end
|
164
|
-
|
165
|
-
# No negative input. Any pin from 0 to 3 can be read.
|
166
|
-
unless negative_pin
|
167
|
-
raise ArgumentError, "given pin: #{pin.inspect} is out of range 0..3" unless [0,1,2,3].include? pin
|
168
|
-
return (0b100 + pin)
|
169
|
-
end
|
170
|
-
|
171
|
-
raise ArgumentError, "only pins 1 and 3 can be used as negative input"
|
172
|
-
end
|
173
|
-
|
174
|
-
def analog_listen(pin, divider=nil)
|
175
|
-
raise StandardError, "ADS1118 does not implement #listen for subcomponents. Use #read or #poll instead"
|
176
|
-
end
|
177
|
-
|
178
|
-
def stop_listener(pin)
|
179
|
-
end
|
180
70
|
end
|
181
71
|
end
|
182
72
|
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Denko
|
2
|
+
module AnalogIO
|
3
|
+
module ADS111X
|
4
|
+
#
|
5
|
+
# Functionality shared among the ADS111X class of ADC converters.
|
6
|
+
#
|
7
|
+
include Behaviors::Reader
|
8
|
+
|
9
|
+
PGA_SETTINGS = [ # Bitmask Full scale voltage
|
10
|
+
0.0001875, # 0b000 6.144 V
|
11
|
+
0.000125, # 0b001 4.095 V
|
12
|
+
0.0000625, # 0b010 2.048 V (default)
|
13
|
+
0.00003125, # 0b011 1.024 V
|
14
|
+
0.000015625, # 0b100 0.512 V
|
15
|
+
0.0000078125, # 0b101 0.256 V
|
16
|
+
0.0000078125, # 0b110 0.256 V
|
17
|
+
0.0000078125, # 0b111 0.256 V
|
18
|
+
]
|
19
|
+
PGA_RANGE = (0..7).to_a
|
20
|
+
|
21
|
+
# Sample rate bitmask maps to sample time in seconds.
|
22
|
+
SAMPLE_TIMES = [ # Bitmask
|
23
|
+
0.125, # 0b000
|
24
|
+
0.0625, # 0b001
|
25
|
+
0.03125, # 0b010
|
26
|
+
0.015625, # 0b011
|
27
|
+
0.0078125, # 0b100 (default)
|
28
|
+
0.004, # 0b101
|
29
|
+
0.002105263, # 0b110
|
30
|
+
0.00116279, # 0b111
|
31
|
+
]
|
32
|
+
SAMPLE_RATE_RANGE = (0..7).to_a
|
33
|
+
|
34
|
+
# Wait times need to be slightly longer than the actual sample times.
|
35
|
+
WAIT_TIMES = SAMPLE_TIMES.map { |time| time + 0.0005 }
|
36
|
+
|
37
|
+
# Mux bits map to array of form [positive input, negative input].
|
38
|
+
MUX_SETTINGS = {
|
39
|
+
0b000 => [0, 1],
|
40
|
+
0b001 => [0, 3],
|
41
|
+
0b010 => [1, 3],
|
42
|
+
0b011 => [2, 3],
|
43
|
+
0b100 => [0, nil],
|
44
|
+
0b101 => [1, nil],
|
45
|
+
0b110 => [2, nil],
|
46
|
+
0b111 => [3, nil],
|
47
|
+
}
|
48
|
+
|
49
|
+
#
|
50
|
+
# BoardProxy behavior so AnalogIO classes can use this as a Board.
|
51
|
+
#
|
52
|
+
include Behaviors::BoardProxy
|
53
|
+
|
54
|
+
# Mimic Board#update, but inside a callback, wrapped by #update.
|
55
|
+
def enable_proxy
|
56
|
+
self.add_callback(:board_proxy) do |value|
|
57
|
+
components.each do |component|
|
58
|
+
if @active_pin == component.pin
|
59
|
+
component.volts_per_bit = PGA_SETTINGS[@active_gain]
|
60
|
+
component.update(value)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def analog_read(pin, negative_pin=nil, gain=nil, sample_rate=nil)
|
67
|
+
# 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
|
72
|
+
|
73
|
+
# Set these for callbacks.
|
74
|
+
@active_pin = pin
|
75
|
+
@active_gain = gain
|
76
|
+
|
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
|
+
|
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
|
+
|
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
|
+
|
89
|
+
read(@config_register)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def pins_to_mux_bits(pin, negative_pin)
|
94
|
+
# Pin 1 is negative input. Only pin 0 can be read.
|
95
|
+
if negative_pin == 1
|
96
|
+
raise ArgumentError, "given pin: #{pin.inspect} cannot be used when pin 1 is negative input, only 0" unless pin == 0
|
97
|
+
return 0b000
|
98
|
+
end
|
99
|
+
|
100
|
+
# Pin 3 is negative input. Pins 0..2 can be read.
|
101
|
+
if negative_pin == 3
|
102
|
+
raise ArgumentError, "given pin: #{pin.inspect} cannot be used when pin 3 is negative input, only 0..2" unless [0,1,2].include? pin
|
103
|
+
return 0b001 + pin
|
104
|
+
end
|
105
|
+
|
106
|
+
# No negative input. Any pin from 0 to 3 can be read.
|
107
|
+
unless negative_pin
|
108
|
+
raise ArgumentError, "given pin: #{pin.inspect} is out of range 0..3" unless [0,1,2,3].include? pin
|
109
|
+
return (0b100 + pin)
|
110
|
+
end
|
111
|
+
|
112
|
+
raise ArgumentError, "only pins 1 and 3 can be used as negative input"
|
113
|
+
end
|
114
|
+
|
115
|
+
def analog_listen(pin, divider=nil)
|
116
|
+
raise StandardError, "ADS111X does not implement #listen for subcomponents. Use #read or #poll instead"
|
117
|
+
end
|
118
|
+
|
119
|
+
def stop_listener(pin)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/denko/analog_io.rb
CHANGED
@@ -4,6 +4,8 @@ module Denko
|
|
4
4
|
autoload :Output, "#{__dir__}/analog_io/output"
|
5
5
|
autoload :Potentiometer, "#{__dir__}/analog_io/potentiometer"
|
6
6
|
autoload :Sensor, "#{__dir__}/analog_io/sensor"
|
7
|
+
autoload :ADS111X, "#{__dir__}/analog_io/ads111x"
|
8
|
+
autoload :ADS1115, "#{__dir__}/analog_io/ads1115"
|
7
9
|
autoload :ADS1118, "#{__dir__}/analog_io/ads1118"
|
8
10
|
end
|
9
11
|
end
|
@@ -4,7 +4,7 @@ module Denko
|
|
4
4
|
include Denko::Behaviors::BusPeripheral
|
5
5
|
|
6
6
|
def before_initialize(options={})
|
7
|
-
#
|
7
|
+
# Allow @address override in options, even if peripheral sets a default.
|
8
8
|
@address = options[:address] if options[:address]
|
9
9
|
|
10
10
|
raise ArgumentError, "missing address for #{self}. Try Bus#search first" unless @address
|
@@ -12,9 +12,12 @@ module Denko
|
|
12
12
|
def initialize_pins(options={})
|
13
13
|
super(options)
|
14
14
|
|
15
|
+
# Assume input direction, and look for pull mode in options.
|
15
16
|
initial_mode = :input
|
16
17
|
initial_mode = :input_pullup if options[:pullup]
|
17
18
|
initial_mode = :input_pulldown if options[:pulldown]
|
19
|
+
|
20
|
+
# If user was explicit about mode, just use that.
|
18
21
|
initial_mode = options[:mode] if options[:mode]
|
19
22
|
|
20
23
|
self.mode = initial_mode
|