Загрузка данных


import RPi.GPIO as GPIO
import sys
import termios
import tty
import select
import time

# --- Настройка GPIO ---
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

# Пины: (forward, backward, enable)
# Плата №1 — передняя ось
LF = (9,  11, 13)   # левое переднее
RF = (25, 24, 18)   # правое переднее
# Плата №2 — задняя ось
LR = (26, 19, 12)   # левое заднее
RR = (20, 16, 17)   # правое заднее

all_pins = [p for wheel in (LF, LR, RF, RR) for p in wheel]
GPIO.setup(all_pins, GPIO.OUT, initial=GPIO.LOW)

# ШИМ на каждом EN-пине
pwm = {
    13: GPIO.PWM(13, 1000),
    18: GPIO.PWM(18, 1000),
    12: GPIO.PWM(12, 1000),
    17: GPIO.PWM(17, 1000),
}
for p in pwm.values():
    p.start(0)

# Глобальные переменные
speed = 60
MIN_SPEED, MAX_SPEED, STEP = 20, 100, 10
current_cmd = None
last_key_time = 0.0
HOLD_TIMEOUT = 0.4   # сек: если клавиша не повторилась за это время — стоп

def set_wheel(wheel, direction):
    """direction: 1 — вперёд, -1 — назад, 0 — стоп"""
    fwd, bwd, en = wheel
    if direction > 0:
        GPIO.output(fwd, GPIO.HIGH)
        GPIO.output(bwd, GPIO.LOW)
        pwm[en].ChangeDutyCycle(speed)
    elif direction < 0:
        GPIO.output(fwd, GPIO.LOW)
        GPIO.output(bwd, GPIO.HIGH)
        pwm[en].ChangeDutyCycle(speed)
    else:
        GPIO.output(fwd, GPIO.LOW)
        GPIO.output(bwd, GPIO.LOW)
        pwm[en].ChangeDutyCycle(0)

def stop_all():
    for w in (LF, LR, RF, RR):
        set_wheel(w, 0)

def forward():
    for w in (LF, LR, RF, RR):
        set_wheel(w, 1)

def backward():
    for w in (LF, LR, RF, RR):
        set_wheel(w, -1)

def turn_left():
    set_wheel(LF, -1); set_wheel(LR, -1)
    set_wheel(RF,  1); set_wheel(RR,  1)

def turn_right():
    set_wheel(LF,  1); set_wheel(LR,  1)
    set_wheel(RF, -1); set_wheel(RR, -1)

def apply_speed_change():
    """Переприменяет текущее движение с новой скоростью."""
    if current_cmd == 'w':   forward()
    elif current_cmd == 's': backward()
    elif current_cmd == 'a': turn_left()
    elif current_cmd == 'd': turn_right()

def get_key(timeout=0.05):
    """Читает один символ, если есть. Иначе None."""
    r, _, _ = select.select([sys.stdin], [], [], timeout)
    if not r:
        return None
    return sys.stdin.read(1)

def main():
    global speed, current_cmd, last_key_time
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)

    print("Управление (движение — только пока клавиша зажата):")
    print("  W / A / S / D   — движение")
    print("  ,   /   .       — скорость -10% / +10%")
    print("  Пробел          — стоп")
    print("  Q               — выход")
    print(f"Стартовая скорость: {speed}%\n")

    current_cmd = None
    last_key_time = 0.0
    stop_all()

    try:
        tty.setraw(fd)
        while True:
            key = get_key(0.05)
            now = time.time()

            if key is not None:
                k = key.lower()

                if k == 'q':
                    print("\nВыход...")
                    break

                elif k in ('w', 's', 'a', 'd'):
                    last_key_time = now
                    if current_cmd != k:
                        if   k == 'w': forward()
                        elif k == 's': backward()
                        elif k == 'a': turn_left()
                        elif k == 'd': turn_right()
                        current_cmd = k
                        names = {'w':'Вперёд','s':'Назад','a':'Влево','d':'Вправо'}
                        print(f"{names[k]} ({speed}%)")

                elif k == '.':
                    speed = min(MAX_SPEED, speed + STEP)
                    print(f"Скорость: {speed}%")
                    apply_speed_change()

                elif k == ',':
                    speed = max(MIN_SPEED, speed - STEP)
                    print(f"Скорость: {speed}%")
                    apply_speed_change()

                elif k == ' ':
                    stop_all()
                    current_cmd = 'stop'
                    print("Стоп")

            # Таймаут удержания: если клавиша движения не повторилась — стоп
            if current_cmd in ('w', 's', 'a', 'd') and (now - last_key_time) > HOLD_TIMEOUT:
                stop_all()
                current_cmd = 'stop'
                print("Стоп (клавиша отпущена)")

    except KeyboardInterrupt:
        print("\nПрервано.")
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old)
        stop_all()
        for p in pwm.values():
            p.stop()
        GPIO.cleanup()
        print("GPIO очищены.")

if __name__ == "__main__":
    main()