Skip to content

Commit

Permalink
Double check and update all I2C examples
Browse files Browse the repository at this point in the history
  • Loading branch information
vickash committed Oct 2, 2024
1 parent c75c4bb commit df5c172
Show file tree
Hide file tree
Showing 24 changed files with 124 additions and 156 deletions.
12 changes: 6 additions & 6 deletions benchmarks/i2c_ssd1306_refresh.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@

# Settings
# Must match speed in the sketch for UART briges. Doesn't matter for native USB.
BAUD_RATE = 115_200
FRAME_COUNT = 100
BAUD_RATE = 115_200
FRAME_COUNT = 100
# Request 1 Mhz I2C frequency. Wire libraries will fall back to fastest available speed.
I2C_FREQUENCY = 1_000_000
# Use :SDA0 for RP2040
I2C_PIN = :SDA
I2C_PIN = :SDA

# Setup
board = Denko::Board.new(Denko::Connection::Serial.new(baud: BAUD_RATE))
bus = Denko::I2C::Bus.new(board: board, pin: I2C_PIN)
oled = Denko::Display::SSD1306.new(bus: bus, rotate: true, i2c_frequency: I2C_FREQUENCY)
board = Denko::Board.new(Denko::Connection::Serial.new(baud: BAUD_RATE))
bus = Denko::I2C::Bus.new(board: board)
oled = Denko::Display::SSD1306.new(bus: bus, rotate: true, i2c_frequency: I2C_FREQUENCY)
canvas = oled.canvas

# Intro
Expand Down
26 changes: 12 additions & 14 deletions examples/advanced/m5_env.rb → examples/advanced/m5_env3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,38 @@
#
require 'bundler/setup'
require 'denko'
require_relative '../sensor/neat_tph_readings'

# How many degrees C the two temperature values can differ by before a warning.
TOLERANCE = 0.50

board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board, pin: :SDA)
sht = Denko::Sensor::SHT3X.new(bus: bus) # address: 0x44 default
qmp = Denko::Sensor::QMP6988.new(bus: bus) # address: 0x70 default
bus = Denko::I2C::Bus.new(board: board)
sht = Denko::Sensor::SHT3X.new(bus: bus) # address: 0x44 default
qmp = Denko::Sensor::QMP6988.new(bus: bus) # address: 0x70 default

# Configure for higher accuracy.
sht.repeatability = :high
sht.repeatability = :high
qmp.temperature_samples = 2
qmp.pressure_samples = 16
qmp.iir_coefficient = 2
qmp.pressure_samples = 16
qmp.iir_coefficient = 2

# Buggy on ESP32-S3 in forced mode. Data registers return zeroes on all but first read.
# Can't recreate on ESP32 V1, AVR or SAMD21. Put it in contiuous mode just in case.
qmp.continuous_mode

# Get the shared #print_tph_reading method to print readings neatly.
require_relative '../sensor/neat_tph_readings'

# How many degrees C the two temperature values can differ by before a warning.
TOLERANCE = 0.50

loop do
# Read both sensors.
qmp_reading = qmp.read
sht_reading = sht.read

# Retry immediately if either failed.
next unless (sht_reading && qmp_reading)

# Warn if large gap between temperature readings.
difference = (qmp_reading[:temperature] - sht_reading[:temperature]).abs
if (difference > TOLERANCE)
puts "WARNING: temperature values differed by more than #{TOLERANCE}\xC2\xB0C (#{difference.round(4)} \xC2\xB0C actual)"
puts "WARNING: temperature values differed by more than #{TOLERANCE}\xC2\xB0C (#{difference.round(4)} \xC2\xB0C)"
end

# Combine values from both sensors, averaging their temperatures.
Expand Down
21 changes: 8 additions & 13 deletions examples/advanced/ssd1306_time_temp_rh.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@
require 'denko'

board = Denko::Board.new(Denko::Connection::Serial.new)
i2c = Denko::I2C::Bus.new(board: board, pin: :SDA)
i2c = Denko::I2C::Bus.new(board: board)

# Get temperature and humidity every second.
htu21d = Denko::Sensor::HTU21D.new(bus: i2c)
htu21d.temperature.poll(1)
htu21d.humidity.poll(1)
htu21d.poll(2)

oled = Denko::Display::SSD1306.new(bus: i2c, rotate: true)
oled = Denko::Display::SSD1306.new(bus: i2c, rotate: true)
canvas = oled.canvas
last_refresh = Time.now

last_refresh = Time.now
loop do
elapsed = Time.now - last_refresh

Expand All @@ -29,15 +28,11 @@
canvas.text_cursor = [0,0]
canvas.print "Time: #{Time.now.strftime("%H:%M:%S.%L")}"

