Управление поездом джойстиком от ps2

Доброго времени суток.
Решил сделать внуку поезд, подсмотрев у Гайвера ролик про управление машинкой пультом от ps2.

Функционал следующий:
Движение вперед-назад стиком
Включение(выключение) головных огней (светодиод)
Включение(выключение) задних огней (светодиод)

в общем двигатель крутится нормально, а вот с огнями возникла проблема, то моргают, то включаются одной кнопкой, а выключаются другой, в общем нужна помощь, сам как-то не справляюсь.
Сразу говорю, что не программист и про программирование знал в школе только бейсик, и это было в конце 80-х прошлого века.

#define MOT_RA 2  // пины драйвера двигателя
#define MOT_RB 3  // пины драйвера двигателя
#define LED_FR 8  // пины светодиодов передних
#define LED_RE 9  // пины светодиодов задних
#define PS2_DAT A0  // пины ресивера ps2
#define PS2_CMD A1  // пины ресивера ps2
#define PS2_SEL A2  // пины ресивера ps2
#define PS2_CLK A3  // пины ресивера ps2
#define pressures false
#define rumble false

#define MIN_DUTY 40  // мин. сигнал, при котором мотор начинает вращение

int buttonStateF = LOW;  // Переменная для хранения состояния кнопки передних огней
int ledStateF = LOW;   // Переменная для хранения состояния светодиода передних огней
int buttonStateR = LOW;  // Переменная для хранения состояния кнопки задних огней
int ledStateR = LOW;   // Переменная для хранения состояния светодиода задних огней

#include <PS2X_lib.h>   // подключаем библиотеку PS2X
PS2X ps2x;

#include <GyverMotor.h>  // подключаем библиотеку GyverMotor
GMotor motor(DRIVER2WIRE, MOT_RA, MOT_RB, HIGH);  // (тип, пин, ШИМ пин, уровень)

void setup() {
  //  Serial.begin(9600);
  //  delay(500);

  motor.setMode(AUTO);
  motor.setDirection(NORMAL);  // НАПРАВЛЕНИЕ ДВИЖЕНИЯ (зависит от подключения)
  motor.setMinDuty(MIN_DUTY);  // мин. сигнал вращения
  motor.setSmoothSpeed(80);    // плавность скорости моторов
  
  ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, false, false);   // подрубаем геймпад

  pinMode(LED_FR, OUTPUT);  // Настраиваем пин для светодиода как выход
  pinMode(LED_RE, OUTPUT);  // Настраиваем пин для светодиода как выход
}

void loop() {
  // читаем геймпад
  bool success = ps2x.read_gamepad(false, 0);  // читаем
  //  ps2x.reconfig_gamepad();      // костыль https://stackoverflow.com/questions/46493222/why-arduino-needs-to-be-restarted-after-ps2-controller-communication-in-arduino


  if (success) {
    int RY = map(ps2x.Analog(PSS_RY), 255, 0, -253, 255);   // преобразуем стики от 0..255 к -255, 255

    RY = constrain(RY, -255, 255);
    int SPEED = RY;
    motor.smoothTick(RY);  // задаём целевую скорость

    // включение(выключение) головных огней
    buttonStateF = ps2x.ButtonPressed(PSB_L1);  // Читаем состояние кнопки
    if (buttonStateF == HIGH) {                 // Если кнопка нажата
      ledStateF = !ledStateF;                   // Меняем состояние светодиода
      digitalWrite(LED_FR, ledStateF);          // Устанавливаем новое состояние светодиода
    }

    // включение(выключение) задних огней
    buttonStateR = ps2x.ButtonPressed(PSB_L2);  // Читаем состояние кнопки
    if (buttonStateR == HIGH) {                 // Если кнопка нажата
      ledStateR = !ledStateR;                   // Меняем состояние светодиода
      digitalWrite(LED_RE, ledStateR);          // Устанавливаем новое состояние светодиода
    }

  }


  else {
    motor.setSpeed(0);  // проблема с геймпадом - остановка
  }
}

Внуки в 40 лет,- это круто.

И почему Вы здесь, а не на форуме “Гайвера”?

Мы-то чем виноваты?

И кстати, Вы написали

только забыли написать какая именно помощь Вам нужна.

Вам дать адрес гивер-форума? Пожалуйста – https://community.alexgyver.ru/

Пожелать удачи? Желаю!

Помогло?

Или Вам какая-то другая помощь нужна? Так Вы говорите, не стеясняйтесь.

Да дело даже не в этом. От сообщества то что надо? Чтобы написали работающий код?

