Home

Awesome

denko-piboard

Use Linux single-board-computer GPIO in Ruby.

# Turn LED on when a button is held down, off when released.
require 'denko/piboard'

board  = Denko::PiBoard.new
led    = Denko::LED.new(board: board, pin: 260)
button = Denko::DigitalIO::Button.new(board: board, pin: 259, mode: :input_pullup)

# Callback fires when button is down (0)
button.down do
  puts "Button down"
  led.on
end

# Callback fires when button is up (1)
button.up do
  puts "Button up"
  led.off
end

# Sleep main thread. Ctrl+C to quit.
sleep

Linux GPIO Features

Support

Hardware

In theory, this should work on any SBC, running Linux, with drivers for the relevant GPIO/I2C/SPI/PWM subsystems available on the system-on-chip (SoC). This is just a list of chips and products confirmed working.

:green_heart: Known working :heart: Awaiting testing :question: Might work. No hardware

ChipStatusProductsNotes
Allwinner H618:green_heart:Orange Pi Zero 2WDietPi
Rockchip RK3566:green_heart:Radxa Zero 3W/E, Radxa Rock 3CArmbian
BCM2835:green_heart:Raspberry Pi 1, Raspberry Pi Zero (W)Raspberry Pi OS
BCM2836/7:question:Raspberry Pi 2
BCM2837A0/B0:green_heart:Raspberry Pi 3Raspberry Pi OS
BCM2711:green_heart:Raspberry Pi 4, Raspberry Pi 400Raspberry Pi OS
BCM2710A1:green_heart:Raspberry Pi Zero 2WRaspberry Pi OS
BCM2712:question:Raspberry Pi 5

Software

Install

Install the lg C library

# Requirements to install lgpio C
sudo apt install swig python3-dev python3-setuptools gcc make

# Temporary fork of: wget https://github.com/joan2937/lg
wget https://github.com/vickash/lg/archive/refs/heads/master.zip

# Install lgpio C
unzip master.zip
cd lg-master
make
sudo make install

Install the denko-piboard gem

# Latest Ruby + YJIT from rbenv works best, but Ruby 3 from apt works too.
# Install system Ruby anyway to automate permissions startup script.
sudo apt install ruby ruby-dev

sudo gem install denko-piboard

Note: sudo may be needed before gem install if using the system Ruby.

Enable Hardware

Note: These are simplified instructions for a few SBCs, to get you going quickly. denko-piboard uses standard Linux interfaces, so should work for many. See the board maps readme.

Orange Pi Zero 2W

# /dev/i2c-3 (I2C3) @ 100 kHz
# /dev/spidev1.0 (SPI1) with first chip select (CS0) enabled
overlay_prefix=sun50i-h616
overlays=i2c1-pi spidev1_0

Radxa Zero3W/E

If you rather build the overlays yourself, that repo contains the script too. On the Zero3:

sudo apt install device-tree-compiler
ruby rk3568_denko_overlay_install.rb
# /dev/i2c-3 (I2C3) @ 100 kHz
# /dev/spidev3.0 (SPI3) with first chip select (CS0) enabled
# 2 PWMs on GPIO 105 and 106
overlay_prefix=rk3568
overlays=i2c3-m0 spi3-m1-cs0-spidev pwm8-m0 pwm9-m0

Note: The Radxa docs are missing I2C3_SDA_M0 and I2C3_SCL_M0 in the function columns for GPIOs 32 and 33 respectively. This is an error. I2C3 works on these pins.

Raspberry Pi 4 and Lower

# 2 PWMS on GPIO 12 and 13
dtoverlay=pwm-2chan,pin=12,func=4,pin2=13,func2=4
# /dev/i2c-1 (I2C1) @ 400 kHz
dtparam=i2c_arm=on
dtparam=i2c_arm_baudrate=400000
# /dev/spidev0.0 (SPI0) with first chip select (CS0) enabled
dtoverlay=spi0-1cs

Get Permissions

By default, only the Linux root user can use GPIO / I2C / SPI / PWM. If you have a default board map at ~/.denko_piboard_map.yml, save this script to your SBC, then run it:

ruby set_permissions.rb

It will load load the default board map, then:

Note: sudo is required.

Note: If you automate this script to run at boot (recommended), it will run as root. Set the USERNAME constant to your Linux user's name as a String literal. This ensures the map loads from your home, and changes are applied to your user, not root.

Modifying Examples From Main Gem

Some examples are included in this gem, but the main denko gem is more comprehensive. Those are written for connected microcontrollers, Denko::Board, but can be modified for Denko::PiBoard:

  1. Replace setup code:
  # Replace this:
  require 'bundler/setup'
  require 'denko'
  # With this:
  require 'denko/piboard'

  # Replace this:
  board = Denko::Board.new(Denko::Connection::Serial.new)
  # With this:
  board = Denko::PiBoard.new
  1. Change pin numbers and I2C/SPI device indices as needed.