Х-образный, с секциями поворотов

Общие положения

Движение на Х-образном перекрёстке регулируется светофором, в данном случае — с дополнительными секциями. Вы можете почитать подробнее информацию о сборке светофора, его настройке, особенностях питания, и настройке расстояния передачи ИК-сигнала.

Схема установки знака на трассе:

В данном случае светофор имеет дополнительные секции.

Центр светофора должен находиться в 15см от линии трассы, образующих перекрёсток, а сам светофор располагаться под углом 45° относительно линии движения автомобиля.

Угол распространения ИК данных составляет около 80°, а дальность передачи ИК данных настраивается поворотом крестовины резистора на обратной стороне платы основания.

Алгоритм работы светофора

Алгоритм работы светофоров:

Движение на данном перекрёстке в любых направлениях можно организовать за 4 фазы работы светофоров, но мы предлагаем алгоритм при котором светофоры работают за 8 фаз. В предложенном алгоритме каждый светофор разрешает движение: только прямо, только вправо, прямо и налево, во всех направлениях.

Для удобства описания работы, назовём левую часть дороги — "A", нижнюю — "B", правую — "C", верхнюю — "D". Тогда светофоры перекрёстка разрешают движение следующим образом:

  • В 1 фазе: между дорогами "A" и "B" в обоих направлениях, дополнительно от "B" к "C" и "D".
  • В 8 фазе: между дорогами "B" и "C" в обоих направлениях, дополнительно от "C" к "A" и "D".
  • В 4 фазе: между дорогами "C" и "D" в обоих направлениях, дополнительно от "D" к "A" и "B".
  • В 5 фазе: между дорогами "D" и "A" в обоих направлениях, дополнительно от "A" к "B" и "C".
  • В 6 фазе: между дорогами "A" и "C" в обоих направлениях, дополнительно от "A" к "B".
  • В 7 фазе: между дорогами "A" и "C" в обоих направлениях, дополнительно от "C" к "D".
  • В 2 фазе: между дорогами "B" и "D" в обоих направлениях, дополнительно от "B" к "C".
  • В 3 фазе: между дорогами "B" и "D" в обоих направлениях, дополнительно от "D" к "A".

Реализуется данный алгоритм следующим образом:

  • 1 фаза:
    • У светофора 0x0A светится красный сигнал и стрелка направо.
    • У светофора 0x0B светится зелёный сигнал и обе стрелки.
    • У светофоров 0x0C и 0x0D светится красный сигнал.
  • 2 фаза:
    • У светофора 0x0B светится зелёный сигнал и стрелка влево.
    • У светофора 0x0D светится зелёный сигнал.
    • У светофоров 0x0A и 0x0C светится красный сигнал.
  • 3 фаза:
    • У светофора 0x0B светится зелёный сигнал.
    • У светофора 0x0D светится зелёный сигнал и стрелка направо.
    • У светофоров 0x0A и 0x0C светится красный сигнал.
  • 4 фаза:
    • У светофора 0x0C светится красный сигнал и стрелка направо
    • У светофора 0x0D светится зелёный сигнал и обе стрелки.
    • У светофоров 0x0A и 0x0B светится красный сигнал.
  • 5 фаза:
    • Светофор 0x0A повторяет сигналы светофора 0x0D для 1 фазы.
    • Светофор 0x0B повторяет сигналы светофора 0x0A для 1 фазы.
    • Светофор 0x0C повторяет сигналы светофора 0x0B для 1 фазы.
    • Светофор 0x0D повторяет сигналы светофора 0x0C для 1 фазы.
  • 6 фаза:
    • Светофор 0x0A повторяет сигналы светофора 0x0D для 2 фазы.
    • Светофор 0x0B повторяет сигналы светофора 0x0A для 2 фазы.
    • Светофор 0x0C повторяет сигналы светофора 0x0B для 2 фазы.
    • Светофор 0x0D повторяет сигналы светофора 0x0C для 2 фазы.
  • 7 фаза:
    • Светофор 0x0A повторяет сигналы светофора 0x0D для 3 фазы.
    • Светофор 0x0B повторяет сигналы светофора 0x0A для 3 фазы.
    • Светофор 0x0C повторяет сигналы светофора 0x0B для 3 фазы.
    • Светофор 0x0D повторяет сигналы светофора 0x0C для 3 фазы.
  • 8 фаза:
    • Светофор 0x0A повторяет сигналы светофора 0x0D для 4 фазы.
    • Светофор 0x0B повторяет сигналы светофора 0x0A для 4 фазы.
    • Светофор 0x0C повторяет сигналы светофора 0x0B для 4 фазы.
    • Светофор 0x0D повторяет сигналы светофора 0x0C для 4 фазы.

Подробнее о переключении от зелёного к красному и от красного к зелёному Вы можете почитать по ссылке.

Адресация на шине I2C

Мы уже говорили о том, что все наши знаки и светофоры являются устройствами, работающими по шине I2C. Это значит, что они подключаются параллельно к одной шине и для того, чтобы они могли взаимодействовать с контроллером, каждое устройство должно иметь свой уникальный адрес в пределах этой шины. Поэтому, при подключении двух и более устройств необходимо убедиться, что они имеют разные адреса.

Смена адреса устройства

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

Установите светофорам адреса 0x0A, 0x0B, 0x0C, 0x0D.

Для установки адресов воспользуйтесь скетчем из меню Arduino IDE:
Файл / Примеры / iarduino I2C Track (модуль трассы) / NewAddress

Схема включения

После установки адресов I2C для каждого светофора, соедините их с помощью I2C Hub'а и подключите к контроллеру. Подробнее о питании контроллера и светофоров Вы можете почитать в статье.

Скетч 

#include <iarduino_I2C_Track.h>         // Подключаем библиотеку для работы с модулем трассы.
iarduino_I2C_Track tl_A(0x0A);          // Создаём объект tl_A для работы с 1 светофором, указав его адрес на шине I2C (0x0A).
iarduino_I2C_Track tl_B(0x0B);          // Создаём объект tl_B для работы с 2 светофором, указав его адрес на шине I2C (0x0B).
iarduino_I2C_Track tl_C(0x0C);          // Создаём объект tl_C для работы с 3 светофором, указав его адрес на шине I2C (0x0C).
iarduino_I2C_Track tl_D(0x0D);          // Создаём объект tl_D для работы с 4 светофором, указав его адрес на шине I2C (0x0D).
                                        //
void setup(){                           //
     tl_A.begin(MODUL_TLIGHT, TRACK_LFR, SECTION_LR); // Инициируем работу с 4 светофорами,
     tl_B.begin(MODUL_TLIGHT, TRACK_LFR, SECTION_LR); // указав что на перекрёстках есть дорога
     tl_C.begin(MODUL_TLIGHT, TRACK_LFR, SECTION_LR); // влево, прямо и направо (TRACK_LFR), и каждый
     tl_D.begin(MODUL_TLIGHT, TRACK_LFR, SECTION_LR); // светофор оснащён стрелками влево, и вправо (SECTION_LR).
     tl_A.irProtocol(IR_IARDUINO);      // Указываем протокол передачи данных по ИК-каналу: "IARDUINO".
     tl_B.irProtocol(IR_IARDUINO);      // Указываем протокол передачи данных по ИК-каналу: "IARDUINO".
     tl_C.irProtocol(IR_IARDUINO);      // Указываем протокол передачи данных по ИК-каналу: "IARDUINO".
     tl_D.irProtocol(IR_IARDUINO);      // Указываем протокол передачи данных по ИК-каналу: "IARDUINO".
     tl_A.irAutoSend();                 // Указываем модулю постоянно отправлять информацию о состоянии светофора по ИК-каналу с интервалами по умолчанию ±50%.
     tl_B.irAutoSend();                 // Указываем модулю постоянно отправлять информацию о состоянии светофора по ИК-каналу с интервалами по умолчанию ±50%.
     tl_C.irAutoSend();                 // Указываем модулю постоянно отправлять информацию о состоянии светофора по ИК-каналу с интервалами по умолчанию ±50%.
     tl_D.irAutoSend();                 // Указываем модулю постоянно отправлять информацию о состоянии светофора по ИК-каналу с интервалами по умолчанию ±50%.
     tl_A.timing(3);                    // Указываем время свечения жёлтого (и мигающего зелёного) сигнала светофора = 3сек.
     tl_B.timing(3);                    // Указываем время свечения жёлтого (и мигающего зелёного) сигнала светофора = 3сек.
     tl_C.timing(3);                    // Указываем время свечения жёлтого (и мигающего зелёного) сигнала светофора = 3сек.
     tl_D.timing(3);                    // Указываем время свечения жёлтого (и мигающего зелёного) сигнала светофора = 3сек.
//   Определяем начальное состояние:    //
     tl_A.set(TL_FORWARD_OFF);          // Запрещаем движение прямо на светофоре "A".
     tl_B.set(TL_FORWARD_OFF, TL_RIGHT_ON); // Запрещаем движение прямо на светофоре "B", но разрешаем поворот вправо.
     tl_D.set(TL_FORWARD_OFF);          // Запрещаем движение прямо на светофоре "D".
}                                       //
                                        //
