Об управлении ярусной автостоянкой.

22.02.2012
Скайнет, начало30Кб памяти, 12 цифровых и 6 аналоговых выходов - этого вполне достаточно для управления въездами-выездами трехярусной автостоянки.

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

Итак, автостоянка. Главные ворота, светофоры, карточка-электронный ключ. На внутренних этажах шлагбаумов нет. Как набор устройств ввода-вывода рассматриваемая автостоянка это:
  1. набор из трех датчиков проезда - по одному на этаж
  2. устройство авторизации на въезде - "карточка"
  3. светофоры - по одному на выезде с этажей и над главными воротами
Пусть также имеется звуковая сигнализация тревоги на этажах - в отсутствии шлагбаумов имеет смысл подавать сигнал тревоги при попытке проезда на красный. При этом, датчики проезда состоят из двух контуров. Замыкание одного контура дает только предположение о движении автомобиля. Факт движения устанавливается, когда замыкаются оба контура - считается, что автомобиль может это сделать, а пешеход ни за что. Датчик проезда фиксирует направление движения.

Вышеописанная модель говорит о том, что нам потребуется 7 цифровых входов для приема сигналов датчиков (детекторы проезда + карточка) и 5 выходов (три светофора и сигнализации на внутренних ярусах). Сигнализацию на главных воротах ставить большого смысла нет.

Зная это, осталось написать программу микроконтроллера, которая бы корректно передавала реакцию на выходы по ситуации на входах.

В ходе работы над этой задачей выяснилось несколько особенностей. 
STL для облегчения работы  и упрощения кода я не стал использовать в силу того, что не удалось корректно реализовать оператор new. Версия
void * operator new(size_t size)
не вызывает вопросов. Но для STL (в частности vector) требуется еще и
void * operator new(unsigned int size, void*)
Подозреваю, что у меня сходу не удалось все сделать правильно.
Далее. Хорошо, черт с ним, с STL. Мне требуется только vector. Напишем его сами - при этом не потребуется реализации оператора new. Да, написать не сложно. Но тут я получил быстрое исчерпание памяти. Следовательно нужно экспериментировать со стратегией выделения памяти под вектор. Это не тривиально и требует времени. Будем проще. Пока что. Целочисленные и строковые массивы - остановимся на них.

Еще одна проблема. Внутренний таймер считает миллисекунды от начала работы микроконтроллера. Число этих миллисекунд переполнит максимальное, которое может быть обработано (максимум для unsigned long = 4294967295) примерно через 50 дней. Следовательно, счетчики таймаутов следует реализовывать не опираясь на время микроконтроллера - или вводить в штатный регламент обслуживания системы периодический сброс. Счетчик таймаута можно привязать к периоду вызова основной функции loop. Зная этот период всегда можно узнать, прошел тот или иной промежуток времени - естественно, не произвольный (на практике этой непроизвольностью можно пренебречь).

На этом пока остановимся. Мы обсудили модель реального объекта и некоторые сложности, которые возникают при моделировании процессов на микроконтроллере. Пора спать.