Данная статья описывает мой опыт создания беспроводного датчика температуры на базе МК Attiny85 + ds18b20 + rf 433 TX, работающего от батареек. Прием данных и программирование Attiny85 сделано на основе Raspberry pi B+.
Предисловие
На Хабре и не только есть много интересно про мини-компьютер Raspberry Pi. Я решил обзавестись в своем доме такой игрушкой. Прошу не критиковать выбор именно этой платформы. Выбор пал только в силу довольно обширной документации и множества различных примеров применения данного мини-компьютера.
Решено было начать с датчиков температуры. Под рукой оказалось пару датчиков (ds18b20, ds1822). Обилие статей по подключению этих датчиков не потребовало много времени, для того что б их присоединить и получить значения температуры. Пришлось приобрести датчик DHT22, который позволял фиксировать не только температуру, но и влажность. На малине был поднят lighttpd + php + mysql. Данные с датчиков теперь с некоторой периодичностью записывались в БД. Из статьи «Интернет термометр или телеметрия загородного дома» была взята идея построения графиков в Highcharts. Не обладая особыми навыками программиста, пришлось потратить пару свободных вечеров. В результате можно было зайти на локальную страничку и посмотреть на текущую температуру на улице, в квартире, а так же динамику изменения температуры за последние n дней.
Некоторое время за окном висело два датчика DHT22 и ds18b20. Показания температуры этих датчиков отличались обычно на несколько десятых. Целью не ставилось делать измерения с очень большой точностью и такие отличия в показаниях меня вполне устраивали.
Все в той же статье было подсмотрены ссылки на проекты openweathermap.com и narodmon.ru. Таким образом, данные c датчика температуры и давления (DHT22) начал отправлять в эти два сервиса.
Я не сильно понял сервис Openweathermap. Народный мониторинг мне понравился больше. На карте можно наглядно сравнить свои показания с данными других датчиков в твоем же городе. Есть приложения для телефонов на Android и iOS.
Всё, конечно, замечательно, но проблемы как всегда кроются в деталях. Окна моей квартиры смотрят на юг. И датчики часто оказываются на солнце. Когда на улице минусовая температура, датчики на солнечной стороне могли показывать до +10. При этом датчики не находятся под прямыми солнечными лучами (спрятаны за блок кондиционера). Тянуть провода через коридор на северную сторону не сильно хотелось. Поэтому было принято решение осваивать беспроводные технологии.
Постановка задачи
Для приема и передачи был выбран RF 433. Опять же, поскольку являюсь новичком в мире электроники и программирования, решил не тратить много денег и оставить свой выбор на наиболее бюджетном варианте. Стоимость приемника + передатчик составляет около 3$.
Схема работы: МК — rf 433 (передатчик) -> rf 433 (приемник) — Raspberry pi.
Нужно было выбрать микроконтроллер. На Instructables есть отличная статья о том, как программировать микроконтроллер Attiny85 при помощи raspberry pi. Перевода данной статьи или чего-то похожего на Хабре не встречал. Так что если будет проявлен интерес, можно будет сделать перевод.
Выбор микроконтроллера был сделан. Была приобретена опытная пара на рынке по цене 2-3$ за штуку. Для простоты начать решил с ds18b20.
Алгоритм работы следующий: МК считывает значение температуры с датчика, считывается напряжение (питать будем от батареек), вычисляется контрольная сумма, отправляются эти данные несколько раз, после чего отправляем всю эту систему в сон на несколько минут, чтобы экономить питание.
rf 433 (приемник) + Raspberry pi слушает эфир в ожидании данных.
Выполнение задачи
Сборка и подключение
На макетной плате собираем схему для программирования МК:
Схема подключения взята с сайта Instructables. Резисторы можно взять немного другие 1-5КОм, какие есть под рукой. Больше чем 4,7 КОм я лично не пробовал. Там же на макетной плате подключаем датчик и передатчик к аттини так, как показано на схеме:
Таким образом, мы получили подключенный МК для программирования при помощи Raspberry Pi и подключенные датчик и RF433 передатчик. Осталось подключить приемник к rasspbery pi. Моя схема подключения:
Raspi RF433 RX
GPIO 27 (13) -> DATA
GND (14) -> GND
5В, Vcc (4) -> Vcc
Пины на схемах подключения к raspberry pi согласно их нумерации в библиотеке WiringPI для работы с GPIO, их физическое расположение на плате в скобках.
И вот так это все выглядит на макетной плате:
С железом разобрались, перейдем к софтверной части.
Устанавливаем необходимый софт и программируем Attiny85
Как устанавливать Raspbian не будем рассматривать. В raspi-config включаем SPI.
Теперь нам надо скачать и установить AVRDude (AVR Downloader-Uploader) — кросплатформенная свободная консольная программа, предназначенная для прошивки микроконтроллеров фирмы Atmel серии AVR.
sudo apt-get install bison automake autoconf flex git gcc
sudo apt-get install gcc-avr binutils-avr avr-libc
git clone https://github.com/kcuzner/avrdude
cd avrdude/avrdude
./bootstrap && ./configure && sudo make install
Для работы с GPIO необходимо скачать и установить WiringPi:
cd ~
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build
Проверяем все ли мы правильно сделали:
sudo gpio -g mode 22 out
sudo gpio -g write 22 0
sudo avrdude -p t85 -P /dev/spidev0.0 -c linuxspi -b 10000
sudo gpio -g write 22 1
Если мы все правильно сделали, должны получить вот такой результат:
На этом этапе подготовительные работы закончились.
Найти рабочий код на Си, который бы выполнял все поставленные задачи, мне не удалось. Пришлось собирать по кусочкам из различных репозиториев (и не только).
Для считывания температуры использовал этот репозиторий. Для определение напряжения использовал этот репозиторий.
Для отправки сигнала использовал репозиторий.
То, что у меня получилось выложил на гитхаб. Нужный нам код находится blinky.c, 1wire.c, 1wire.h, manchester.c, manchester.h.
Осталось все собрать и запрограммировать нашу Аттиньку 85.
Создаем или копируем Makefile там же, где находятся файлы нашего проекта.
Выполняем:
make
И если все хорошо и не будет никаких ошибок в коде программы, выполняем:
make install
Расслабились и наблюдаем запись нашей программы на микроконтроллер:
Если все хорошо и ничего нам не помешало, на этом этап программирования нашего МК завершено.
По схеме выше собираем все на отдельной макетной плате уже без Rasspberry Pi и питание от батареек. У меня в наличии был корпус для трех батареек АА. Это мой первый проект и я не сильно напрягался с разводкой на плате. Вот что у меня в итоге получилось:
Теперь пришло время принимать данные температуры с передатчика.
Есть хорошая статья о расшифровке Х10 RF протокола. Там есть примеры программ для приема сигнала по RF433. Для приемника за основу был взят код из этой статьи, а именно X10RFSnifferBit.cpp. Программа сидит и ждет сигнал определенной длительности, а точнее, несколько последовательных сигналов, так называемый lock. После чего начинается прием необходимого количества бит.
Изменяем под свои значения lock, добавляем проверку контрольной суммы и пишем полученные значения в файл. Полученную информацию записываем в файл в виде id датчика, заряда батареек, температуры и контрольной суммы.
Так выглядит мой rf433recieve.cpp, а так выглядит пример файла, в который записываем полученные данные.
В моем случае RF 433 RX подключил к GPIO 2 (13). При подключении к другому пину необходимо изменить номер GPIO в строке:
wiringPiISR(2, INT_EDGE_BOTH, &handleInterrupt);
Собираем и запускаем нашу программку (Makefile). Запускать надо с правами root:
make
sudo ./rf433recieve
Теперь на raspberry pi мы принимаем нашу температуру и записываем в полученные данные в файл.
Заключение
Пока все это собиралось и программировалось, данные из локальной БД перенес на
Когда все было в сборе, надо было проверить дальность передачи данных в домашних условиях с различными антеннами.
На приемнике антенной выступает кусок от витой пары длинной около 17 см. Для передатчика пробовал несколько вариаций: витая пара 17 и 34 см; медная жила около 1 мм в диаметре и длинной 34 см в виде прямой и в виде спирали. Хуже всего в моих экспериментах оказалась медная жила в виде спирали, остальные антенны дали приблизительно одинаковый вариант, поэтому я решил оставить кусок витой пары 17 см. По дальности у меня получилось пробить три кирпичных стены и дистанцию около 10 м. Увеличение перегородок и дистанции приводили к тому, что приемник совсем не принимал сигнал или пытался выловить один два сигнала из lock-a.
Сейчас идет период испытаний и датчик положил на балкон (тоже на солнечную сторону). На открытом балконе датчик не прятал от солнца и явно балкон хуже проветривается, чем датчик спрятанный за корпус кондиционера в тень. Поэтому в солнечные дни беспроводной датчик выдает пики и по этим пикам можно отслеживать солнечную активность.
Что дальше? Дальше хотел попробовать связку МК Attiny85 + RF 433 TX + DHT22, но это уже совсем другая история…
Автор: Kisa_ua