Загрузка данных
// =====================================================
// СВЕТОФОР ДЛЯ МАШИН
// =====================================================
const int LED_RED = 13;
const int LED_YELLOW = 12;
const int LED_GREEN = 11;
// =====================================================
// СВЕТОФОР ДЛЯ ПЕШЕХОДОВ
// =====================================================
const int PED_RED = 10;
const int PED_GREEN = 9;
// =====================================================
// УЛЬТРАЗВУКОВОЙ ДАТЧИК HC-SR04
// =====================================================
const int TRIG_PIN = 7;
const int ECHO_PIN = 6;
// Расстояние, на котором срабатывает датчик
const int DETECT_DISTANCE = 20; // сантиметры
// =====================================================
// ВРЕМЕНА
// =====================================================
// Желтый для машин
const int TIMEOUT_YELLOW = 1690;
// Мигание зеленого машин
const int TIMEOUT_FLASH_GREEN = 500;
// Сколько времени пешеходам горит зеленый
const int TIMEOUT_PEDESTRIAN = 5000;
// Небольшая пауза безопасности
const int SAFETY_DELAY = 500;
// Флаг.
// true = датчик может запустить светофор
// false = уже срабатывал, ждем пока человек уберет руку
bool sensorReady = true;
// =====================================================
// SETUP
// =====================================================
void setup()
{
// Светофор машин
pinMode(LED_RED, OUTPUT);
pinMode(LED_YELLOW, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
// Светофор пешеходов
pinMode(PED_RED, OUTPUT);
pinMode(PED_GREEN, OUTPUT);
// HC-SR04
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
// Начальное состояние:
// машинам зеленый
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_RED, LOW);
// пешеходам красный
digitalWrite(PED_RED, HIGH);
digitalWrite(PED_GREEN, LOW);
}
// =====================================================
// ФУНКЦИЯ ИЗМЕРЕНИЯ РАССТОЯНИЯ
// =====================================================
float getDistance()
{
// На всякий случай выключаем TRIG
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
// Посылаем импульс 10 микросекунд
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Измеряем время возвращения сигнала
// 30000 мкс - максимальное время ожидания
long duration = pulseIn(ECHO_PIN, HIGH, 30000);
// Если отражение не получено
if (duration == 0)
{
return 999;
}
// Переводим время в сантиметры
float distance = duration * 0.0343 / 2.0;
return distance;
}
// =====================================================
// ПЕРЕКЛЮЧЕНИЕ НА ПЕШЕХОДНЫЙ ЗЕЛЕНЫЙ
// =====================================================
void pedestrianCycle()
{
// ---------------------------------------------------
// 1. Машинам мигает зеленый
// ---------------------------------------------------
for (int i = 0; i < 3; i++)
{
digitalWrite(LED_GREEN, LOW);
delay(TIMEOUT_FLASH_GREEN);
digitalWrite(LED_GREEN, HIGH);
delay(TIMEOUT_FLASH_GREEN);
}
// ---------------------------------------------------
// 2. Выключаем зеленый машин
// Включаем желтый
// ---------------------------------------------------
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_YELLOW, HIGH);
delay(TIMEOUT_YELLOW);
digitalWrite(LED_YELLOW, LOW);
// ---------------------------------------------------
// 3. Машинам красный
// ---------------------------------------------------
digitalWrite(LED_RED, HIGH);
// Пешеходам пока еще красный
delay(SAFETY_DELAY);
// ---------------------------------------------------
// 4. Пешеходам зеленый
// ---------------------------------------------------
digitalWrite(PED_RED, LOW);
digitalWrite(PED_GREEN, HIGH);
delay(TIMEOUT_PEDESTRIAN);
// ---------------------------------------------------
// 5. Пешеходам снова красный
// ---------------------------------------------------
digitalWrite(PED_GREEN, LOW);
digitalWrite(PED_RED, HIGH);
delay(SAFETY_DELAY);
// ---------------------------------------------------
// 6. Машинам красный + желтый
// ---------------------------------------------------
digitalWrite(LED_YELLOW, HIGH);
delay(TIMEOUT_YELLOW);
// ---------------------------------------------------
// 7. Машинам снова зеленый
// ---------------------------------------------------
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_RED, LOW);
digitalWrite(LED_GREEN, HIGH);
}
// =====================================================
// LOOP
// =====================================================
void loop()
{
float distance = getDistance();
// Если датчик готов и объект ближе 20 см
if (sensorReady &&
distance > 2 &&
distance <= DETECT_DISTANCE)
{
// Запрещаем повторное срабатывание
sensorReady = false;
// Запускаем цикл светофора
pedestrianCycle();
}
// Чтобы светофор снова мог сработать,
// необходимо убрать руку от датчика.
//
// Используем 25 см вместо 20,
// чтобы датчик не дергался на границе.
if (!sensorReady && distance > 25)
{
sensorReady = true;
}
// Измеряем примерно 10 раз в секунду
delay(100);
}