- H Подключаем датчики к Raspberry Pi без проводов и с Arduino в черновиках
- На закуску, видео работы двух Arduino с одной Raspberry Pi.
- Получение данных с аналоговых датчиков, подключенных к Raspberry Pi
- Подключение датчика температуры DS18B20 к Raspberry Pi
- Необходимые компоненты
- Общие принципы работы датчика DS18B20
- Схема проекта
- Установка библиотеки Adafruit для работы с ЖК дисплеем
H Подключаем датчики к Raspberry Pi без проводов и с Arduino в черновиках
В процессе создания умного дома, каждый рано или поздно сталкивается с размещением датчиков, показатели которых нужно выводить на экран, а то и обрабатывать для чего-то более умного.
Большинство датчиков легче всего подключаются к Arduino, за счет наличия библиотек, безгеморройных PWM, ADC и прочих вкусностей.
Но слишком умную логику на Arduino не построишь, и волей-неволей возникает необходимость использования чего-то более быстрого, универсального, и с простой индикацией\управлением. Например, почти ставший стандартом де-факто, Raspberry Pi.
У него есть HDMI\AV выход. Есть флешка, сеть, память, USB и SSH. Все что нам нужно.
Но напрямую датчики к Raspberry Pi подключить весьма непросто, в силу отсутствия большого количества библиотек, примеров, и просто потому что она не совсем к этому приспособлена. Да и держать эти датчики тогда придется рядом, а значит либо Малинке придется жить на балконе, либо датчику влажности воздуха у вас в шкафу.
Разумеется, тянуть два-три провода от датчиков к Малине — тоже не вариант, ибо тогда умный дом станет сложным домом.
Интересно?
Для этих целей была придумана радиосвязь.
В качестве самой дешевой, понятной и доступной радиосвязи, я выбрал радиомодуль-трансивер nrf24l01, и вот почему:
1) Дальность. В пределах дома — до ста метров. То что нам подходит.
2) Скорость передачи данных — до 2 Мбит. Хоть потоковое видео передавай.
3) Возможности подключения точка-точка, точки-хаб, хаб-хаб, хаб-точка.
4) Толерантны к 5В, хотя могут принимать и 3.3В.
5) Эти контроллеры имеют свою прошивку, которая позволяет им становиться независимым девайсом.
6) Автоматически шлет идентификатор сигнала, избавляя нас от необходимости заморачиваться с индивидуальной настройкой каналов для каждого трансивера.
7) Дуплекс.
8) Дешевизна. Кстати взял я их не дешево, решил не ждать три недели ради экономии 10 баксов.
Вот так выглядит этот девайс.
Топология связи очень проста, дешева и понятна.
1) Набор датчиков в какой-либо локации, подключается к Arduino. Таких локаций может быть несколько.
2) Она (Arduino) играет роль предварительного буфера, который собирает данные с датчиков, и комбинирует их для последующей отправки.
Ну и выполняет какую-то базовую логику, например включает на балконе свет по датчику движения (без участия центрального сервера). В общем согласно наши потребностям.
3) Raspberry Pi через такой же самый модуль, принимает радиосигнал.
В интернете очень много примеров связи Arduino-Raspberry Pi, используя эти трансиверы nrf24l01.
Однако почему-то все эти примеры рассматривают Arduino как центральный узел (хаб), а Raspberry Pi как придаток (клиент). И мало что из примеров работоспособно с первого раза.
Методом проб и ошибок, мне удалось сделать обратное — один Raspberry Pi-блок, и несколько узлов с Ардуинами, которые настраиваются абсолютно одинаково, не нуждаются в выборе каналов, частот и прочего. Поменяли циферку в строке — получили новое устройство.
Несколько фоток из центра событий.
Малиновый сервер. Не удобно подключаться по сети, WiFi рулит.
Первый подопечный. Arduino Nano с датчиком движения.
Второй подопечный. Arduino Mini и USB-TTL. Где-то там отстает проводок.
Все вместе.
Итак, не буду вдаваться в подробности установок IDE, библиотек, а выложу сразу работающий код для двух устройств.
Arduino-часть.
#include #include // CE,CSN пины RF24 radio(9,10); // init counter unsigned long count = 0; int sensor1 = 2; void setup(void) < // Инициализируем канал связи и не только. radio.begin(); radio.setPALevel(RF24_PA_MAX); radio.setChannel(0x4c); radio.openWritingPipe(0xF0F0F0F0E1LL); radio.enableDynamicPayloads(); radio.powerUp(); pinMode(sensor1, INPUT); pinMode(3, OUTPUT); >void loop(void) < char outBuffer[32]= ""; int pin1 = digitalRead(sensor1); // Следующая строка изменяется по нашему желанию. Я шлю на сервер три значения: ID блока (ардуины), ID пина, и его значение. Больше ничего изменять не нужно. String out = "dev1:p1:"+pin1; out.toCharArray(outBuffer, 32); radio.write(outBuffer, 32); delay(50); // Не знаю почему, но периодически трансивер зависает. Помогает повторная инициализация. radio.begin(); radio.setPALevel(RF24_PA_MAX); radio.setChannel(0x4c); radio.openWritingPipe(0xF0F0F0F0E1LL); radio.enableDynamicPayloads(); radio.powerUp(); delay(50); // Следующий костыль включает свет по датчику движения на 10 секунд, не замораживая при этом основной цикл loop. if (pin1=HIGH) < digitalWrite(3, HIGH); count=0; >count++; if (count>100) < digitalWrite(3, LOW); count=0; >>
На Малине нам понадобится библиотека, установить которую можно так:
git clone https://github.com/stanleyseow/RF24.git cd RF24 cd librf24-rpi/librf24 make sudo make install
C++ код для Raspberry Pi. В инклуде нужно указать путь к файлу хидера.
#include #include #include "../RF24.h" #include using namespace std; // spi device, spi speed, ce gpio pin RF24 radio("/dev/spidev0.0",8000000,25); void setup(void) < // init radio for reading radio.begin(); radio.enableDynamicPayloads(); radio.setAutoAck(1); radio.setRetries(15,15); radio.setDataRate(RF24_1MBPS); radio.setPALevel(RF24_PA_MAX); radio.setChannel(76); radio.setCRCLength(RF24_CRC_16); radio.openReadingPipe(1,0xF0F0F0F0E1LL); radio.startListening(); >void loop(void) < char receivePayload[64]; while (radio.available()) < uint8_t len = radio.getDynamicPayloadSize(); radio.read(receivePayload, len); // Костыль для создания промежуточного файла. ofstream out("/dev/nrf24"); out > int main(int argc, char** argv) < coutСкомпилировать на Малинке мы его можем командой
g++ -Wall -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -L../librf24/ -lrf24 receiver.cpp -o rpi
Запустив это поделие в фоне, мы получим файл /dev/nrf24, который будет содержать строку, пришедшую к нам по радиоканалу.
Его мы можем читать и парсить как нам заблагорассудится. Хоть read, хоть cat, хоть tail.
Внимание: костыль с этим файлом был введен ТОЛЬКО для «удобства» совместной работы приложений на разных языках: bash, PHP. По феншую все делать только на С++.На закуску, видео работы двух Arduino с одной Raspberry Pi.
Ради интереса попробовал сформировать строку в JSON, это видно на видео. Неэффективно, если датчиков много. Лимит на 32 символа, а разбираться глубже не было времени. Просто поменять циферку 32 на 64 — не помогает.
Все элементы использую только для наглядности примера. Реальная реализация выглядит по-другому.
Получение данных с аналоговых датчиков, подключенных к Raspberry Pi
Информация, снимаемая с аналогового датчика, представляет собой напряжение сигнального выхода датчика. Это напряжение может изменяться от 0 до напряжения питания датчика (грубо говоря, чем больше измеряемая датчиком величина, тем выше напряжение сигнального выхода)
Чтобы считать это напряжение и преобразовать его к осязаемому цифровому значению используется аналого-цифровой преобразователь (AЦП).
В Raspberry Pi отсутствует встроенный АЦП, поэтому для подключения к RasPi аналоговых датчиков потребуется внешний АЦП.
Это 4-канальный 8-битный АЦП, который передаёт считываемые с датчика значения напряжения по i2c. Соответственно подключаем его к пинам 5V, GND, SDA, SCL GPIO разъёма Raspberry Pi. Также нам потребуется подгрузить модули ядра для работы с i2c:
sudo modprobe i2c-dev sudo modprobe i2c-bcm2708
Чтобы постоянно не подгружать их постоянно вручную рекомендую добавить строчки в /etc/modules:
Как я уже выше писал, разрешающая способность PCF85918-бит. Это значит, что величина цифрового значения, в которое будет преобразовано напряжение сигнального выхода датчика будет лежать в диапазоне от 0 до 2^8-1=255. Это значение высчитывается по формуле -
напряжение сигнального выхода датчика/напряжение АЦП * разрешающую способность АЦП
Таким образом для 3V с датчика: value=3/5*255=153
К АЦП мы будем подключать аналоговый датчик MQ-3, который определяет концентрацию паров этилового спирта в воздухе.
У MQ-3 4 выхода - AD, DO, Vcc, GND. Vcc и GND подключаем к пинам GPIO 5V и GND. AD (выход сигнального напряжения датчика) подключаем к одному из 4 входов АЦП (я подключил к А0). DO не подключаем никуда. На выходе DO появляется напряжение, когда значение измеряемой величины (в нашем случае концентрации паров этилового спирта в воздухе) достигает некоторой критической величины. Критическая величина задаётся подкруткой подстроечного резистора на плате датчика.
Далее переходим к программной части. Для получения значения датчика будем использовать популярную библиотеку для работы с GPIOwiringPi:
sudo apt-get install git-core git clone git://git.drogon.net/wiringPi cd wiringPi ./build
Напишем небольшую программу, которая будет каждые полсекунды выводить на экран значение датчика:
В функциюpcf8591Setupпередаётся число большее 64, которое будет служить номером "виртуального" пина для библиотеки wiringPi и адрес АЦП на интерфейсе i2c.analogReadвозвращает преобразованное значение напряжения датчика (число от 0 до 255), подключённого к АЦП.
Компилируем нашу программу:
gcc -o ./analogread ./analogread.c -lwiringPi
Запускаем скомпилированный analogread - на экране побегут значения датчика, обновляемые каждые полсекунды.
Если к датчику поднести открытую бутылку с алкоголем, то значения будут в реальном времени увеличиваться.
Чтобы это значение преобразовать в реальное значение концентрации паров этилового спирта нужно обратиться к даташиту на MQ-3, в этой статье я этот вопрос рассматривать не буду.
Подключение датчика температуры DS18B20 к Raspberry Pi
Плата Raspberry Pi хорошо известна в современном мире благодаря своей вычислительной мощности и широкой распространенности в проектах интернета вещей, автоматизации дома. Тем не менее, ни один достаточно сложный электронный проект не может нормально работать без информации об окружающем мире, получаемой с помощью разнообразных датчиков.
Одним из таких часто используемых датчиков является датчик температуры DS18B20, способный работать в условиях агрессивной окружающей среды: заводы, химические производства и т.д. В данной статье мы рассмотрим его подключение к плате Raspberry Pi. Получаемое от датчика значение температуры мы будем выводить на экран ЖК дисплея 16x2. Ранее на нашем сайте мы рассматривали подключение датчика DS18B20 к плате Arduino и микроконтроллеру AVR. Также вы можете посмотреть статью о подключении к плате Raspberry Pi датчика температуры и влажности DHT11.
Необходимые компоненты
- Плата Raspberry Pi (купить на AliExpress).
- ЖК дисплей 16x2 (купить на AliExpress).
- Датчик температуры DS18B20 (купить на AliExpress).
- Подтягивающий резистор 10 кОм (купить на AliExpress).
- Потенциометр 10 кОм (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Общие принципы работы датчика DS18B20
DS18B20 представляет собой датчик температуры с 3 выводами, упакованный в корпус TO-92 (транзисторный тип). С ним очень просто работать и для его подключения необходимо использовать всего один внешний компонент (подтягивающий резистор). Для его подключения к микроконтроллеру используется всего один контакт. Внешний вид датчика DS18B20 и его распиновка показаны на следующем рисунке.
Датчик DS18B20 доступен также в водонепроницаемом варианте, при котором он заключен в цилиндрическую металлическую трубку. В этом проекте мы его будем использовать в обычном виде – в транзисторном корпусе. DS18B20 является однопроводным программируемым датчиком температуры, что означает что ему необходим всего лишь один контакт данных чтобы передавать информацию микроконтроллеру (в нашем случае плате Raspberry Pi). Каждый датчик имеет свой уникальный адрес длиной 64 бита, что позволяет по одной и той же шине (проводу) подключать к одному и тому же микроконтроллеру множество подобных датчиков – в этом случае обращение к конкретному датчику осуществляется по его адресу.
Датчик DS18B20 имеет следующие технические характеристики:
- рабочее напряжение: 3-5V;
- диапазон измеряемых температур: от -55°C до +125°C;
- точность измерения температуры: ±0.5°C;
- разрешение: от 9 до 12 бит.Схема проекта
Схема подключения датчика температуры DS18B20 к плате Raspberry Pi представлена на следующем рисунке.
В представленной схеме датчик DS18B20 и ЖК дисплей запитываются от контакта 5V платы Raspberry Pi. ЖК дисплей подключен к плате в 4-битном режиме, его контакты данных подключены к контактам GPIO 18, 23, 24 и 25 платы, а контакты управления – к контактам GPIO 7 и 8 платы. Потенциометр используется для регулировки контрастности ЖК дисплея. Контакт данных датчика DS18B20 подключен к контакту GPIO 4 платы Raspberry Pi. Резистор 10 кОм, подключенный к датчику, выполняет роль подтягивающего резистора.
Чтобы вам легче было делать соединения в схеме на следующем рисунке представлена схема расположения контактов платы Raspberry Pi.
После сборки схемы на макетной плате у нас получилась конструкция следующего вида:
Установка библиотеки Adafruit для работы с ЖК дисплеем
Библиотека от Adafruit позволяет значительно упростить управление ЖК дисплеем в 4-битном режиме с платы Raspberry Pi. Поэтому откроем терминал и выполним следующую последовательность шагов.
Шаг 1. Установим инструмент git на плату Raspberry Pi. Git позволяет клонировать файлы любого проекта на Github и затем использовать их в плате. Для установки git выполним следующую команду: