Школьный звонок на .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:
    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) какой нибудь узел(по IP адресу) в сети. В случает отсутствия ответа, заново инициализировать сеть. Но это недоработка 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

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 14

      0
      Безопасность. Задание списка IP адресов, с которых возможно управление системой. Авторизация по логин/пароль(не было реализовано, но технически возможно)


      Вот это не понял. Если я вдруг узнаю IP компа, с которого возможен доступ, есть средства безопасности, которые помешают мне подцепиться к сети и похимичить?
        0
        Это прототип, а не готовое устройство. Вопрос безопасности пропущен, из-за ограниченного личного времени. В данном случае защиту от НСД, можно реализовать старым дедовским способом. Используя форму авторизации. И запись ключа в тело html страницы, поле «hidden».
        Пример:
        input type=«hidden» name=«name» value=«Vasya»
        input type=«hidden» name=«password» value=«pupkin»
          0
          Понял.
          .htaccess?
            0
            Скрытое поле
            .htaccess и web.config, отсутствует.
            Только если самостоятельно реализовать. Еще вариант запись в cookies, но я не проверял реализована ли такая функциональность.
              0
              Это ограничение веб-сервера?
              Тогда понятно.
                0
                Ограничение на уровне реализации net micro framework для FEZ Domino. Если поддержка cookies реализована, то ее можно добавить. Когда потребовалось отслеживать состояние подключение ethernet кабеля, я согласно документации добавил обработчик. На практике оказалось, что не работает. Класс Microsoft.SPOT.Net.NetworkInformation.NetworkChange с примером.
                Событие при подключение/отключение кабеля Ethernet не генерировалось.
                p.s. нашел поддержку авторизации GHIElectronics.NETMF.W5100.Http The Authorization HTTP header. Но это проприетарный модуль. Он недоступен в netduino.
        +5
        Постам с такой грамматикой надо тег «машинный перевод» ставить.
          –3
          Да, ладно. Вы почитайте блог MS. Перевод один-в-один с английского. Приведите конкретные примеры «с такой грамматикой»
            +1
            К сожалению, не работает отслеживание состояния Ethernet кабеля. При отключение кабеля, необходимо проводить инициализацию сети. Как вариант решения этой проблему периодически опрашивать ping какой ни будь узел в сети. В случает отсутствия ответа, заново инициализировать сеть. Но это недоработка CLR для микроконтроллера FEZ Domino.
            Отслеживание времени звонка осуществляется с секундной точность. Поэтому, для того что бы звонок не проскочил, сохраняется предыдущее время и новое. Если время звонка попадает в этот интервал, звенит звонок. Процедура засыпает на 1 секунду, но так же еще тратится время на выполнение самой процедуры, поэтому и был сделан интервал.

            Признавайся, дружище, ты был пьян.
              0
              исправил
          +1
          Спасибо хоть и за слегка запоздалый, но развернутый и полный ответ на мою публикацию. Реализация хороша, хотя, на мой скромный взгляд, имеет свои плюсы и минусы. Попробую перечислить:

          Минусы:
          • Это все-таки не Arduino, как было описано в первоначальной задаче. =) По сути FEZ Domino напоминает Arduino только расположением гребенок контактов.
          • Цена. Не считая мелочевку, FEZ Domino стоит $60, в то время, как Raspberry Pi — порядка $35-$40. Мне в свое время приехал за $35 с доставкой к подъезду, в комплекте уже содержал 8 Gb карту памяти с предустановленной системой. Не принципиально, но…
          • Кажется мне, специалистов по .NET Micro Framework слегка меньше, чем специалистов по Python. Не уверен, что среднестатистический учитель информатики с ходу сможет отредактировать код на .NET Micro Framework
          • Ресурсы «впритык», о чем вы сами напоминаете в статье, в то время, как на Raspberry при желании параллельно можно еще и кино смотреть =)


          Однако, плюсы:
          • Монументально. Если решить проблемы с памятью, есть больше уверенности, что оно будет работать годами без вмешательства, что сервер не зависнит, что Вася из 9-Б не «взломает» звонок и не будет на нем играть музыку из к.ф. Бригада. =)
          • Как ни странно, .NET Micro Framework. Поддерживать код для Ардуино было бы куда как сложнее.


          Как вывод, обе реализации имеют свои плюсы и минусы. Переубедить метя в том, что Linux в звонке это плохо не поучилось, но зато получилось убедить в том, что на простых МК без ОС вполне можно делать серьезные вещи, тем более трузодазтраты на реализацию сравнимы. Но все-таки мне кажется, что в целом имеется тренд пхать Linux в каждый чайник, и навряд ли это уже изменишь. С появлением таких плат, как BlackSwift это становится не только проще, но и банально дешевле. За $25 получаем полноценный Linux + WiFi размером с половину спичечного коробка.
            0
            согласен.
            Добавлю еще плюсы подхода без ОС
            • Дешевле и проще в обслуживание. По причине минимизации используемых компонентов
            • Легче внести изменения в программный код. Вся логика в рамках одного приложения
            • Интерактивная удаленная отладка по Ethernet. Особенность Net micro Framework
            • .NET Micro Framework это урезаная платформа «большого» .NET Framework. Научить специалиста по C# программировать под .NET Micro Framework, недолго. Программистов под C# больше, чем под питон
            • Выше надежность. Отсутствует проблемы с ФС и исключается Linux: Kernel panic

            +1
            А что так дорого? 50 баксов на мк? Тут реально было бы проще на малине реализовать, да и ресурсов на ней больше, хоть голосовое оповещение делай, хоть расписание на телек выводи и рекламу показывай. Было бы желание и Васи из 9б не взломают имхо.
              +1
              Для решения задач учитывается не только стоимость железа, а так же работа инженера. Напрямую тупо сравнивать стоимость МК между собой, не имеет смысла. Если конечно она не отличается в 5-8 раз. Существует такое понятие как совокупная стоимость разработки. Затраты для двух вариантов решений практически совпадают. Но есть дополнительные плюсы, о которых я писал выше.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое