denko 0.13.0 → 0.13.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|