logo

# Godot-GPIO A [Godot](https://godotengine.org/)/GDScript addon to access GPIO on linux hosts (eg Raspberry Pi). [!["Buy Me A Coffee"](https://buymeacoffee.com/assets/img/custom_images/yellow_img.png)](https://www.buymeacoffee.com/valbisson) # Setup `Godot-GPIO` (`ggpio`) depends on [lg](https://abyz.me.uk/lg/index.html): 1. [install](#requirements) `rgpiod` on the computer you want to control (eg Raspberri Pi). 2. run it: `sudo rgpiod` (or start it as a deamon: `sudo nohup rgpiod` 3. on your host (where the `ggpio` will be running, possibly the same host, depending on you situation) [install](#requirements) `rgs` # Requirements - on Raspberri Pi: `sudo apt-get install rgpio-tools` - others: download & compile `rgs` using [`lg`'s install info](https://abyz.me.uk/lg/download.html): ```bash wget http://abyz.me.uk/lg/lg.zip unzip lg.zip cd lg make sudo make install ``` # Introduction Here's a quick rundown of the main classes: - `ggpio`: `class_name`'d to make it globally available, it can be considered a namespace for the project, so that no other gd script needs to be imported in most cases. - `ggpio.SBC`: (Single Board Computer). That's the host we'll be interacting with. - `ggpio.Chip`: refers to a gpiochip under [the kernel's GPIO driver interface](https://docs.kernel.org/driver-api/gpio/driver.html). Most of the time we're working with gpio `0`. - `ggpio.GPIO`: this is a single pin on a board.
Here's how GPIOs on a Pi are numbered (source):

RPi pinout

