This gem adds support for the Raspberry Pi GPIO interface to the denko
gem. Unlike the main gem, which requires an external microcontroller, this lets you to connect peripherals directly to the Pi.
Denko::PiBoard
is a drop-in replacement for Denko::Board
, which would represent a connected micrcontroller. Everything maps to the Pi's built-in GPIO pins instead, and Ruby runs on the Pi itself.
Note: This is not for the Raspberry Pi Pico (W) / RP2040. That microcontroller works with the main gem.
require 'denko/piboard'
# Board instance for the Pi.
board = Denko::PiBoard.new
# LED connected to GPIO4.
led = Denko::LED.new(board: board, pin: 4)
# Momentary button connected to GPIO17, using internal pullup.
button = Denko::DigitalIO::Button.new(board: board, pin: 17, pullup: true)
# Callback runs when button is down (0)
button.down do
puts "Button down"
led.on
end
# Callback runs when button is up (1)
button.up do
puts "Button up"
led.off
end
# Sleep main thread. Ctrl+C to quit.
sleep
Pi-specific examples are in this gem's examples folder, but examples from the main gem can be modified to work on the Pi:
- Replace setup code:
# Replace this:
require 'bundler/setup'
require 'denko'
# With this:
require 'denko/piboard'
# Replace this:
connection = Denko::Connection::Serial.new()
board = Denko::Board.new()
# With this:
board = Denko::PiBoard.new
- Update GPIO/pin numbers as needed. Raspberry Pi pinouts can be found here.
Note: Not all features from all examples are implemented yet, nor can be implemented. See Features below.
💚 Support verified ❓ Should work, but not verified
Chip | Status | Products | Notes |
---|---|---|---|
BCM2835 | 💚 | Pi 1, Pi Zero (W) | |
BCM2836/7 | ❓ | Pi 2 | |
BCM2837A0/B0 | 💚 | Pi 3 | |
BCM2711 | 💚 | Pi 4, Pi 400 | |
BCM2710A1 | ❓ | Pi Zero 2W |
-
Operating Systems:
- Raspberry Pi OS
- DietPi
Note: Both with kernel version 6.1 or higher.
-
Rubies:
- Ruby 2.7.4 (system Ruby on some Raspberry Pi OS installs)
- Ruby 3.2.2 (with and without YJIT)
- TruffleRuby 22.3.1 🤷♂️ (Not available on ARMv6 Pis: Zero W, Pi 1. Not recommended in general)
- pigpio
- libgpiod
- pigpio gem (Ruby bindings for pigpio)
- denko (peripheral implementations from main gem)
sudo apt install pigpio libgpiod-dev
gem install denko-piboard
This automatically installs dependency gems: denko
and pigpio
.
Note: sudo
may be needed before gem install
if using the Pi's system ruby.
The pigpio
package installs pigpiod
, which must run in the background (as root) for Ruby scripts to work. You should only need to start it once per boot. Automate it, or start manually with:
sudo pigpiod -s 10
Note: -s 10
sets tick interval to 10 microseconds, lowering CPU use. Valid values are: 1, 2, 4, 5, 8, 10 (5 default).
Depending on your Pi and OS, libgpiod
may limit GPIO access. If this happens, some scripts will fail. It is only used for digital read/write operations, so test with a simple script like blinking an LED. To get permission, add your user account to the gpio
group:
sudo usermod -a -G gpio $(whoami)
I2C, SPI and the hardware UART may be disabled on the Pi by default. Enable them with the built-in utility:
# On Raspberry Pi OS:
sudo raspi-config
# On DietPi:
sudo dietpi-config
Select "Interfacing Options" (Raspberry Pi OS), or "Advanced Options" (DietPi) and enable features as needed.
- Internal Pull Down/Up
- Digital Out
- Digital In
- Listeners are polled in a thread, similar to a microcontroller, but always at 1ms.
pigpio
supports even faster polling (1-10 microseconds), but events are not received in a consistent order across pins. Won't work for MultiPin components, but may implement for SinglePin.
- PWM Out
- Servo
- Tone Out
- Infrared Out
- DHT Class Temperature + Humidity Sensors
- I2C
- SPI
- Always uses SPI1 interface.
- Must enable before use. Instructions here.
- Does not bind CE pins according to GPIO pinout. Any pin can be used for chip enable.
- SPI modes 1 and 3 may not work.
- No listeners yet.
-
PWM Out / Servo Out
- Using either of these on any pin disables the Pi's PCM audio output globally.
-
Tone Out / Infrared Out
- Both of these use pigpio's wave interface, which only has a single instance. Calling either on any pin automatically stops any running instance that exists. Both features can co-exist in a script, but cannot happen at the same time.
- OneWire
- Hardware UART
- BitBang I2C
- BitBang SPI
- BitBang UART
- WS2812
- EEPROM (Use the filesystem for persistence instead)
- Analog IO (No analog pins on Raspberry Pi. Use ADC or DAC over I2C or SPI)