Достаточно давно меня привлекала Arduino и всё что с ней связано. Несколько лет назад прикупил UNO поигрался  миганием светодиодов и прочими классическими примерами. Приобрел разные датчики, посмотрел как с ними работать, но всё это было как-то не то. Хотелось все-таки решить какую-то прикладную задачку. Пускай, может, высосанную из пальца, но прикладную. И вот при очередной передаче показаний счетчиков учета воды задача родилась!

Задача

  1. Используя Arduino, сделать доступным показания счетчиков учета воды через интернет.
  2. Все данные с устройства должны передаваться по радиоканалу.
  3. Устройство помещаемое в стояк должно быть энергонезависимым от электросети помещения.
  4. Данные по потреблению должны отображаться в виде графиков, с детализацией по часу в сутках/дням в месяце/месяцам в году.
  5. Данные о потреблении должны поступать каждые 30 секунд.

Что есть в наличие

Приборы учета воды с импульсными выходами, которые меняют значение с нуля на единицу каждые пол-литра.

Arduino Uno, Nano, радио модули nRF24L01+, Ethernet шилд и всякая мелочь.

В радиусе 20 метров от стояка маршрутизатор подключенный к интернету.

Процесс

Итак, задача в целом ясна. Как делать примерно, в общих чертах, тоже понятно.

prototype_water

Планирую сделать два железных узла («Передатчик показаний», «Приемник показаний и передатчик на сервер») и один виртуальный на базе существующего веб-сервера.

Сначала надо было научиться снимать показания счетчиков. Это не сложная задача. Подключение аналогично подключению кнопки (не забываем ставить сопротивление, что бы исключить неопределенность). Вешаем на два цифровых входа — один для показаний горячей воды, второй для холодной. А дальше считаем количество изменений состояния с «0» на «1» и обратно, а затем раз в 30 секунд обнулять после «отправки».

Следующий этап — разобраться с радио модулями и передачей данных. По-неопытности решил передавать полнотекстовые данные, а-ля xml или json. Но, спасибо знающим людям, объяснили, что такой подход крайне не эффективен в рамках моей задачи.

Основное ограничение — это размер пакета, который передаётся за один раз по радиоканалу. Для имеющегося чипа он может быть динамическим, но максимальный размер — 32 байта. Поэтому придумать передавать текст было, мягко говоря, глупо. Удобным способом формирования пакета является использование структур.

Для своего проекта я использовал следующую структуру:


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() {}
};

Таким образом все необходимые данные занимают всего 13 байт. И, как потом станет понятно, даже этот набор в общем-то избыточен.

Пакет сформирован, надо научиться его принимать. Настройка соединения между двумя модулями оказалась достаточно простой. Для разбора пакета надо всего лишь использовать эту же структуру. Очень удобно!

wpid-20150117_220431_partizanskaya-ul..jpg.jpeg

Теперь необходимо этот пакет передавать на сервер. Для этого пишем на сервере простейший API, который при запросе определенного URL добавляет данные из параметров URL в БД.

После написания API дописываем скетч для Ардуино, что бы полученный по радиоканалу пакет был передан в БД.

Пакет передан, копим данные и отображаем на графике.

Результат

Ура, первый прототип собран, схема работает!

wpid-20150118_212921_partizanskaya-ul..jpg.jpegПервый макет передатчика. Для удобства коммутации использовал шилд для Arduino Nano, к нему подключен nRF24L01+. Для подсоединения проводов от водосчетчиков использовал контактную площадку, к которой припаял клемники.

wpid-20150118_212741_partizanskaya-ul..jpg.jpegПриемник, который передает данные на сервер в интернете. На нижнем уровне Arduino UNO, на ней Ethernet Shield на базе Wiznet W5100, и на стяжке болтается радио-модуль nRF24L01+.

grap

Вывод графиков на веб странице.

Дальше были испытания и наблюдения — сколько протянет прототип на батарейках? Оказалось совсем не долго. Всего-то 2.5 дня. Как выяснилось, беды две. Одна (но не главная) — не использование спящего режима. Вторая — обвязка Arduino, которая потребляет слишком много, по сравнению с самим микроконтроллером ATmega328.

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