※和文はページ下部にあります
Previous sections:
- Setup + LED: https://tinyurl.com/picoruby-2025
In this section, we'll learn about analog-to-digital conversion (ADC) and explore how to read analog sensors. We'll use a microphone to detect sound levels and also explore the RP2350's built-in temperature sensor.
But first, let's learn how to write longer programs and run them as scripts!
So far we've been using IRB (Interactive Ruby) for quick experimentation. For longer programs, it's better to write Ruby scripts on your laptop:
- Experiment in IRB - Test your hardware connections and basic functionality
- Write a script - Use your favorite text editor on your laptop to write a
.rbfile - Upload to R2P2 - Drag and drop the script file into the "home" directory of the R2P2 drive
- Execute - Run the script from R2P2 shell with
$> ./[script name].rb
class LED < GPIO
def initialize(pin)
super(pin, GPIO::OUT)
end
def on
write 1
end
def off
write 0
end
def toggle
high? ? off : on
end
end
led = LED.new(16)
10.times do
led.toggle
sleep 0.5
endDrag and drop led.rb into R2P2's home directory.
Run ls in the R2P2 shell:
$> ls
You should see the file listed in the shell prompt.
Then run the script:
$> ./led.rb
ADC (Analog-to-Digital Converter) converts continuous analog signals (like sound levels, temperature, or light intensity) into digital values that a computer can understand.
Think of it like translating a smooth curve into a series of discrete steps that represent the original signal.
The RP2350/RP2040 has a 12-bit ADC, which means:
- Range: 0 to 4095 (2^12 - 1)
- 0 represents 0 volts
- 4095 represents maximum voltage (3.3V for RP2350/RP2040)
We'll use an analog microphone module to detect sound levels.
Components needed:
- 1x Analog microphone module (https://akizukidenshi.com/catalog/g/g105757/)
- 1x LED (from previous section)
- 1x 1kΩ resistor
- Jumper wires
Wiring:
RP2[3V3] --- Microphone[VCC]
RP2[GND] --- Microphone[GND]
RP2[GP26] --- Microphone[OUT(AUD)]
RP2[GP16] --- Resistor(1kΩ) --- LED[Anode(long leg)]
RP2[GND] --- LED[Cathode(short leg)]
See the diagrams in the previous section for breadboard setup.
Pin Reference:
- GP26 is ADC0
- 3V3 (pin 36) is the 3.3V power output
Connection on the breadboard can be seen in the previous section.
Let's start with IRB to test our circuit:
irb> require 'adc'
irb> mic = ADC.new 26
irb> mic.read_raw
=> 2048 # Should be around 2048 (middle value) in silence
irb> mic.read
=> 1.65 # Voltage reading (around 1.65V in silence)Try to check the values while clapping or speaking near the microphone.
Now let's create our first sound-activated circuit. Save this as sound_led.rb:
require 'adc'
led = GPIO.new(16, GPIO::OUT)
mic = ADC.new(26)
puts "Sound-activated LED started!"
puts "Clap or make noise to turn on the LED"
while true
sound_level = mic.read_raw - 2048 # -2048..2047
if 1000 < sound_level.abs # Adjust threshold as needed
led.write 1
puts "Sound detected: #{sound_level}"
else
led.write 0
end
sleep 0.1
endIn R2P2 shell, Ctrl+C to stop the program.
The RP2350 has a built-in temperature sensor that we can access through ADC:
irb> temp_adc = ADC.new :temperature
irb> temp_adc.read
=> 0.721 # This is the raw voltage from temperature sensorSave this as temperature.rb and try running it:
require 'adc'
def voltage_to_celsius(voltage)
reference_temp = 27.0
reference_voltage = 0.706
temp_coefficient = -0.001721
temp_difference = (voltage - reference_voltage) / temp_coefficient
reference_temp + temp_difference
end
temp_adc = ADC.new(:temperature)
while true
voltage = temp_adc.read
temperature = voltage_to_celsius(voltage)
puts "Temperature: #{temperature.round(1)}°C"
sleep 2
endUnfortunately, the built-in sensor of the Raspi Pico is not very accurate. Please use this material as a reference when using discrete sensors.
Let's create a more sophisticated sound monitoring program. Save as sound_monitor.rb:
require 'adc'
led = GPIO.new(16, GPIO::OUT)
mic = ADC.new(26)
temp_adc = ADC.new(:temperature)
def voltage_to_celsius(voltage)
reference_temp = 27.0
reference_voltage = 0.706
temp_coefficient = -0.001721
temp_difference = (voltage - reference_voltage) / temp_coefficient
reference_temp + temp_difference
end
puts "=== Sound & Temperature Monitor ==="
puts "Press Ctrl+C to stop"
loop do
# Read sensors
sound = mic.read_raw - 2048
temp_voltage = temp_adc.read
temperature = voltage_to_celsius(temp_voltage)
# Sound detection with multiple thresholds
if 1500 < sound.abs
led.write 1
puts "LOUD! Sound: #{sound}, Temp: #{temperature.round(1)}°C"
elsif 500 < sound
led.write(led.high? ? 0 : 1) # Blink for moderate sound
puts "Sound: #{sound}, Temp: #{temperature.round(1)}°C"
else
led.write 0
puts "Quiet: #{sound}, Temp: #{temperature.round(1)}°C"
end
sleep 0.5
endFor those who want to explore further:
-
Calibration: Create a calibration routine that measures the baseline noise level for 5 seconds and automatically sets the threshold.
-
Sound Patterns: Create different LED patterns for different sound levels:
- Quiet: LED off
- Moderate: Slow blink
- Loud: Fast blink
- Very loud: Solid on
-
Data Logging: Modify the sound monitor to keep track of:
- Maximum sound level detected
- Average sound level over time
- Number of sound events above threshold
-
Multi-Sensor Dashboard: Combine multiple ADC readings:
# Read multiple sensors and display formatted output def init @mic = ADC.new(26) @temp = ADC.new(:temperature) end def display_sensor_dashboard puts "┌─────────────────────────┐" puts "│ Sensor Dashboard │" puts "├─────────────────────────┤" puts "│ Sound Level: #{@mic.read_raw.to_s.rjust(4)} │" puts "│ Temperature: #{voltage_to_celsius(@temp.read).to_i}°C │" puts "└─────────────────────────┘" end
-
Sound Trigger Recording: Create a system that detects when sound exceeds a threshold and records the maximum value reached during that "event":
# Pseudo-code structure: # - Monitor continuously # - When sound > threshold, start "recording" # - Track peak value during the event # - When sound drops below threshold for 1 second, end recording # - Display event summary (duration, peak value)