Created
October 21, 2025 13:10
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!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