void loop(){                            //
//   ================================== // =============================================================================
//   Фаза 1:                            // Было:   "A" X-X-X , "B" X-X-> , "C" <-^-> , "D" X-X-X.
                                        // Станет: "A" X-X-> , "B" <-^-> , "C" X-X-X , "D" X-X-X.
                                        // Нужно:  "A"-включить стрелку направо, "B"-переключить на зелёный и включить стрелку налево, "C"-переключить на красный и отключить обе стрелки, "D"-оставить без изменений.
//   ----------------1----------------- //
     tl_C.set(TL_FORWARD_OFF, TL_LEFT_OFF, TL_RIGHT_OFF); // Запрещаем движение в прямом направлении и оба поворота на светофоре "C".
     delay(3000);                       // В течении 3 секунд на светофоре "C" будут мигать отключаемые стрелки и основной зелёный.
//   ----------------2----------------- //
     tl_B.set(TL_FORWARD_ON );          // Разрешаем движение в прямом направлении светофора "B".
     delay(3000);                       // В течении 3 секунд на светофоре "B" будет светиться красный с жёлтым.
//   ----------------3----------------- //
     tl_A.set(TL_RIGHT_ON);             // Разрешаем поворот вправо на светофоре "A". Стрелка включается сразу.
     tl_B.set(TL_LEFT_ON);              // Разрешаем поворот влево на светофоре "B". Стрелка включается сразу.
     delay(10000);                      // Ждём 10 секунд пока едут машины.
//   ================================== // =============================================================================
//   Фаза 2:                            // Было:   "A" X-X-> , "B" <-^-> , "C" X-X-X , "D" X-X-X.
                                        // Станет: "A" X-X-X , "B" X-^-> , "C" X-X-X , "D" X-^-X.
                                        // Нужно:  "A"-отключить стрелку направо, "B"-отключить стрелку налево, "C"-оставить без изменений, "D"-переключить на зелёный.
//   ----------------1----------------- //
     tl_A.set(TL_RIGHT_OFF);            // Запрещаем поворот вправо на светофоре "A".
     tl_B.set(TL_LEFT_OFF);             // Запрещаем поворот влево  на светофоре "B".
     delay(3000);                       // В течении 3 секунд на светофорах "A" и "B" будут мигать отключаемые стрелки.
//   ----------------2----------------- //
     tl_D.set(TL_FORWARD_ON );          // Разрешаем движение в прямом направлении светофора "D".
     delay(3000);                       // В течении 3 секунд на светофоре "D" будет светиться красный с жёлтым.
//   ----------------3----------------- //
     delay(10000);                      // Ждём 10 секунд пока едут машины.
//   ================================== // =============================================================================
//   Фаза 3:                            // Было:   "A" X-X-X , "B" X-^-> , "C" X-X-X , "D" X-^-X.
                                        // Станет: "A" X-X-X , "B" X-^-X , "C" X-X-X , "D" X-^->.
                                        // Нужно:  "A"-оставить без изменений, "B"-отключить стрелку направо, "C"-оставить без изменений, "D"-включить стрелку направо.
//   ----------------1----------------- //
     tl_B.set(TL_RIGHT_OFF);            // Запрещаем поворот вправо на светофоре "B".
     delay(3000);                       // В течении 3 секунд на светофоре "B" будет мигать отключаемая стрелка.
//   ----------------2----------------- //
     delay(3000);                       // В данной фазе нет переключений светофоров на разрешающий сигнал в прямом направлении.
//   ----------------3----------------- //
     tl_D.set(TL_RIGHT_ON);             // Разрешаем поворот вправо на светофоре "D". Стрелка включается сразу.
     delay(10000);                      // Ждём 10 секунд пока едут машины.
//   ================================== // =============================================================================
//   Фаза 4:                            // Было:   "A" X-X-X , "B" X-^-X , "C" X-X-X , "D" X-^->.
                                        // Станет: "A" X-X-X , "B" X-X-X , "C" X-X-> , "D" <-^->.
                                        // Нужно:  "A"-оставить без изменений, "B"-переключить на красный, "C"-включить стрелку направо, "D"-включить стрелку налево.
//   ----------------1----------------- //
     tl_B.set(TL_FORWARD_OFF);          // Запрещаем движение в прямом направлении на светофоре "B".
     delay(3000);                       // В течении 3 секунд на светофоре "B" будет мигать зелёный.
//   ----------------2----------------- //
     delay(3000);                       // В данной фазе нет переключений светофоров на разрешающий сигнал в прямом направлении.
//   ----------------3----------------- //
     tl_C.set(TL_RIGHT_ON);             // Разрешаем поворот вправо на светофоре "C". Стрелка включается сразу.
     tl_D.set(TL_LEFT_ON);              // Разрешаем поворот влево на светофоре "D". Стрелка включается сразу.
     delay(10000);                      // Ждём 10 секунд пока едут машины.
//   ================================== // =============================================================================
//   Фаза 5:                            // Было:   "A" X-X-X , "B" X-X-X , "C" X-X-> , "D" <-^->.
                                        // Станет: "A" <-^-> , "B" X-X-X , "C" X-X-X , "D" X-X->.
                                        // Нужно:  "A"-переключить на зелёный и включить обе стрелки, "B"-оставить без изменений, "C"-отключить стрелку направо, "D"-переключить на красный и отключить стрелку налево.
//   ----------------1----------------- //
     tl_C.set(TL_RIGHT_OFF);            // Запрещаем поворот направо на светофоре "C".
     tl_D.set(TL_FORWARD_OFF, TL_LEFT_OFF); // Запрещаем движение в прямом направлении и поворот влево на светофоре "D".
     delay(3000);                       // В течении 3 секунд на светофорах "C" и "D" будут мигать отключаемые зелёные сигналы.
//   ----------------2----------------- //
     tl_A.set(TL_FORWARD_ON );          // Разрешаем движение в прямом направлении светофора "A".
     delay(3000);                       // В течении 3 секунд на светофоре "A" будет светиться красный с жёлтым.
//   ----------------3----------------- //
     tl_A.set(TL_LEFT_ON, TL_RIGHT_ON); // Разрешаем повороты влево и вправо на светофоре "A". Стрелки включатся сразу.
     delay(10000);                      // Ждём 10 секунд пока едут машины.
//   ================================== // =============================================================================
//   Фаза 6:                            // Было:   "A" <-^-> , "B" X-X-X , "C" X-X-X , "D" X-X->.
                                        // Станет: "A" X-^-> , "B" X-X-X , "C" X-^-X , "D" X-X-X.
                                        // Нужно:  "A"-отключить стрелку налево, "B"-оставить без изменений, "C"-переключить на зелёный, "D"-отключить стрелку направо.
//   ----------------1----------------- //
     tl_A.set(TL_LEFT_OFF);             // Запрещаем поворот влево  на светофоре "A".
     tl_D.set(TL_RIGHT_OFF);            // Запрещаем поворот вправо на светофоре "D".
     delay(3000);                       // В течении 3 секунд на светофорах "A" и "D" будут мигать отключаемые стрелки.
//   ----------------2----------------- //
     tl_C.set(TL_FORWARD_ON );          // Разрешаем движение в прямом направлении светофора "C".
     delay(3000);                       // В течении 3 секунд на светофоре "C" будет светиться красный с жёлтым.
//   ----------------3----------------- //
     delay(10000);                      // Ждём 10 секунд пока едут машины.
//   ================================== // =============================================================================
//   Фаза 7:                            // Было:   "A" X-^-> , "B" X-X-X , "C" X-^-X , "D" X-X-X.
                                        // Станет: "A" X-^-X , "B" X-X-X , "C" X-^-> , "D" X-X-X
                                        // Нужно:  "A"-отключить стрелку направо, "B"-оставить без изменений, "C"-включить стрелку направо, "D"-оставить без изменений.
//   ----------------1----------------- //
     tl_A.set(TL_RIGHT_OFF);            // Запрещаем поворот вправо на светофоре "A".
     delay(3000);                       // В течении 3 секунд на светофоре "A" будет мигать отключаемая стрелка.
//   ----------------2----------------- //
     delay(3000);                       // В данной фазе нет переключений светофоров на разрешающий сигнал в прямом направлении.
//   ----------------3----------------- //
     tl_C.set(TL_RIGHT_ON);             // Разрешаем поворот вправо на светофоре "C". Стрелка включается сразу.
     delay(10000);                      // Ждём 10 секунд пока едут машины.
//   ================================== // =============================================================================
//   Фаза 8:                            // Было:   "A" X-^-X , "B" X-X-X , "C" X-^-> , "D" X-X-X
                                        // Станет: "A" X-X-X , "B" X-X-> , "C" <-^-> , "D" X-X-X
                                        // Нужно:  "A"-переключить на красный, "B"-включить стрелку направо, "C"-включить стрелку налево, "D"-оставить без изменений
//   ----------------1----------------- //
     tl_A.set(TL_FORWARD_OFF);          // Запрещаем движение в прямом направлении на светофоре "A".
     delay(3000);                       // В течении 3 секунд на светофоре "A" будет мигать зелёный.
//   ----------------2----------------- //
     delay(3000);                       // В данной фазе нет переключений светофоров на разрешающий сигнал в прямом направлении.
//   ----------------3----------------- //
     tl_B.set(TL_RIGHT_ON);             // Разрешаем поворот вправо на светофоре "B". Стрелка включается сразу.
     tl_C.set(TL_LEFT_ON);              // Разрешаем поворот влево на светофоре "C". Стрелка включается сразу.
     delay(10000);                      // Ждём 10 секунд пока едут машины.
//   ================================== // =============================================================================
}                                       //