if htu21d[:temperature]
canvas.text_cursor = [0,8]
canvas.print "Temp: " + ('%.3f' % htu21d[:temperature]).rjust(7, " ") + " C"
end
canvas.text_cursor = [0,8]
canvas.print "Temp: " + ('%.3f' % htu21d.temperature).rjust(7, " ") + " C"

if htu21d[:humidity]
canvas.text_cursor = [0,16]
canvas.print "Humidity: " + ('%.3f' % htu21d[:humidity]).rjust(7, " ") + " %"
end
canvas.text_cursor = [0,16]
canvas.print "Humidity: " + ('%.3f' % htu21d.humidity).rjust(7, " ") + " %"

# Only refresh the area in use.
oled.draw(0, 127, 0, 24)
Expand Down
6 changes: 3 additions & 3 deletions examples/analog_io/ads1100.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def print_reading(name, raw, voltage)
end

board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
bus = Denko::I2C::Bus.new(board: board)

# Unlike the ADS1115/1118, full-scale voltage depends on Vdd. Give during setup.
# This works for my M5Stack ADC unit (0-12V) when checked against a multimeter.
Expand All @@ -31,12 +31,12 @@ def print_reading(name, raw, voltage)
# Gain: 1 (default), 2, 4, 8
# Sample Rate: 8 (default), 16, 32, 128
#
ads.gain = 1
ads.sample_rate = 8
ads.gain = 1

# Configure smoothing.
ads.smoothing = true
ads.smoothing_size = 4
ads.smoothing_size = 8

# Poll and print indefinitely.
ads.poll(0.25) do |reading|
Expand Down
4 changes: 2 additions & 2 deletions examples/analog_io/ads1115.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
require 'denko'

board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
ads = Denko::AnalogIO::ADS1115.new(bus: bus)
bus = Denko::I2C::Bus.new(board: board)
ads = Denko::AnalogIO::ADS1115.new(bus: bus)

# Helper method so readings look nice.
def print_reading(name, raw, voltage)
Expand Down
30 changes: 5 additions & 25 deletions examples/i2c/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,17 @@
require 'bundler/setup'
require 'denko'

# Method to let the user set I2C pins.
def enter_pins
puts "Please manually specify I2C pins..."
print "I2C SDA pin: "; sda = gets
print "I2C SCL pin: "; scl = gets
puts
[sda.to_i, scl.to_i]
end

board = Denko::Board.new(Denko::Connection::Serial.new)

# If no board map, ask user to set pins manually.
unless board.map
puts "Error: Pin map not available for this board"
sda, scl = enter_pins

# Else get defaults from map.
else
# If board has a map, show the pins to the user.
if board.map
puts "Detected board: #{board.name}"

sda = board.map[:SDA] || board.map[:SDA0]
scl = board.map[:SCL] || board.map[:SCL0]

# If not in map, ask user to set manually.
unless sda && scl
puts "Error: I2C pins not found in this board's pin map"
sda, scl = enter_pins
end
puts "Using default I2C interface on pins #{sda} (SDA) and #{scl} (SCL)"
else
puts "Pin map not available for this board. Using default interface, but SCL and SDA pins unknown"
end

puts "Using I2C interface on pins #{sda} (SDA) and #{scl} (SCL)"
puts

# Board's hardware I2C interface on predetermined pins.
Expand Down
38 changes: 18 additions & 20 deletions examples/rtc/ds3231.rb
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
#
# Example using a D3231 real-time-clock over I2C. Sets the time and reads it
# back every 5 seconds.
# D3231 real-time-clock over I2C. Set time and read back every 5 seconds.
#
require 'bundler/setup'
require 'denko'

board = Denko::Board.new(Denko::Connection::Serial.new)
# Board's hardware I2C interface on predetermined pins.
bus = Denko::I2C::Bus.new(board: board) # address: 0x68 default
i2c = Denko::I2C::Bus.new(board: board) # address: 0x68 default

# Tell the bus to search for devices.
bus.search
i2c.search

# Show the found devices.
puts "No I2C devices connected!" if bus.found_devices.empty?
bus.found_devices.each do |address|
puts "I2C device connected with address: 0x#{address.to_s(16)}"
if i2c.found_devices.empty?
puts "No I2C devices connected!"
return
end

# 0x68 or 140 is the I2C address for most real time clocks.
unless (bus.found_devices.include? 0x68)
puts "No real time clock found!" unless bus.found_devices.empty?
else
puts; puts "Using real time clock at address 0x68"; puts
rtc = Denko::RTC::DS3231.new(bus: bus, address: 0x68)
rtc.time = Time.now
# 0x68 is the I2C address for most real time clocks.
unless (i2c.found_devices.include? 0x68)
puts "DS3231 real time clock not found!"
return
end

puts "Using DS3231 RTC at address 0x68"; puts
rtc = Denko::RTC::DS3231.new(bus: i2c, address: 0x68)
rtc.time = Time.now

5.times do
puts rtc.time
sleep 5
end
5.times do
puts rtc.time
sleep 5
end
15 changes: 4 additions & 11 deletions examples/sensor/aht10.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
#
# Example using AHT10 sensor over I2C, for temperature and humidity.
# AHT10 sensor over I2C, for temperature and humidity.
#
require 'bundler/setup'
require 'denko'
require_relative 'neat_tph_readings'

board = Denko::Board.new(Denko::Connection::Serial.new)

# Board's hardware I2C interface on predetermined pins.
bus = Denko::I2C::Bus.new(board: board)
# Bit-banged I2C on any pins.
# bus = Denko::I2C::BitBang.new(board: board, pins: {scl: 8, sda: 9})

board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
sensor = Denko::Sensor::AHT10.new(bus: bus) # address: 0x38 default

# Get the shared #print_tph_reading method to print readings neatly.
require_relative 'neat_tph_readings'

# Poll it and print readings.
sensor.poll(5) do |reading|
print_tph_reading(reading)
Expand Down
10 changes: 4 additions & 6 deletions examples/sensor/aht20.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
#
# Example using AHT21 sensor over I2C, for temperature and humidity.
# AHT21 sensor over I2C, for temperature and humidity.
#
require 'bundler/setup'
require 'denko'
require_relative 'neat_tph_readings'

board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
sensor = Denko::Sensor::AHT20.new(bus: bus) # address: 0x38 default

# Get the shared #print_tph_reading method to print readings neatly.
require_relative 'neat_tph_readings'

# Poll it and print readings.
sensor.poll(5) do |reading|
print_tph_reading(reading)
Expand Down
6 changes: 3 additions & 3 deletions examples/sensor/bme280.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#
# Example using a BME280 sensor over I2C, for temperature, pressure and humidity.
# BME280 sensor over I2C, for temperature, pressure and humidity.
#
require 'bundler/setup'
require 'denko'
require_relative 'neat_tph_readings'

board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
bus = Denko::I2C::Bus.new(board: board)

sensor = Denko::Sensor::BME280.new(bus: bus) # address: 0x76 default
# Use A BMP280 with no humidity instead.
Expand All @@ -28,7 +29,6 @@
# print sensor.config_register_bits

# Get the shared #print_tph_reading method to print readings neatly.
require_relative 'neat_tph_readings'

# Poll it and print readings.
sensor.poll(5) do |reading|
Expand Down
10 changes: 4 additions & 6 deletions examples/sensor/bmp180.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#
# Example using a BMP180 sensor over I2C, for temperature and pressure.
# BMP180 sensor over I2C, for temperature and pressure.
#
require 'bundler/setup'
require 'denko'
require_relative 'neat_tph_readings'

board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
sensor = Denko::Sensor::BMP180.new(bus: bus) # address: 0x77 default

# Enable oversampling for the pressure sensor only (1,2,4, 8).
Expand All @@ -17,9 +18,6 @@
puts "Pressure unit helpers: #{sensor.pressure} Pa | #{sensor.pressure_atm.round(6)} atm | #{sensor.pressure_bar.round(6)} bar"
puts

# Get the shared #print_tph_reading method to print readings neatly.
require_relative 'neat_tph_readings'

# Poll it and print readings.
sensor.poll(5) do |reading|
print_tph_reading(reading)
Expand Down
10 changes: 4 additions & 6 deletions examples/sensor/htu21d.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#
# Example using HTU21D sensor over I2C, for temperature and humidity.
# HTU21D sensor over I2C, for temperature and humidity.
#
require 'bundler/setup'
require 'denko'
require_relative 'neat_tph_readings'

board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
board = Denko::Board.new(Denko::Connection::Serial.new)
bus = Denko::I2C::Bus.new(board: board)
htu21d = Denko::Sensor::HTU21D.new(bus: bus) # address: 0x40 default

# Get and set heater state.
Expand Down Expand Up @@ -34,9 +35,6 @@
puts "Temperature unit helpers: #{htu21d.temperature} \xC2\xB0C | #{htu21d.temperature_f} \xC2\xB0F | #{htu21d.temperature_k} K"
puts

# Get the shared #print_tph_reading method to print readings neatly.
require_relative 'neat_tph_readings'

# Poll it and print readings.
htu21d.poll(5) do |reading|
print_tph_reading(reading)
Expand Down
Loading

0 comments on commit df5c172

Please sign in to comment.