Школьный звонок на .NET Micro Framework с удаленным управлением

в 12:39, , рубрики: arduino, diy или сделай сам, программирование микроконтроллеров

Пост раскрывает реализацию подачи школьного звонка с использованием отладочной платы 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:
image

  • 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 давно снята с производства, поэтому ниже ближайшие аналоги

Схема подключения
image

Фото устройства:

Вид сверху
image
Связка Fez Domino, Ethernet Shield, I/O Expansion Shield, в режиме стека
image
image

Запуск устройства
При запуске устанавливается 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

Видео:

Скриншоты:

image
image
image

Код:
FEZ_Domino_Zvonok.zip

Автор: devzona

Источник


  1. Денис:

    а на чем вы писали код?

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js