Menu
CoddyTech

Кнопка перехода

Часть раздела Проекты путешествия по Arduino на Coddy. Урок 3 из 24.

Пешеходам нужен способ попросить разрешения перейти дорогу. Синяя кнопка на контакте 2 — это кнопка перехода: нажатие во время зелёного сигнала немедленно завершает его, и для машин загорается жёлтый, а затем красный.

Поскольку светофоры работают с помощью millis(), loop() проходит через состояние зелёного сигнала тысячи раз в секунду и каждый раз может считывать состояние кнопки, а также время. Зелёный сигнал заканчивается, когда верно хотя бы одно из этих условий, что и означает || (или):

case GREEN:
  if (millis() - lightStart >= 3000 || digitalRead(buttonPin) == LOW) {
    // переключиться на жёлтый
  }
  break;

Кнопка соединяет контакт 2 с землёй, поэтому настрой контакт как INPUT_PULLUP: он считывает HIGH, пока нажатие кнопки не переключит его на LOW.

Кнопка считывается только в состоянии зелёного сигнала. При жёлтом и красном сигналах машины уже останавливаются, а жёлтый горит полную секунду, чтобы у водителей было время остановиться.

challenge icon

Задание

Средне

Добавь кнопку перехода на пин 2:

  • установи для пина 2 значение INPUT_PULLUP
  • пока горит зелёный свет, нажатие сразу завершает его (загорается жёлтый свет)
  • жёлтый и красный свет горят положенное время независимо от нажатия

Нажми Run, дождись зелёного света, нажми синюю кнопку, затем Check.

Попробуйте сами

// Светофор для автомобилей
const int redPin = 12;
const int yellowPin = 11;
const int greenPin = 10;
// Собственный светодиод платы: индикатор состояния контроллера
const int statusPin = 13;

enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0;  // когда загорелся текущий сигнал светофора

bool statusOn = false;
unsigned long lastBlink = 0;

// Включить один сигнал светофора и выключить два других.
void showLight(int pin) {
  digitalWrite(redPin, LOW);
  digitalWrite(yellowPin, LOW);
  digitalWrite(greenPin, LOW);
  digitalWrite(pin, HIGH);
}

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(statusPin, OUTPUT);
  showLight(greenPin);
}

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

  switch (light) {
    case GREEN:
      if (now - lightStart >= 3000) {
        light = YELLOW;
        lightStart = now;
        showLight(yellowPin);
      }
      break;
    case YELLOW:
      if (now - lightStart >= 1000) {
        light = RED;
        lightStart = now;
        showLight(redPin);
      }
      break;
    case RED:
      if (now - lightStart >= 3000) {
        light = GREEN;
        lightStart = now;
        showLight(greenPin);
      }
      break;
  }

  // Индикатор состояния мигает каждые 500 мс независимо от работы светофора.
  if (now - lastBlink >= 500) {
    lastBlink = now;
    if (statusOn) {
      statusOn = false;
      digitalWrite(statusPin, LOW);
    } else {
      statusOn = true;
      digitalWrite(statusPin, HIGH);
    }
  }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Проекты

Потренируйтесь самостоятельно: Песочница Arduino