Достаточно давно меня привлекала Arduino и всё что с ней связано. Несколько лет назад прикупил UNO поигрался миганием светодиодов и прочими классическими примерами. Приобрел разные датчики, посмотрел как с ними работать, но всё это было как-то не то. Хотелось все-таки решить какую-то прикладную задачку. Пускай, может, высосанную из пальца, но прикладную. И вот при очередной передаче показаний счетчиков учета воды задача родилась!
Задача
- Используя Arduino, сделать доступным показания счетчиков учета воды через интернет.
- Все данные с устройства должны передаваться по радиоканалу.
- Устройство помещаемое в стояк должно быть энергонезависимым от электросети помещения.
- Данные по потреблению должны отображаться в виде графиков, с детализацией по часу в сутках/дням в месяце/месяцам в году.
- Данные о потреблении должны поступать каждые 30 секунд.
Что есть в наличие
Приборы учета воды с импульсными выходами, которые меняют значение с нуля на единицу каждые пол-литра.
Arduino Uno, Nano, радио модули nRF24L01+, Ethernet шилд и всякая мелочь.
В радиусе 20 метров от стояка маршрутизатор подключенный к интернету.
Процесс
Итак, задача в целом ясна. Как делать примерно, в общих чертах, тоже понятно.
Планирую сделать два железных узла (“Передатчик показаний”, “Приемник показаний и передатчик на сервер”) и один виртуальный на базе существующего веб-сервера.
Сначала надо было научиться снимать показания счетчиков. Это не сложная задача. Подключение аналогично подключению кнопки (не забываем ставить сопротивление, что бы исключить неопределенность). Вешаем на два цифровых входа – один для показаний горячей воды, второй для холодной. А дальше считаем количество изменений состояния с “0” на “1” и обратно, а затем раз в 30 секунд обнулять после “отправки”.
Следующий этап – разобраться с радио модулями и передачей данных. По-неопытности решил передавать полнотекстовые данные, а-ля xml или json. Но, спасибо знающим людям, объяснили, что такой подход крайне не эффективен в рамках моей задачи.
Основное ограничение – это размер пакета, который передаётся за один раз по радиоканалу. Для имеющегося чипа он может быть динамическим, но максимальный размер – 32 байта. Поэтому придумать передавать текст было, мягко говоря, глупо. Удобным способом формирования пакета является использование структур.
Для своего проекта я использовал следующую структуру:
[code language=”cpp”]
struct SensorData {
uint8_t node_id; // node id (номер передатчика – задел на будущее) 1 байт
uint32_t packet_id; // id пакета (на всякий случай, что бы понимать были ли потерянные пакеты) 4 байта
uint32_t timefromstart; // Время с момента запуска Arduino (целое значение в миллисекундах) 4 байта
uint8_t tic_h; // Целое значение кол-ва тиков (смен с 0 на 1 или с 1 на 0) горячей воды 1 байт
uint8_t tic_c; // Целое значение кол-ва тиков холодной воды 1 байт
uint8_t vcc_h; // Целое значение напряжения (0 .. 255) 1 байт
uint8_t vcc_l; // Дробное значение напряжения (2 знака) 1 байт
SensorData() {}
};
[/code]
Таким образом все необходимые данные занимают всего 13 байт. И, как потом станет понятно, даже этот набор в общем-то избыточен.
Пакет сформирован, надо научиться его принимать. Настройка соединения между двумя модулями оказалась достаточно простой. Для разбора пакета надо всего лишь использовать эту же структуру. Очень удобно!
Теперь необходимо этот пакет передавать на сервер. Для этого пишем на сервере простейший API, который при запросе определенного URL добавляет данные из параметров URL в БД.
После написания API дописываем скетч для Ардуино, что бы полученный по радиоканалу пакет был передан в БД.
Пакет передан, копим данные и отображаем на графике.
Результат
Ура, первый прототип собран, схема работает!
Первый макет передатчика. Для удобства коммутации использовал шилд для Arduino Nano, к нему подключен nRF24L01+. Для подсоединения проводов от водосчетчиков использовал контактную площадку, к которой припаял клемники.
Приемник, который передает данные на сервер в интернете. На нижнем уровне Arduino UNO, на ней Ethernet Shield на базе Wiznet W5100, и на стяжке болтается радио-модуль nRF24L01+.
Вывод графиков на веб странице.
Дальше были испытания и наблюдения – сколько протянет прототип на батарейках? Оказалось совсем не долго. Всего-то 2.5 дня. Как выяснилось, беды две. Одна (но не главная) – не использование спящего режима. Вторая – обвязка Arduino, которая потребляет слишком много, по сравнению с самим микроконтроллером ATmega328.
В связи с этим будет второй прототип передатчика, который сможет долго жить на батарейках.