В коде setup() выполняются следующие действия:

  • Обращением к функции begin() мы указываем что каждый модуль является светофором MODUL_TLIGHT, который регулирует перекрёсток с дорогами влево, прямо и направо TRACK_LFR и оснащён двумя секциями поворотов SECTION_LR.
  • Обращением к функции irProtocol() мы указываем ИК-протокол передачи данных. В скетче используется IR_IARDUINO.
  • Обращением к функции irAutoSend() мы заставляем модуль самостоятельно постоянно отправлять данные о состоянии светофора по ИК-каналу.
  • Обращением к функции timing() мы указали длительность свечения жёлтого и мигающего зелёного равной 3 секундам. Это требуется так как в полуавтоматическом режиме модуль включает эти цвета без нашего участия.
  • В конце кода setup() выполнено обращение к функции set() для установки цветов необходимых для корректной работы цикла loop() при его первом проходе.

Код loop() разделён на 8 фаз в которых выполняются по 3 действия:

  • Действие №1 — запрет движения для любых направлений:
    • Вызов функции set() для светофоров которым требуется запретить движение прямо TL_FORWARD_OFF, влево TL_LEFT_OFF, вправо TL_RIGHT_OFF.
    • Задержка delay() на время свечения мигающего зелёного сигнала.
  • Действие №2 — разрешение движения в прямом направлении:
    • Вызов функции set() для светофоров которым требуется разрешить движение прямо TL_FORWARD_ON.
    • Задержка delay() на время свечения жёлтого сигнала.
  • Действие №3 — включение секций поворотов:
    • Вызов функции set() для светофоров которым требуется разрешить движение влево TL_LEFT_ON, вправо TL_RIGHT_ON(стрелки поворотов включаются сразу, без задержек).
  • После выполнения всех действий, на светофорах перекрёстка установлены требуемые сигналы. Осталось приостановить выполнение скетча функцией delay() на желаемую длительность текущей фазы движения машин.

Обратите внимание на то, что в 3,4,7,8 фазах нет команд на разрешение движения в прямом направлении, но задержка delay() осталась. Благодаря этой задержке выполняется сразу два условия: Запрет движения влево и вправо завершится за 1 цикл свечения жёлтого сигнала до того как осуществится включение других секций поворотов. Включение секций поворотов совпадёт с включением красного или основного зелёного сигналов светофоров.

Ну что же, поздравляем!
Вы освоили основы программирования, выполнили множество упражнений и проектов. Не стесняйтесь возвращаться к предыдущим урокам, если что-нибудь забыли. А мы предлагаем двигаться дальше и переходить к следующей главе.
перейти к выбору главы

Продукт в магазине

Светофор

В магазин

Обсуждение

Гарантии и возврат. Используя сайт, Вы соглашаетесь с условиями.