Device GPIO - Getting Started
Note
Since GPIO sysfs
interface is deprecated after Linux version 4.8, two ABI interfaces are provided: the sysfs
version and the new chardev
version. By default, the interface is set to sysfs
. It can be changed inside the Driver
section of the service's configuration. For the chardev
interface, you need to specify a selected chip. This is also under Driver
section. See the Configuration section for more details
Running the Service
The simplest way to run all the required services is to use the Compose Builder tool from a terminal window
-
Clone https://github.com/edgexfoundry/edgex-compose/tree/main
-
Change to the compose-builder folder
-
Run the services
This runs, in non-secure mode, all the standard EdgeX services along with the Device GPIO service.make run no-secty ds-gpio
Sample Device Profile and Devices
This service contains the following sample device profiles and devices:
Device Profile | Device | Description |
---|---|---|
device.custom.gpio.yaml | device.custom.gpio.yaml | Example for GPIO with Power, LED and Switch |
device.led.gpio.yaml | device.led.gpio.yaml | Example for GPIO with just LED |
The device profiles are used to describe the actual GPIO hardware of a device and allow individual GPIOs to be given human-readable names/aliases.
Example walk-thru
The following are step-by-step examples of using this device service. In these examples, we use Core Command RESTful API to interact with EdgeX rather than directly interact with GPIO device service.
Example - Query Core Command for device GPIO-Device01
commands
curl http://localhost:59882/api/v3/device/name/GPIO-Device01
{
"apiVersion": "v2",
"statusCode": 200,
"deviceCoreCommand": {
"deviceName": "GPIO-Device01",
"profileName": "Custom-GPIO-Device",
"coreCommands": [
{
"name": "Power",
"get": true,
"set": true,
"path": "/api/v3/device/name/GPIO-Device01/Power",
"url": "http://edgex-core-command:59882",
"parameters": [
{
"resourceName": "Power",
"valueType": "Bool"
}
]
},
{
"name": "LED",
"set": true,
"path": "/api/v3/device/name/GPIO-Device01/LED",
"url": "http://edgex-core-command:59882",
"parameters": [
{
"resourceName": "LED",
"valueType": "Bool"
}
]
},
{
"name": "Switch",
"get": true,
"path": "/api/v3/device/name/GPIO-Device01/Switch",
"url": "http://edgex-core-command:59882",
"parameters": [
{
"resourceName": "Switch",
"valueType": "Bool"
}
]
}
]
}
}
Use the curl
response to get the command URLs (with device and command ids) to issue commands to the GPIO device via the command service as shown above. You can also use a tool like Postman
instead of curl
to issue the same commands.
Direction setting with sysfs
When using sysfs, the operations to access (read or write) the GPIO pins are:
- Export the pin
- Set the direction (either IN or OUT)
- Read the pin input or write the pin value based on the direction
- Unexport the pin
When using sysfs, setting the direction causes the value to be reset. Therefore, this implementation only sets the direction on opening the line to the GPIO. After that, it is assumed the same direction is used while the pin is in use and exported.
The direction is set by an optional attribute in the device profile called defaultDirection
. It can be set to either "in" or "out". If it is not set, the default direction is assumed to be "out".
Example - GPIO resource in device profile
-
name: "LED"
isHidden: false
description: "mocking LED"
attributes: { line: 27, defaultDirection: "out" }
properties:
valueType: "Bool"
readWrite: "W"
Note
The direction should not be confused with the device profile's read/write property. If you set the defaultDirection to in
but then set the readWrite property to RW
or W
, any attempt to write to the pin will result in a "permission denied" error. For consistency, when your defaultDirection is in
set readWrite to R
only.
Write value to GPIO
Assume a GPIO device (used for power enable) connected to gpio17 on current system of raspberry pi 4b. When a value is written to GPIO, this GPIO will give a high voltage.
Example - Set commands to set Power
resource on GPIO-Device01
# Set the 'Power' GPIO to high
$ curl -X PUT -d '{"Power":"true"}' http://localhost:59882/api/v3/device/name/GPIO-Device01/Power
{"apiVersion":"v2","statusCode":200}
$ cat /sys/class/gpio/gpio17/direction ; cat /sys/class/gpio/gpio17/value
out
1
# Set the 'Power' GPIO to low
$ curl -X PUT -d '{"Power":"false"}' http://localhost:59882/api/v3/device/name/GPIO-Device01/Power
{"apiVersion":"v2","statusCode":200}
$ cat /sys/class/gpio/gpio17/direction ; cat /sys/class/gpio/gpio17/value
out
0
Now if you test gpio17 of raspberry pi 4b , it is outputting high voltage.
Read value from GPIO
Assume another GPIO device (used for button detection) connected to pin 22 on current system. When a value is read from GPIO, this GPIO will be exported and set direction to input.
Example - GET command for Switch
resource on GPIO-Device01
$ curl http://localhost:59882/api/v3/device/name/GPIO-Device01/Switch
{
"apiVersion": "v2",
"statusCode": 200,
"event": {
"apiVersion": "v2",
"id": "a6104256-92a4-41a8-952a-396cd3dabe25",
"deviceName": "GPIO-Device01",
"profileName": "Custom-GPIO-Device",
"sourceName": "Switch",
"origin": 1634221479227566300,
"readings": [
{
"id": "240dc2ea-d69f-4229-94c4-3ad0507cf657",
"origin": 1634221479227566300,
"deviceName": "GPIO-Device01",
"resourceName": "Switch",
"profileName": "Custom-GPIO-Device",
"valueType": "Bool",
"value": "false"
}
]
}
}