Skip to content

Instantly share code, notes, and snippets.

@sleventyeleven
Created October 21, 2025 13:10
Show Gist options
  • Select an option

  • Save sleventyeleven/76a5f041eb80eb16b3782b19dfeebb22 to your computer and use it in GitHub Desktop.

Select an option

Save sleventyeleven/76a5f041eb80eb16b3782b19dfeebb22 to your computer and use it in GitHub Desktop.
simple flask app to control the Radxa Zero 3w control pins for skeleton animatronic
import gpiod
from flask import Flask, render_template, request
# --- Configuration ---
# Find the chip and line using the `gpiofind` command.
# For example, to find PIN_11, run: `gpiofind PIN_11`
# This might output something like "gpiochip0 11".
GPIO_CHIP_NAME = "gpiochip3"
# --- Flask App Initialization ---
app = Flask(__name__)
# --- GPIO Control Functions ---
def set_gpio_state(state, GPIO_PIN_OFFSET):
"""Sets the specified GPIO pin to the desired state (1 or 0)."""
try:
chip = gpiod.Chip(GPIO_CHIP_NAME)
line = chip.get_line(GPIO_PIN_OFFSET)
line.request(consumer="webserver", type=gpiod.LINE_REQ_DIR_OUT)
line.set_value(state)
line.release()
except Exception as e:
print(f"Error controlling GPIO: {e}")
def get_gpio_status(GPIO_PIN_OFFSET):
"""Attempt to get current GPIO Status"""
chip = gpiod.Chip(GPIO_CHIP_NAME)
line = chip.get_line(GPIO_PIN_OFFSET)
line.request(consumer="webserver")
status = line.get_value()
return status
# --- Web Routes ---
@app.route('/')
def index():
"""Renders the main web page with the control buttons."""
return render_template('index.html', offsets=[get_gpio_status(20),get_gpio_status(1), get_gpio_status(8)])
@app.route('/gpio/status/<int:pinoffset>')
def status_gpio(pinoffset):
"""Handles the GPIO status request from the web page."""
if pinoffset not in [1,7,8,20]:
return "Invalid offset", 400
return str(get_gpio_status(pinoffset))
@app.route('/gpio/<int:pinoffset>/<int:state>')
def control_gpio(state,pinoffset):
"""Handles the GPIO control request from the web page."""
if pinoffset not in [1,7,8,20]:
return "Invalid offset", 400
if state == 1:
set_gpio_state(1,pinoffset)
return "LED ON", 200
elif state == 0:
set_gpio_state(0,pinoffset)
return "LED OFF", 200
else:
return "Invalid state", 400
if __name__ == '__main__':
# It's important to run with elevated permissions to access GPIO.
# Alternatively add a udev rule to assign read privileges to a gpio group and add your user
# The `host='0.0.0.0'` makes the server accessible from other devices on the network.
app.run(host='0.0.0.0', port=8080)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Radxa GPIO Control</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; }
.button-group button { font-size: 24px; padding: 10px 20px; margin: 10px; cursor: pointer; }
.on { background-color: #4CAF50; color: white; }
.off { background-color: #f44336; color: white; }
</style>
</head>
<body>
<h1>Radxa GPIO Web Control</h1>
<div class="button-group">
Pin 7 Control is {% if offsets[0] == 1%}
<button class="on" onclick="control_gpio(0,20)">ON</button>
{% else %}
<button class="off" onclick="control_gpio(1,20)">OFF</button>
{% endif %}
</div>
<div class="button-group">
Pin 11 Control is {% if offsets[1] == 1%}
<button class="on" onclick="control_gpio(0,1)">ON</button>
{% else %}
<button class="off" onclick="control_gpio(1,1)">OFF</button>
</div>
{% endif %}
<div class="button-group">
Pin 15 Control is {% if offsets[2] == 1%}
<button class="on" onclick="control_gpio(0,8)">ON</button>
{% else %}
<button class="off" onclick="control_gpio(1,8)">OFF</button>
{% endif %}
</div>
<script>
function control_gpio(state,pinoffset) {
fetch(`/gpio/${pinoffset}/${state}`)
.then(response => response.text())
.then(text => console.log(text))
.catch(error => console.error('Error:', error));
setTimeout(() => {
location.reload();
}, 500);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment