feat: added gpio control for led

This commit is contained in:
Arduinum628
2025-08-04 23:00:10 +03:00
parent d93d039406
commit 576d3c145f
6 changed files with 69 additions and 5 deletions

View File

@@ -1,3 +1,2 @@
run: run:
chmod +x robot_pi_service/robot_pi_service.py
python3 robot_pi_service/robot_pi_service.py python3 robot_pi_service/robot_pi_service.py

View File

@@ -2,6 +2,11 @@
**Robot-pi-service** - сервис для управления роботом на orange pi, работающий на linux Armbian. **Robot-pi-service** - сервис для управления роботом на orange pi, работающий на linux Armbian.
**Для работы с GPIO:**
1. `chmod +x gpio_setup.sh`
2. `./gpio_setup.sh`
**Запуск сервиса (как проекта python3)** - `make run` **Запуск сервиса (как проекта python3)** - `make run`
<details> <details>

7
gpio_setup.sh Normal file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
chmod -R +x robot_pi_service/
sudo groupadd gpio
sudo usermod -aG gpio $USER
echo 'SUBSYSTEM=="gpio", KERNEL=="gpiochip[0-9]*", GROUP="gpio", MODE="0660"' | sudo tee /etc/udev/rules.d/99-gpio.rules
sudo udevadm control --reload-rules
sudo udevadm trigger

View File

@@ -1,2 +1,3 @@
websockets==15.0.1 websockets==15.0.1
pydantic-settings==2.9.1 pydantic-settings==2.9.1
gpiod==2.3.0

View File

@@ -0,0 +1,34 @@
from gpiod import request_lines, LineSettings
from gpiod.line import Direction, Value
class LedLineGpio:
"""Класс для управления динией gpio для LED"""
def __init__(self, line: int) -> None:
self.line = line
self._request = request_lines(
'/dev/gpiochip0',
consumer='led-blinker',
config={
line: LineSettings(
direction=Direction.OUTPUT,
output_value=Value.INACTIVE
)
}
)
def on(self) -> None:
"""Метод для включения LED"""
self._request.set_value(self.line, Value.ACTIVE)
def off(self) -> None:
"""Метод для выключения LED"""
self._request.set_value(self.line, Value.INACTIVE)
def close(self) -> None:
"""Метод для освобождения ресурса"""
self._request.release()

View File

@@ -1,8 +1,10 @@
import asyncio import asyncio
from websockets import serve, exceptions from websockets import serve, exceptions
from websockets.legacy.server import WebSocketServerProtocol from websockets.legacy.server import WebSocketServerProtocol
from json import loads, JSONDecodeError
from settings import settings from settings import settings
from gpio_control import LedLineGpio
async def robot_control_gpio(websocket: WebSocketServerProtocol): async def robot_control_gpio(websocket: WebSocketServerProtocol):
@@ -11,16 +13,28 @@ async def robot_control_gpio(websocket: WebSocketServerProtocol):
""" """
try: try:
led_line_gpio = LedLineGpio(line=6)
action = None
while True: while True:
try: try:
command = await asyncio.wait_for(websocket.recv(), timeout=30.0) command = await asyncio.wait_for(websocket.recv(), timeout=30.0)
data = loads(command)
except asyncio.TimeoutError as err: except asyncio.TimeoutError as err:
print('Таймаут ожидания команды от клиента') print('Таймаут ожидания команды от клиента')
continue # продолжение цикла, чтобы не закрывать соединение continue # продолжение цикла, чтобы не закрывать соединение
except JSONDecodeError:
print("Ошибка при декодировании JSON")
continue
match command: match next(iter(data), None):
case settings.commands_robot.forward: case settings.commands_robot.forward:
if data.get(settings.commands_robot.forward):
action = 'Робот едет вперёд' action = 'Робот едет вперёд'
led_line_gpio.on()
else:
action = 'Команда вперёд стоп'
led_line_gpio.off()
print(action) print(action)
await websocket.send(message=action) await websocket.send(message=action)
case settings.commands_robot.backward: case settings.commands_robot.backward:
@@ -45,11 +59,15 @@ async def robot_control_gpio(websocket: WebSocketServerProtocol):
message_err = f'{err.__class__.__name__}: {err}' message_err = f'{err.__class__.__name__}: {err}'
print(message_err) print(message_err)
await websocket.send(message=message_err) await websocket.send(message=message_err)
finally:
led_line_gpio.close()
async def start(): async def start():
"""Асинхронная функция запуска вебсокета и бесконечного цикла""" """Асинхронная функция запуска вебсокета и бесконечного цикла"""
print('Старт сервиса робота для приёма команд.')
async with serve(handler=robot_control_gpio, host=settings.websocket_host, port=settings.websocket_port): async with serve(handler=robot_control_gpio, host=settings.websocket_host, port=settings.websocket_port):
# бесконечный цикл # бесконечный цикл
await asyncio.Future() await asyncio.Future()
@@ -61,7 +79,7 @@ def run_app():
try: try:
asyncio.run(start()) asyncio.run(start())
except KeyboardInterrupt: except KeyboardInterrupt:
pass print('Выключение сервиса робота для приёма команд.')
if __name__ == '__main__': if __name__ == '__main__':