Note that some pins in the diagram above are not GPIO, and as such, won't be visible in the lib. Reversely, depending on the SBC, some devices may appears as GPIO while not being mentioned in the diagram above.
- `ggpio.devices.*`: those are high level facilities to help development. See [#facilities](#facilities) for details. - `ggpio.lg`: this is where the low level `lg`/`rpio` interface is implemented. The flow is to create an `LGCommand` and `run` it on an `SBC`. This is for more advanced use. # Usage In a nutshell: ```gdscript # turn on LED on gpio 27 using the gpio itself var sbc_hostname := 'rpi.local' var sbc := ggpio.SBC.new(sbc_hostname) gpio27 = sbc.open_chip().open_gpio( 27, ggpio.Mode.OUTPUT, ggpio.LineFlag.PULL_DOWN, ggpio.Level.LOW ) gpio27.write(ggpio.Level.HIGH) assert(gpio27.read() == ggpio.Level.HIGH) ``` For more, check out scenes in the [samples](./samples) directory. Couple points: - Each scene can be played independently (`F6`) - the main scene is *GPIO explorer*, kind of a live version of the pinout above, but dedicated to GPIO:

GPIO Explorer

Note: - by default, `ggpio` connects to `localhost`, ie it access GPIOs of the board it runs on. - set `LG_ENVADDR` & `LG_ENVPORT` to work remotely and access GPIOS of the board at those address & port. # Facilities ## Devices GGPIO implements a few abstractions similar to [gpiozero](https://gpiozero.readthedocs.io/en/latest/api_output.html#base-classes) (this is very much a work-in-progress). Legend: - lighter classes are abstract - darker ones are concrete / instanciable - classes marked with a ✔ have been implemented - classes marked with a ✖ are not written yet (I may lack the hardware to test them, contributions are welcome!) ```mermaid flowchart RL Device[Device ✖] class Device abstract GPIODevice[GPIODevice ✖] --> Device class GPIODevice abstract RGBLED[RGBLED ✖] --> Device CompositeDevice[CompositeDevice ✖] --> Device class CompositeDevice abstract OutputDevice[OutputDevice ✔] --> GPIODevice DigitalOutputDevice[DigitalOutputDevice ✔] --> OutputDevice PWMOutputDevice[PWMOutputDevice ✔] --> OutputDevice Buzzer[Buzzer ✖] --> DigitalOutputDevice LED[LED ✖] --> DigitalOutputDevice PWMLED[PWMLED ✖] --> PWMOutputDevice Servo[Servo ✖] --> CompositeDevice Motor[Motor ✖] --> CompositeDevice PhaseEnableMotor[PhaseEnableMotor ✔] --> CompositeDevice TonalBuzzer[TonalBuzzer ✖] --> CompositeDevice AngularServo[AngularServo ✖] --> Servo classDef abstract fill:#d4ffa6,stroke:#000 classDef default fill:#86bc4c,stroke:#000 ``` ## Logging `Godot-GPIO` logs under 4 levels: - `VERBOSE`: to debug the lib itself. Will flood your terminal. - `DEBUG`: Logs most events and gives a verbose overview of what's happening in the lib. - `INFO`: Default level. - `WARNING`: for local errors detected within this lib. - `ERROR`: when the underlying stack (rgs/lg) returns errors. # WIP Status Not all of `rgs` API is implemented (but still available as raw commands). This is a work in progress where contributions are welcome.
In addition to the high-level classes described above, here's a table to track which which parts of [rgs API](https://abyz.me.uk/lg/rgs.html) are supported: | Command | Supported | | :-------| :-------: | | LEGEND | --------- | | CMD | ✖ | <- `CMD` supported as raw command only | CMD | ✔ | <- `CMD` is supported in high-level objects | CMD | ? | <- there's no current plan to support `CMD` | FILES | --------- | | FO | ? | | FC | ? | | FR | ? | | FW | ? | | FS | ? | | FL | ✔ | | GPIO | --------- | | GO | ✔ | | GC | ✔ | | GIC | ✔ | | GIL | ✔ | | GMODE | ✔ | | GSI | ✔ | | GSIX | ✔ | | GSO | ✔ | | GSOX | ✔ | | GSA | ✖ | | GSAX | ✖ | | GSF | ✔ | | GSGI | ? | | GSGIX | ? | | GSGO | ? | | GSGOX | ? | | GSGF | ✖ | | GR | ✔ | | GW | ✔ | | GGR | ✖ | | GGW | ✖ | | GGWX | ✖ | | GP | ✔ | | GPX | ✔ | | P | ✖ | | PX | ✖ | | S | ✖ | | SX | ✖ | | GWAVE | ✖ | | GBUSY | ✖ | | GROOM | ✖ | | GDEB | ✖ | | GWDOG | ✖ | | I2C | --------- | | I2CO | ✖ | | I2CC | ✖ | | I2CWQ | ✖ | | I2CRS | ✖ | | I2CWS | ✖ | | I2CRB | ✖ | | I2CWB | ✖ | | I2CRW | ✖ | | I2CWW | ✖ | | I2CRK | ✖ | | I2CWK | ✖ | | I2CWI | ✖ | | I2CRI | ✖ | | I2CRD | ✖ | | I2CWD | ✖ | | I2CPC | ✖ | | I2CPK | ✖ | | I2CZ | ✖ | | NOTIFICATIONS | --- | | NO | ✖ | | NC | ✖ | | NP | ✖ | | NR | ✖ | | SCRIPTS | --------- | | PROC | ✖ | | PROCR | ✖ | | PROCU | ✖ | | PROCP | ✖ | | PROCS | ✖ | | PROCD | ✖ | | PARSE | ✖ | | SERIAL | --------- | | SERO | ✖ | | SERC | ✖ | | SERRB | ✖ | | SERWB | ✖ | | SERR | ✖ | | SERW | ✖ | | SERDA | ✖ | | SHELL | --------- | | SHELL | ✖ | | SPI | --------- | | SPIO | ✖ | | SPIC | ✖ | | SPIR | ✖ | | SPIW | ✖ | | SPIX | ✖ | | UTILITIES | ------- | | LGV | ✖ | | SBC | ✖ | | CGI | ✖ | | CSI | ✖ | | T/TICK | ✖ | | MICS | ✖ | | MILS | ✖ | | U/USER | ✖ | | C/SHARE | ✔ (Chip.share_id) | | LCFG | ✖ | | PCD | ✖ | | PWD | ✖ |
## FAQ ### Why spam `rds` subprocesses instead of doing a proper rgpio / GDExtension integration? I know. I wish I had the time. I'm working on this as a side-quest for a hobby. If the lib picks up, we'll plug a strategy pattern in, and add a native rpgio implementation. Until then, this is a quick (to write) way to get Godot to play with the Pi. ## Changelog ### 0.5.2 - fixed files missing in downloaded asset
Previous entries ### 0.5.1 - upgraded types to use fully typed Dictionary - motor slider sample: - fixed motor updates frequency by debouncing updates - made the reset btn a stop btn - phase and enable GPIO numbers can now be set from `GPIO_PHASE` & `GPIO_ENABLE` env vars ### 0.5 - upgrade to Godot 4.4 - samples now read .env file for setup ### 0.4 - implemented DigitalOutputDevice, and PHaseEnableMotor (with `enable` being a DigitalOutputDevice until PWMOutputDevice gets done) - added sample scenes to test / play with a single GPIO ([light_switch](https://github.com/onze/godot-gpio/tree/trunk/samples/light_switch)) and [a PE motor](https://github.com/onze/godot-gpio/tree/trunk/samples/motor_slider) ### 0.3 - moved all `lg` commands into the `ggpio.lg` namespace - added `SBC` class, refactored `Chip` & `GPIO` into an object oriented API ### 0.2 - ggpio explorer and fixes ### 0.1 - first working version