Помощь нужна, чтобы носом ткнули в чем ошибаюсь.
Т.е. даже смотрю осциллографом на ногах куда светодиоды подключены, ну не срабатывает на нажатие кнопок.
Может опрос кнопок неверно описал, может еще чего.

А насчет внуков в 40 - улыбнуло. Основы информатики и вычислительной техники были в 9 и 10 классах, та-то.
Мне уже давно за 50. :wink:

А на первый мой вопрос ответа не будет?

Вы забыли толком написать что Вы хотели сделать, так что как понять в чём Вы ошибаетесь. а в чём – нет?

Впрочем, это всё вторично. Первичен мой первый вопрос. Почему с поделкой Гивера Вы пришли к нам, а не к нему? Чем мы провинились?

  1. От поделки Гайвера тут только идея - использовать пуль от плойки.
  2. Движение двигателя в обоих направлениях работает
  3. есть светодиод головного прожектора, который должен включаться и выключаться по нажатию кнопки.
  4. есть светодиод заднего фонаря, должен включаться и выключаться нажатием другой кнопки.

Так вот светодиоды не понятно включаются и выключаются, хотя монитор порта показывает, что все хорошо. Но вот на пинах ардуинки осциллограф показывает скачки сигналов, никак не связанные с нажатием кнопок

Для начала попробуйте зашунтировать контакты двигателя конденсатором 0,1 мкФ

Где показывает? В исходнике Serial вообще никак не участвует.

Это и не удивительно

Цикл loop отрабатывает очень быстро, миллисекунды. Во время одного нажатия кнопки этот код отработает несколько раз.
Чтобы этого не было , вам надо или сделать задержку (но это скажется на работе остальной части программы, или завести ещё по флагу на кнопку, и, блокировать/разрешать работу определённых частей кода.

…или включать одной кнопкой, а отключать другой, если есть лишняя.

Спасибо!
Буду пробовать

неверно.
У вас принцип опроса кнопок в корне неправильный.

В коде выше Вы определяете состояние пина кнопки. А надо - ИЗМЕНЕНИЕ состояния. Почувствуйте разницу.
Почему это важно ? - потому уровень HIGH с кнопки вы можете прочитать много раз за время нажатия - и каждый раз ваш код будет включать-выключать огни туда-обратно. А вот изменение , допустим из LOW в HIGH происходит только один раз за нажатие.
Отслеживайте изменение - и кнопки будут работать четко и адекватно.

Что-то видимо не получается…А от Гайвера ни ответа ни привета))
Внёс минимальные изменения в ваш код:

Спойлер
#define LED_FR 8  // пины светодиодов передних
#define LED_RE 9  // пины светодиодов задних
#define PSB_L1 2  // пины светодиодов передних
#define PSB_L2 3  // пины светодиодов задних
bool L1 = false;
bool L2 = false;
bool buttonStateF = LOW;  // Переменная для хранения состояния кнопки передних огней
bool ledStateF = LOW;   // Переменная для хранения состояния светодиода передних огней
bool buttonStateR = LOW;  // Переменная для хранения состояния кнопки задних огней
bool ledStateR = LOW;   // Переменная для хранения состояния светодиода задних огней

void setup(){
  pinMode(LED_FR, OUTPUT);
  pinMode(LED_RE, OUTPUT);
  pinMode(PSB_L1, INPUT); //кнопки подтянуты к земле, 
  pinMode(PSB_L2, INPUT); //активный уровень - HIGH
}


void loop(){
  // включение(выключение) головных огней
    buttonStateF = digitalRead(PSB_L1);  // Читаем состояние кнопки
    if (buttonStateF == HIGH && ! L1) {                 // Если кнопка нажата
      ledStateF = !ledStateF;                   // Меняем состояние светодиода
      digitalWrite(LED_FR, ledStateF);// Устанавливаем новое состояние светодиода
      L1 = true;   // зафиксировали факт нажатия установкой флага
    }
    if (buttonStateF == LOW &&  L1)
        L1 = false;//убедившись, что кнопка отпущена - сбрасываем флаг

    // включение(выключение) задних огней
    buttonStateR = digitalRead(PSB_L2);  // Читаем состояние кнопки
    if (buttonStateR == HIGH && !L2) {                 // Если кнопка нажата
      ledStateR = !ledStateR;                   // Меняем состояние светодиода
      digitalWrite(LED_RE, ledStateR);
       L2 = true;          
    }
     if (buttonStateF == LOW &&  L2)
        L2 = false;
     
}