Good afternoon
I come looking for your guidance, I have been struggling for 2 days with this that should be simple, I have a work team that does not have Pixhawk, because I only need video, but now I would like to add lights controlled by a pwm (0 to 3.3 V) from the same Raspberry, the first thing I thought was the existing extension “example5-gpio-control” which did not work for me because it was focused on controlling a servo (pwm varies between 0.2 and 0.35 V) so I tried to modify the main.py code and created my own extension (code attached) but I still can’t get it to work, does anyone have a simpler solution or how to make my extension work?
#! /usr/bin/env python3
from pathlib import Path
import appdirs
import uvicorn
from fastapi.staticfiles import StaticFiles
from fastapi import FastAPI, HTTPException, status
from fastapi.responses import HTMLResponse, FileResponse
from fastapi_versioning import VersionedFastAPI, version
from loguru import logger
from typing import Any
from gpiozero import PWMLED # Se importa PWMLED en lugar de Servo
from pydantic import BaseModel
class TextData(BaseModel):
data: str
SERVICE_NAME = "ExampleExtension5"
app = FastAPI(
title="Example Extension r API",
description="API for an example extension that saves/loads data as files.",
)
logger.info(f"Starting {SERVICE_NAME}!")
servos = {} # Cambiado de "servos" a "leds"
@app.post("/setLed", status_code=status.HTTP_200_OK)
@version(1, 0)
async def set_led(pin: int, pwm: float) -> Any:
if pin < 0 or pwm < -1 or pwm > 1:
raise HTTPException("Invalid values")
if pin not in servos:
servos[pin] = PWMLED(pin)
intensity = (pwm + 1) / 2 # Mapea el valor de la barra (-1 a 1) a intensidad LED (0 a 1)
servos[pin].value = intensity
return "ok"
app = VersionedFastAPI(app, version="1.0.0", prefix_format="/v{major}.{minor}", enable_latest=True)
app.mount("/", StaticFiles(directory="static",html = True), name="static")
@app.get("/", response_class=FileResponse)
async def root() -> Any:
return "index.html"
if __name__ == "__main__":
# Running uvicorn with log disabled so loguru can handle it
uvicorn.run(app, host="0.0.0.0", port=80, log_config=None)
Hi @seba -
Can you give more context for what you are trying to accomplish? You’d like a PWM signal output, of the more traditional PWM rather than servo-style? You’re trying to output this from a Pixhawk pin, or a pin on a Raspberry Pi without a Navigator?
How are you executing your code? From within a Docker container in BlueOS?
Hi Tony
I followed your advice and changed the code using the library (the code is attached) and replaced the main.py file in the extension, but it doesn’t work. I don’t know if I’m building the extension incorrectly or if I need to change something other than the main code. I appreciate any guidance.
#! /usr/bin/env python3
from pathlib import Path
import appdirs
import uvicorn
from fastapi.staticfiles import StaticFiles
from fastapi import FastAPI, HTTPException, status
from fastapi.responses import HTMLResponse, FileResponse
from fastapi_versioning import VersionedFastAPI, version
from loguru import logger
from typing import Any
import pigpio # Se importa pigpio en lugar de gpiozero
from pydantic import BaseModel
class TextData(BaseModel):
data: str
SERVICE_NAME = "ExampleExtension5"
app = FastAPI(
title="Example Extension r API",
description="API for an example extension that saves/loads data as files.",
)
logger.info(f"Starting {SERVICE_NAME}!")
# Se inicializa pigpio
pi = pigpio.pi()
if not pi.connected:
raise RuntimeError("No se pudo conectar al demonio pigpio. Asegúrese de que esté corriendo (sudo pigpiod).")
@app.post("/setLed", status_code=status.HTTP_200_OK)
@version(1, 0)
async def set_led(pin: int, pwm: float) -> Any:
# Verifica que el valor esté en el rango esperado
if pin < 0 or pwm < -1 or pwm > 1:
raise HTTPException(status_code=400, detail="Invalid values")
# Mapea el valor recibido (-1 a 1) a la intensidad (0 a 1)
intensity = (pwm + 1) / 2
# Transforma la intensidad a un valor de duty cycle entre 0 y 255
duty_cycle = int(intensity * 255)
# Configura la frecuencia de PWM para el pin si es necesario (opcional)
# pi.set_PWM_frequency(pin, 1000)
# Establece el duty cycle en el pin especificado
pi.set_PWM_dutycycle(pin, duty_cycle)
return "ok"
app = VersionedFastAPI(app, version="1.0.0", prefix_format="/v{major}.{minor}", enable_latest=True)
app.mount("/", StaticFiles(directory="static", html=True), name="static")
@app.get("/", response_class=FileResponse)
async def root() -> Any:
return "index.html"
if __name__ == "__main__":
# Se ejecuta uvicorn con el log deshabilitado para que loguru se encargue del logging
uvicorn.run(app, host="0.0.0.0", port=80, log_config=None)
Hi @seba -
Are you running that code within a BlueOS docker container as an extension, or on a Pi running Raspian? If using BlueOS, you likely need t adjust your container’s permissions to have access to the GPIO…
Hi @seba -
Apologies, my earlier advice assumed you weren’t doing anything with BlueOS. This example should be what you need!
You can fork that repo and deploy it to your docker hub, then install as an extension manually as detailed in the documentation.
That’s exactly what I did. I used that same example as a base to create my extension. I installed it without any problems, but I still can’t get it to work the way I need it to. I don’t know what I’m doing wrong.
Hi @seba -
Where are you having issues? Have you successfully deployed the docker image to your BlueOS device? If so, the logs, available from the installed extensions page in BlueOs, should give a starting point for troubleshooting the issue…