※和文はページ下部にあります
Previous sections:
- Setup + LED: https://tinyurl.com/picoruby-2025
- Microphone: https://tinyurl.com/picoruby-mic
- Buzzer: https://tinyurl.com/picoruby-buzzer
So far we've learned the fundamental peripherals: GPIO, ADC, and PWM. These are the building blocks of all microcontroller programming. Now let's explore how PicoRuby's gem system makes working with complex sensors much easier!
Before diving into gems, let's review what we've learned:
-
GPIO (General Purpose Input/Output): Digital on/off control
- Examples: LED control, button reading
GPIO.new(pin, GPIO::OUT)orGPIO.new(pin, GPIO::IN)
-
ADC (Analog-to-Digital Converter): Reading analog signals
- Examples: Microphone, temperature sensor, light sensors
ADC.new(pin)gives 12-bit values (0-4095)
-
PWM (Pulse Width Modulation): Simulating analog output
- Examples: Buzzer tones, LED brightness, motor speed control
PWM.new(pin)withfrequency()andduty()methods
-
[new!] I2C (Inter-Integrated Circuit): Digital communication protocol
- Examples: OLED displays, advanced sensors, EEPROMs
- Two-wire communication: SDA (data) and SCL (clock)
- I2C is slightly complex to try in IRB (but doable)
PicoRuby gems wrap these basic peripherals to provide easy-to-use interfaces for specific hardware modules. Instead of manually handling GPIO timing or I2C protocols, gems give you simple, intuitive methods.
Let's explore two powerful gems:
The HC-SR04 uses GPIO pins with precise timing to measure distance using ultrasonic sound waves.
Components needed:
- 1x HC-SR04 ultrasonic sensor
- Jumper wires
Wiring:
RP2[3V3] --- HC-SR04[VCC]
RP2[GND] --- HC-SR04[GND]
RP2[GP0] --- HC-SR04[Echo]
RP2[GP1] --- HC-SR04[Trig]
See the wiring diagram in the previous section.
irb> require 'hcsr04'
irb> hcsr04 = HCSR04.new(echo: 0, trig: 1)
irb> hcsr04.distance_cm
=> 23.4The gem handles all the complex timing internally:
- Sends a short trigger pulse to the Trig pin
- Measures the duration of the Echo pin's high state
- Calculates distance using:
distance = (duration × sound_speed) / 2
You can find the implementation here: https://github.com/picoruby/picoruby/blob/master/mrbgems/picoruby-hcsr04/mrblib/hcsr04.rb
Save this as distance_monitor.rb:
require 'pwm'
require 'hcsr04'
hcsr04 = HCSR04.new(echo: 0, trig: 1)
buzzer = PWM.new(11)
buzzer.duty 50
buzzer.frequency 0
puts "Distance Monitor Started!"
puts "Buzzer will sound when an object is detected within range."
while true
begin
distance = hcsr04.distance_cm
puts "Distance: #{distance} cm"
# closer = faster blink
buzzer.frequency((5000 - (distance * 10)) / 10)
rescue
puts "Distance: Out of range"
buzzer.frequency 0
sleep 1
end
sleep 0.5
endThe SSD1306 is a popular OLED display that uses I2C communication. The gem handles all the complex I2C protocol details.
Components needed:
- 1x SSD1306 OLED Display (128x64 pixels)
- Jumper wires
Wiring:
RP2[3V3] --- OLED[VCC]
RP2[GND] --- OLED[GND]
RP2[GP8] --- OLED[SDA]
RP2[GP9] --- OLED[SCL]
irb> require 'ssd1306'
irb> width = 128
irb> height = 64
irb> i2c = I2C.new(unit: :RP2040_I2C0, sda_pin: 8, scl_pin: 9)
irb> display = SSD1306.new(i2c: i2c, w: width, h: height)# Clear the display
irb> display.clear
# Draw lines (Display does not auto-update at this point)
irb> display.draw_line(0, 0, width-1, height-1, 1)
irb> display.draw_line(width-1, 0, 0, height-1, 1)
# Update display to show changes
irb> display.update_display# Clear and draw rectangles
irb> display.clear
irb> display.draw_rect(10, 10, 30, 20, 1, false) # Outline rectangle
irb> display.draw_rect(50, 20, 25, 15, 1, true) # Filled rectangle
irb> display.update_display# Clear and show text
irb> display.clear
irb> display.draw_text(:terminus_6x12, 0, 24, "Hello PicoRuby!")
irb> display.draw_text(:terminus_6x12, 0, 40, "Workshop 2025")
irb> display.update_displaySave this as oled_demo.rb:
require 'ssd1306'
width = 128
height = 64
i2c = I2C.new(unit: :RP2040_I2C0, sda_pin: 8, scl_pin: 9, frequency: 400_000)
display = SSD1306.new(i2c: i2c, w: width, h: height)
puts "OLED Demo Started!"
# Demo 1: Text welcome
display.clear
display.draw_text(:terminus_6x12, 0, 0, "EuRuKo 2025")
display.draw_text(:terminus_16x32, 0, 16, "PicoRuby")
display.draw_text(:terminus_8x16, 0, 48, "Workshop Demo")
display.update_display
sleep 3
# Demo 2: Geometric patterns
display.clear
display.draw_line(0, 0, width-1, height-1, 1)
display.draw_line(width-1, 0, 0, height-1, 1)
display.draw_line(width/2, 0, width/2, height-1, 1)
display.draw_line(0, height/2, width-1, height/2, 1)
display.update_display
sleep 3
# Demo 3: Rectangles
display.clear
display.draw_rect(10, 10, 30, 20, 1, false)
display.draw_rect(50, 20, 25, 15, 1, true)
display.draw_rect(85, 35, 35, 25, 1, false)
display.update_display
sleep 3
# Demo 4: Animation - moving dot
display.clear
display.draw_text(:terminus_12x24, 0, 0, "Moving Dot!")
x = 0
y = 16
10.times do
display.draw_rect(x, y, 4, 4, 1, true)
display.update_display_optimized # only update changed pages
display.erase(x, y, 4, 4)
sleep 0.3
x += 12
y += 4
end
puts "Demo complete!"You can find the full API list here: https://github.com/picoruby/picoruby/blob/master/mrbgems/picoruby-ssd1306/sig/ssd1306.rbs
Challenge yourself with these advanced projects:
-
OLED Sound Visualizer: Display microphone levels on the OLED in real-time:
# Show sound level as a bar graph # Include peak hold indicator
-
Interactive Distance Game: Create a game using the OLED display:
- Display a target distance (e.g., "Get 25cm away!")
- Show current distance and "warmer/colder" feedback
- Score based on how quickly user achieves target
- Multiple rounds with different targets
-
OLED Animation Engine: Create a simple animation system:
# Bouncing ball physics # Multiple moving objects # Collision detection with distance sensor # Sound effects synchronized with animations