0.0
The project is in a healthy, maintained state
Use Linux single-board-computer GPIO, I2C, SPI and PWM in Ruby
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

~> 0.1
~> 0.14
 Project Readme

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

  • Internal Pull-Up/Down
  • Open Drain/Source
  • Digital Read/Write
  • Digital Listen (Alerts)
    • Interrupt driven, unlike denko microcontroller implementation 1ms polling
    • Built in software debounce (1us by default)
    • Alerts are read from a FIFO queue up to 65,536. Oldest alerts are lost first.
  • Analog Read (ADC)
  • Analog Write (DAC)
  • Software PWM Out (any pin)
  • Hardware PWM Out (specific pins per board)
  • Tone Out (via Software PWM or Hardware PWM)
  • Servo (via Hardware PWM)
  • Infrared Out (via Hardware PWM)
  • Hardware I2C
    • Multiple interfaces
  • Hardware SPI
    • Multiple interfaces
    • WS2812 addressable LED via SPI MOSI
    • SPI Listeners from denko
  • UART
  • Ultrasonic Input (for HC-SR04 and similar)
  • Pulse Sequence Input (for DHT enviro sensors and similar)
  • Bit-Bang I2C
  • Bit-Bang SPI
  • Bit-Bang 1-Wire

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.

💚 Known working ❤️ Awaiting testing ❓ Might work. No hardware

Chip Status Products Notes
Allwinner H618 💚 Orange Pi Zero 2W DietPi
Rockchip RK3566 💚 Radxa Zero 3W/E, Radxa Rock 3C Armbian
BCM2835 💚 Raspberry Pi 1, Raspberry Pi Zero (W) Raspberry Pi OS
BCM2836/7 Raspberry Pi 2
BCM2837A0/B0 💚 Raspberry Pi 3 Raspberry Pi OS
BCM2711 💚 Raspberry Pi 4, Raspberry Pi 400 Raspberry Pi OS
BCM2710A1 💚 Raspberry Pi Zero 2W Raspberry Pi OS
BCM2712 Raspberry Pi 5

Software

  • Operating Systems:

    • DietPi (Bookworm)
    • Armbian (Bookworm)
    • Raspberry Pi OS (Bookworm)
  • Rubies:

    • Ruby 3.3.5 +YJIT

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

  • For DietPi OS specifically
  • 2 PWMs on GPIO 226 and 227 (not matching the docs) are enabled without any setup.
  • Save the default map as ~/.denko_piboard_map.yml on your Zero2W.
  • Add/edit the lines below in /boot/dietpiEnv.txt, and reboot.
# /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

  • For Armbian OS specifically. Newer and performs better than latest Radxa OS or DietPi available.
  • Unfortunately, Armbian does not package all device tree overlays for the RK3566. I built binaries for this default config, on kernel 6.1.75-vendor-rk35xx, and made them available here. To use, download the .dtbo files into /boot/dtb/rockchip/overlay on your Zero3. Make sure your kernel version matches.

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
  • Save the default map as ~/.denko_piboard_map.yml on your Zero3.
  • Add/edit the lines below in /boot/armbianEnv.txt, and reboot.
# /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

  • For Raspberry Pi OS specifically
  • Save the default map as ~/.denko_piboard_map.yml on your Raspberry Pi.
  • Add the lines below to /boot/config.txt, and reboot.
# 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:

  • Create any necessary Linux groups
  • Add your user to the relevant groups
  • Change ownership and permissions for devices in the map, so you can read/write them

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.