Помогите создать управление поворотниками и сигналом

Приветствую. Имеется плата arduino nano v3, хочу сделать управление поворотниками для электросамоката.

Мы не возражаем - делайте

1 лайк

Вопрос как в этом коде добавить аварийку при удержании одной кнопки и добавить ещё одну кнопку без удержания для клаксона? В ардуино новичок, данный код нашел на этом форуме

#define KEY_LEFT      2
#define KEY_RIGHT     3
#define LED_LEFT      4
#define LED_RIGHT     5
#define DEBOUNCE_TIME 30
#define BLINK_TIME    490

#define in(x)         pinMode(x, INPUT_PULLUP)
#define out(x)        pinMode(x, OUTPUT)
#define pin(x)        !digitalRead(x)
#define off(x)        digitalWrite(x, LOW)
#define toggle(x)     digitalWrite(x, !digitalRead(x))

bool left, right;
int timer;

void setup() {
  in(KEY_LEFT);
  in(KEY_RIGHT);
  off(LED_LEFT);  out(LED_LEFT);
  off(LED_RIGHT); out(LED_RIGHT);
  timer = 0;
}

void loop() {
  delay(1);
  char key = getKey();
  if (key == 1<<KEY_LEFT) {
    left = !left;
    right = false;
    setup();
  }
  if (key == 1<<KEY_RIGHT) {
    right = !right;
    left = false;
    setup();
  }

  if (left)
    blink(LED_LEFT);
  else if (right)
    blink(LED_RIGHT);
  else
    setup();

}

char getKey() {
  static char timer;
  static char old;
  char key = pin(KEY_LEFT)<<KEY_LEFT | pin(KEY_RIGHT)<<KEY_RIGHT;
  if (old != key) {
    old = key;
    timer = DEBOUNCE_TIME;
  }
  else if (timer && !--timer)
    return key; 
  return 0;
}
 
void blink(char pin) {
  if (!timer)
    toggle(pin);
  if (++timer >= BLINK_TIME)
    timer = 0;
}
#define KEY_LEFT      2  // Кнопка левого поворотника
#define KEY_RIGHT     3  // Кнопка правого поворотника
#define KEY_HORN      6  // Кнопка клаксона (новая)
#define LED_LEFT      4  // Левый поворотник
#define LED_RIGHT     5  // Правый поворотник
#define HORN_OUT      7  // Выход для клаксона (новый)
#define DEBOUNCE_TIME 30 // Время антидребезга
#define BLINK_TIME    490 // Интервал мигания
#define HOLD_TIME     1000 // Время удержания для аварийки (1 секунда)

#define in(x)         pinMode(x, INPUT_PULLUP)
#define out(x)        pinMode(x, OUTPUT)
#define pin(x)        !digitalRead(x)
#define off(x)        digitalWrite(x, LOW)
#define on(x)         digitalWrite(x, HIGH)
#define toggle(x)     digitalWrite(x, !digitalRead(x))

bool left, right, hazard; // Флаги для левого, правого и аварийного режима
int timer; // Таймер для мигания
unsigned long holdTimer; // Таймер для удержания кнопки

void setup() {
  in(KEY_LEFT);
  in(KEY_RIGHT);
  in(KEY_HORN);       // Инициализация кнопки клаксона
  off(LED_LEFT);      out(LED_LEFT);
  off(LED_RIGHT);     out(LED_RIGHT);
  off(HORN_OUT);      out(HORN_OUT); // Инициализация выхода клаксона
  timer = 0;
  holdTimer = 0;
}

void loop() {
  delay(1);
  char key = getKey();

  // Обработка короткого нажатия левого поворотника
  if (key == 1<<KEY_LEFT) {
    left = !left;
    right = false;
    hazard = false;
    setup(); // Сброс состояния
  }
  // Обработка короткого нажатия правого поворотника
  if (key == 1<<KEY_RIGHT) {
    right = !right;
    left = false;
    hazard = false;
    setup();
  }
  // Обработка кнопки клаксона
  if (pin(KEY_HORN)) {
    on(HORN_OUT); // Включить клаксон
  } else {
    off(HORN_OUT); // Выключить клаксон
  }

  // Проверка удержания кнопки KEY_LEFT для аварийки
  if (pin(KEY_LEFT) && !left && !right) { // Если кнопка удерживается и поворотники выключены
    if (holdTimer == 0) holdTimer = millis(); // Начать отсчёт времени
    if (millis() - holdTimer >= HOLD_TIME) { // Если прошло достаточно времени
      hazard = true;
      left = false;
      right = false;
    }
  } else {
    holdTimer = 0; // Сброс таймера удержания
  }

  // Логика мигания
  if (hazard) {
    blinkBoth(); // Мигаем обоими поворотниками
  } else if (left) {
    blink(LED_LEFT); // Левый поворотник
  } else if (right) {
    blink(LED_RIGHT); // Правый поворотник
  } else {
    setup(); // Выключить всё
  }
}

char getKey() {
  static char timer;
  static char old;
  char key = pin(KEY_LEFT)<<KEY_LEFT | pin(KEY_RIGHT)<<KEY_RIGHT;
  if (old != key) {
    old = key;
    timer = DEBOUNCE_TIME;
  }
  else if (timer && !--timer)
    return key; 
  return 0;
}

