Школьный звонок на .NET Micro Framework с удаленным управлением
Пост раскрывает реализацию подачи школьного звонка с использованием отладочной платы FEZ Domino. Управление расписанием осуществляется через веб-страницу. На FEZ Domino портирована платформа .NET Micro Framework. Язык программирования C#. Предистория поста такова…Хабровчан prostosergik опубликовал пост Новогодняя малина — прикручиваем экран HD44780 к Raspberry Pi. В комментариях между мною и prostosergik завязался спор о целесообразности использования для этих задач Raspberry Pi. prostosergik в комментариях сообщил о уже готовом проекте школьного звонка на Raspberry Pi.Позже был опубликован пост Школьный звонок на Raspberry Pi с удаленным управлением. Теперь настала моя очередь в реализации этой задачи.По итогу переписки сформировал следующее ТЗ: Цель: включать звонок в соответствии с расписанием школьных звонков в учебном заведениеМеханизм работы: звонок подается в соответствие с поданным сигналом »1» на контактном реле. При замыкания реле, звенит звонок.ТребованияВозможность изменения расписания звонков через Web-интерфейс Синхронизация времени с NTP сервером с сети Интернет Наличие кнопка сброса к «заводским» настройкам Время подачи звонка не изменяется, и всегда 5 секунд Безопасность. Задание списка IP адресов, с которых возможно управление системой. Авторизация по логин/пароль (не было реализовано, но технически возможно) Время расписание звонков на каждый рабочий день, одинаково Кнопка подачи звонка в любое время РеализацияСразу скажу, из-за технический ограничений на Arduino UNO R3, не удалось реализовать этот проект в полной мере.При выборе контроллера руководствовался следующими правиламиArduino-совместимый по шилдам и методологии работы. Отсутствие Linux в любом проявление Доступная цена Не для сегмента промышленности В заголовке не упоминается FEZ Domino, не случайно. Программный код между микроконтроллерами работающие на .NET Micro Framework, практически без изменений переносим всегда, при соблюдение версии. В данном случае FEZ Domino легко заменяется на плату NET Duino Plus 2, без ущерба в функциональности.Список используемых компонентов:
Отладочная плата FEZ Domino или аналог по характеристикам Реле — для подачи звонка Светодиод — загорается в момент подачи звонка Кнопка — для сброса к заводским настройкам Кнопка — ручной подачи звонка LCD двухстрочный — отображение служебной информации SD-карта — на 8 Гб Шилд подключения — подключения кнопок, LCD, реле, LED Ethernet Shield — локальная сеть Все компоненты можно врассыпную купить на Aliexpress.com, будет существенно дешевле.Спецификация FEZ Domino: Arduino совместимые контакты с Arduino 72Mhz 32-bit ARM7 LPC2388 процессор USBizi-144 Chipset ~148KB доступной памяти Flash ~62KB доступной памяти RAM Порт USB Host (USB-разветвители, джойстик, клавиатура, мышь, принтер, CDC, виртуальный последовательный интерфейс и т.д.) Порт USB client (для отладки, выборочно для эмуляции клавиатуры, мыши или CDC) Поддержка карт памяти microSD (SDHC support, 4-bit SD Bus, поддержка более 2GB, успешно использовалась microSDHC 8 GB class 10 Transcend) RTC realtime clock — часы реального времени Поддержка TCP/IP используя Ethernet shield (WIZnet W5100 chip) 30 программируемых IOs К сожалению FEZ Domino давно снята с производства, поэтому ниже ближайшие аналогиСхема подключенияФото устройства: Вид сверхуСвязка Fez Domino, Ethernet Shield, I/O Expansion Shield, в режиме стека Запуск устройстваПри запуске устанавливается WatchDog на 20 секунда, в случае зависание устройства. //Enable Watchdog GHI_LowLevel.Watchdog.Enable (1000×20); Сброс счётчика осуществляется GHI_LowLevel.Watchdog.ResetCounter (); Инициализация прерываний на кнопки //Кнопка подачи звонка в ручном режиме FEZ_Components.Button Button_ManualCall = new FEZ_Components.Button (FEZ_Pin.Interrupt.Di5); //Кнопка аппаратного сброса и перезагрузки FEZ_Components.Button Button_HardReset = new FEZ_Components.Button (FEZ_Pin.Interrupt.Di6); // установление прерывания на кнопку Button_ManualCall.ButtonPressEvent += new FEZ_Components.Button.ButtonPressEventHandler (Button_ManualCall_ButtonPressEvent); // установление прерывания на кнопку Button_HardReset.ButtonPressEvent += new FEZ_Components.Button.ButtonPressEventHandler (Button_HardReset_ButtonPressEvent); Затем устанавливается ждущий режим на 5 с для сброса настроек по умолчанию. Горит светодиод и высвечивается надпись на экране «Starting …».Чтение настроек с SD карты памяти //загрузка настроек appset = new AppSettings (); appset.ReadSettings (); Инициализация сети netinter = new netinteface (); Чтение времени из RTC. RTC интегрирован в чип. Для обеспечения хода часов необходимо подключит батарейку v3.3 к контактам Utility.SetLocalTime (RealTimeClock.GetTime ()); Запуск потока синхронизации времени с NTP сервером. Интервал синхронизации задается в настройках. Thread ThreadUpdateTimeNTP = new Thread (UpdateTimeNTPThread); ThreadUpdateTimeNTP.Start (); Запуск потока подачи звонка. Сопоставляет текущее время и время звонков. В случае совпадения подает звонок. Thread ThreadTimeBells = new Thread (TimeBells); ThreadTimeBells.Start (); Запуск Web сервера Webserver server = new Webserver (); подготовка массива для передачи. Небольшой велосипед для экономии памяти string[] confstr = {appset.SyncTimeDelayMin.ToString (), appset.CurTimeBell[0].ToString («HH: mm»), … appset.CurTimeBell[7].ToString («HH: mm»)}; server.StartServer (confstr); Особенности реализацииОт Arduino UNO пришлось практически сразу отказаться по следующим причинам: Одновременно не поддерживается работа с сетью и SD картой. Есть реализация у ladyada Arduino Ethernet+SD, но к у меня не получилось запустить.Arduino поддерживает два параллельных потока или два прерывания.В моей реализации получилось 4 потока: прерывание на кнопку для ручной подачи звонка, синхронизация с NTP сервером, поток отслеживания времени подачи звонка, поток обслуживания http сервера. Для Arduino UNO это слишком много.По сравнению с проектом на Raspberry pi, простота реализации поддержки Watchdog.К сожалению, не работает отслеживание состояния Ethernet кабеля. При отключение кабеля, необходимо проводить инициализацию сети. Как вариант решения этой проблему периодически опрашивать ping какой ни будь узел в сети. В случает отсутствия ответа, заново инициализировать сеть. Но это недоработка CLR для микроконтроллера FEZ Domino.Отслеживание времени звонка осуществляется с секундной точность. Поэтому, для того что бы звонок не проскочил, сохраняется предыдущее время и новое. Если время звонка попадает в этот интервал, звенит звонок. Процедура засыпает на 1 секунду, но так же еще тратится время на выполнение самой процедуры, поэтому и был сделан интервал. public static void TimeBells () { string NowLocalTime = »; DateTime NewTime; DateTime OldTime = DateTime.Now.ToLocalTime (); OpredCallZvon ocz; while (true) { //текущее время NewTime = DateTime.Now.ToLocalTime (); //отображение текущего времени NowLocalTime = NewTime.ToString («HH: mm: ss»); //проверка подачи звонка foreach (DateTime dt in appset.CurTimeBell) { ocz=new OpredCallZvon (NewTime, OldTime, dt); if (ocz.isCall) { LCD.setCursor (0, 1); LCD.print («NOW ZVONOK »); RunBell (); } } OldTime = NewTime; Thread.Sleep (1000); } } В момент подачи звонка горит светодиод.RTC встроен. Достаточно подвести питание на пины VBAT IN и Ground.Для упрощения шаблоны html страниц были помещены в ресурсы к проекту.Использовались библиотеки: На реализацию ушло 3 дня x 4 часа = 12 человеко-часов.Иногда при http запросах получалось исключение о превышение оперативной памяти (~62KB). Из-за этого пришлось применять новые настройки только при перезагрузке, не в оперативном режиме.Смета расходов№ Название кол-во цена Сумма, $ 1 Netduino Plus 2 1 59,95 59,95 2 Relay Module 1 1,74 1,74 3 RGB 3 Color Full Color LED любой цвет 1 1,99 1,99 4 Standard Button Switch Sensor Module 2 1,29 2,58 5 LCD module Blue screen IIC/I2C 2004 5V 1 7,6 7,6 6 Карта памяти MicroSD 1 3,14 3,14 7 Основа для монтажа, провода 1 10 10 ИТОГО 87 Видео:[embedded content]Скриншоты:
Код: FEZ_Domino_Zvonok.zip