void blink(char pin) {
  if (!timer)
    toggle(pin);
  if (++timer >= BLINK_TIME)
    timer = 0;
}

void blinkBoth() {
  if (!timer) {
    toggle(LED_LEFT);
    toggle(LED_RIGHT);
  }
  if (++timer >= BLINK_TIME)
    timer = 0;
}

Короткое нажатие на KEY_LEFT или KEY_RIGHT включает/выключает соответствующий поворотник.
Удержание KEY_LEFT более 1 секунды включает аварийку (оба поворотника мигают).
Нажатие на KEY_HORN активирует клаксон, отпускание — выключает

Спасибо большое

Не понял, чего все кинулсь поворотники делать? Президент указ, что ли, такой издал? Вроде, в новостях не было.

У нас в городе гайцы домахиваются если ехать по дороге

Аварийка не срабатывает почему то

а нахрена здесь чип с прошивкой? два штуки NE555, три физические кнопки, горстка обвязки, не?

нет. надо чтоб одна плата управляла

меньше одной смысла нет делать, ага)

Мы цифровики или где? А цифровик – это человек, который пихает микроконтроллер даже туда, где достаточно конденсатора.

Да и, что значит,

Тогда уж

1 лайк
#define KEY_LEFT      2  // Кнопка левого поворотника
#define KEY_RIGHT     3  // Кнопка правого поворотника
#define KEY_HORN      6  // Кнопка клаксона
#define LED_LEFT      4  // Левый поворотник
#define LED_RIGHT     5  // Правый поворотник
#define HORN_OUT      7  // Выход для клаксона
#define DEBOUNCE_TIME 50 // Время антидребезга (мс)
#define BLINK_TIME    500 // // Интервал мигания (мс)
#define HOLD_TIME     1000 // Время удержания для аварийки (мс)

#define in(x)         pinMode(x, INPUT_PULLUP)
#define out(x)        pinMode(x, OUTPUT)
#define pin(x)        !digitalRead(x)
#define off(x)        digitalWrite(x, LOW)
#define on(x)         digitalWrite(x, HIGH)
#define toggle(x)     digitalWrite(x, !digitalRead(x))

bool left = false;
bool right = false;
bool hazard = false;

void setup() {
  in(KEY_LEFT);
  in(KEY_RIGHT);
  in(KEY_HORN);
  out(LED_LEFT);  off(LED_LEFT);
  out(LED_RIGHT); off(LED_RIGHT);
  out(HORN_OUT);  off(HORN_OUT);
  Serial.begin(9600); // Для отладки
}

void loop() {
  unsigned long currentTime = millis();

  // Обработка кнопок
  if (checkKey(KEY_LEFT)) {
    Serial.println("Left pressed");
    if (!left && !right && !hazard) left = true;
    else left = right = hazard = false;
  }
  if (checkKey(KEY_RIGHT)) {
    Serial.println("Right pressed");
    if (!left && !right && !hazard) right = true;
    else left = right = hazard = false;
  }
  if (pin(KEY_HORN)) {
    on(HORN_OUT);
    Serial.println("Horn ON");
  } else {
    off(HORN_OUT);
  }

  // Удержание KEY_LEFT для аварийки
  static unsigned long holdStart = 0;
  if (pin(KEY_LEFT) && !left && !right && !hazard) {
    if (holdStart == 0) holdStart = currentTime;
    if (currentTime - holdStart >= HOLD_TIME) {
      hazard = true;
      left = right = false;
      holdStart = 0;
      Serial.println("Hazard ON");
    }
  } else {
    holdStart = 0;
  }

  // Логика мигания
  static unsigned long lastBlink = 0;
  if (currentTime - lastBlink >= BLINK_TIME) {
    lastBlink = currentTime;
    if (hazard) {
      toggle(LED_LEFT);
      toggle(LED_RIGHT);
      Serial.println("Hazard blinking");
    } else if (left) {
      toggle(LED_LEFT);
      off(LED_RIGHT);
      Serial.println("Left blinking");
    } else if (right) {
      toggle(LED_RIGHT);
      off(LED_LEFT);
      Serial.println("Right blinking");
    } else {
      off(LED_LEFT);
      off(LED_RIGHT);
    }
  }
}

bool checkKey(uint8_t keyPin) {
  static bool lastState[2] = {false, false};
  static uint8_t debounceTimer[2] = {0, 0};
  uint8_t idx = (keyPin == KEY_LEFT) ? 0 : 1;
  bool currentState = pin(keyPin);

  if (currentState != lastState[idx]) {
    debounceTimer[idx] = DEBOUNCE_TIME;
    lastState[idx] = currentState;
  } else if (debounceTimer[idx]) {
    if (--debounceTimer[idx] == 0 && currentState) {
      return true;
    }
  }
  return false;
}

пробуй

Нет не включается. Удерживаю и более секунды, и левую и правую пробовал

в сериал что пишет когда кнопки нажимаешь?

Ух ты! Узнаю до боли знакомый почерк. Откуда это?

// Удержание KEY_LEFT для аварийки
static unsigned long holdStart = 1;
заменил 0 на 1 и заработало всё

Основа судя по всему ваша

Ага. Почти 5 лет прошло.) Эх.