Делаем метеостанцию на базе arduino
Содержание:
- Виды датчиков
- Скетч
- Принципиальные схемы
- Схема самодельной метеостанции
- Общий принцип работы
- Исходный код
- Android
- Радиодатчики
- Шаг третий. Подключаем ЖК-экран
- Arduino: как сделать термометр
- Что понадобится
- А как же камера?
- Подключение SX1278 к Raspberry Pi
- Программа
- Пояснения к коду
- Как сделать метеостанцию на LM35
- Сборка метеостанции с дисплеем 1602 и DHT11
- Установка сервера
- Архитектура
- Датчик на Arduino Uno и плате расширения Troyka Shield
- Что ещё можно сделать?
Виды датчиков
Для измерения параметров среды часто применяют три вида сенсоров:
- DHT11;
- DHT22;
- SHT1x.
Плюс первого — дешевизна, скорость работы и стабильность сигнала. Из минусов отметим сравнительно слабую программную реализацию библиотеки, высокую погрешность выполняемых измерений и не всегда подходящий диапазон рабочих температур. DHT22 выгодно отличается благодаря:
- малым погрешностям;
- высокой дальности сигнала;
- поддержке дробных значений.
Как и первый сенсор, DHT22 не работает без подгруженной библиотеки. Кроме того, для профессиональных задач его чувствительность и скорость реакции может стать недостаточной.
Датчики линейки SHT1x быстро срабатывают, имеют весьма низкую погрешность, экономичны и умеют «засыпать» при долгой неактивности. Из недостатков выделим:
- два цифровых интерфейса;
- невозможность работы без подключения программной библиотеки и диапазон от 0 до 50 градусов — как в других образцах. Его хватает не всегда.
По стоимости все три варианта примерно одинаковы. Для «домашних» установок чаще берут DHT11-22 за их сравнительную простоту в эксплуатации и настройке.
Скетч
- p160_meteostation.ino
-
#include <math.h> int minute = 1; // Параметр конкретного типа термистора (из datasheet): #define TERMIST_B 4300 #define VIN 5.0 void setup() { // мы хотим передавать информацию на компьютер через USB, а // точнее через последовательный (англ. serial) порт. // Для этого необходимо начать (англ. begin) передачу, указав // скорость. 9600 бит в секунду — традиционная скорость. // Функция «begin» не является глобальной, она принадлежит // объекту с именем «Serial». Объекты — это «продвинутые» // переменные, которые обладают собственными функциями, // к которым обращаются через символ точки. Serial.begin(9600); // передаём заголовок нашей таблицы в текстовом виде, иначе // говоря печатаем строку (англ. print line). Символы «\t» — // это специальная последовательность, которая заменяется на // знак табуляции (англ. tab): 8-кратный выровненный пробел Serial.println("Minute\tTemperature"); } void loop() { // вычисляем температуру в °С с помощью магической формулы. // Используем при этом не целые числа, а вещественные. Их ещё // называют числами с плавающей (англ. float) точкой. В // выражениях с вещественными числами обязательно нужно явно // указывать дробную часть у всех констант. Иначе дробная // часть результата будет отброшена float voltage = analogRead(A0) * VIN 1024.0; float r1 = voltage (VIN - voltage); float temperature = 1.( 1.(TERMIST_B)*log(r1)+1.(25. + 273.) ) - 273; // печатаем текущую минуту и температуру, разделяя их табом. // println переводит курсор на новую строку, а print — нет Serial.print(minute); Serial.print("\t"); Serial.println(temperature); delay(60000); // засыпаем на минуту ++minute; // увеличиваем значение минуты на 1 // откройте окно Serial Monitor в среде Arduino, оставьте на // сутки, скопируйте данные в Excel, чтобы построить графики }
Принципиальные схемы
Передатчик
Передающая часть беспроводного термометра на ATMega328p
(для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)
В данном примере я не буду выводить неиспользуемые выводы микроконтроллера на внешние контакты термометра, после чего их можно было бы использовать для дальнейшего усовершенствования устройства. Здесь мы рассматриваем лишь идею для устройства и соберем его только на макетной плате.
Приемник
Приемная часть беспроводного термометра на Arduino Mega
(для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)
Пожалуйста, обратите внимание, что приемник построен на базе платы Arduino Mega, которая не изображена на схеме. Для подключения платы Arduino Mega соедините с ней радиочастотный модуль и LCD дисплей согласно метка на схеме
Схема самодельной метеостанции
Схема очень проста и по сути состоит из 4 основных компонентов. Это МК, датчик атмосферного давления + температуры, датчик влажности и USB – UART преобразователь.
Сразу скажу, что все компоненты покупал на всем известном электронном аукционе, причём покупал сразу в виде готовых модулей. Поясню почему готовыми модулями, во первых – цена датчика (или микросхемы) отдельно и цена модуля ничем практически не отличается, во вторых – готовый модуль уже имеет всю необходимую обвязку, такую как подтягивающие резисторы, стабилизаторы и прочее, в третьих – это намного упрощает конструкцию, а соответственно и её реализацию. Теперь немного о каждом модуле по отдельности.
Общий принцип работы
Измеряющая данные окружающей среды метеостанция на Ардуино состоит из нескольких основных компонентов:
- собственно плата управления Arduino (например, Uno). На нее поступает информация со внешних датчиков, контроллер выполняет вычисления и выводит информацию на экран;
- электронный дисплей — служит для отображения поступивших с контроллера данных в понятной человекочитаемой форме;
- сенсор влажности температуры. В подобных схемах популярны датчики DHT11 и DHT22. Они регистрируют данные среды и отдают их контроллеру;
- макетная плата — основа для сборки всех компонентов. На ней фиксируются все элементы метеостанции, по ней же прокладываются электрические соединения;
- соединительные провода — с «оголенными» концами под пайку или оснащенные штекерами.
Кроме того, в плату понадобится залить соответствующее программное обеспечение — скетч. Его содержимое зависит от набора элементов и выполняемых задач, примеры скетчей мы также рассмотрим ниже.
Исходный код
Код автономной части
- meteo_sensor.ino
-
#include <Arduino.h> #include <SHT1x.h> #include <LowPower_Teensy3.h> #include <ampline.h> // Таймаут между посылками (не более 65535) #define TIMEOUT 60000 // Количество попыток отправки посылки #define ATTEMPTS 3 // Информационный пин передатчика #define RF_PIN 5 // Пины датчика температуры и влажности #define GND1_PIN 10 #define VCC1_PIN 11 #define GND2_PIN 7 #define VCC2_PIN 8 #define DATA_PIN 12 #define CLK_PIN 9 AmperkaLine rf(RF_PIN); SHT1x sht1x(CLK_PIN, DATA_PIN); void loop(void); // Функция усыпления платы. Каждые TIMEOUT секунд // будет вызываться функция loop_func. TEENSY3_LP LP = TEENSY3_LP(); sleep_block_t* LP_config; void sleep_mode(void) { LP_config = (sleep_block_t*)calloc(1,sizeof(sleep_block_t)); // Просыпаться будем по таймеру LP_config->modules = (LPTMR_WAKE); // Задаём таймаут для таймера LP_config->lptmr_timeout = TIMEOUT; // По истечении таймаута будет вызываться функция loop LP_config->callback = loop; LP.Hibernate(LP_config); } // Функция включения периферии void periferial_start(void) { // Включаем линию передачи данных pinMode(RF_PIN, OUTPUT); // Включаем питания и земли датчиков температуры и влажности pinMode(GND1_PIN, OUTPUT); pinMode(GND2_PIN, OUTPUT); pinMode(VCC1_PIN, OUTPUT); pinMode(VCC2_PIN, OUTPUT); digitalWrite(GND1_PIN, LOW); digitalWrite(GND2_PIN, LOW); digitalWrite(VCC1_PIN, HIGH); digitalWrite(VCC2_PIN, HIGH); // Включаем светодиод для индикации передачи pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); // Выбираем в качестве опорного напряжения внутренний // источник (=1.2 В) analogReference(INTERNAL); } // Функция выключения периферии void periferial_stop(void) { // Выключаем линию передачи данных pinMode(RF_PIN, INPUT); // Выключаем датчик температуры и влажности pinMode(GND1_PIN, INPUT); pinMode(GND2_PIN, INPUT); pinMode(VCC1_PIN, INPUT); pinMode(VCC2_PIN, INPUT); pinMode(18, INPUT_PULLUP); pinMode(19, INPUT_PULLUP); // Выключаем светодиод digitalWrite(LED_BUILTIN, LOW); } void setup(void) { // Ничего не инициализируем, сразу засыпаем sleep_mode(); } // Эта функция выполняется раз в TIMEOUT секунд void loop(void) { unsigned long msg; byte temp, humidity, voltage; // Включаем периферию periferial_start(); // Подождём, пока включится датчик температуры и влажности delay(30); // Получаем входные данные с сенсоров temp = (byte)(sht1x.readTemperatureC() + 40.)*2; humidity = (byte)sht1x.readHumidity(); voltage = analogRead(A0)4; // Составляем из данных посылку msg = ; msg |= voltage; msg <<= 8; msg |= humidity; msg <<= 8; msg |= temp; // Отправляем несколько раз посылку for(int i = ; i < ATTEMPTS; i++) rf.send(msg); // Выключаем периферию periferial_stop(); // После выхода из функции плата снова уснёт }
Код платы, работающей в помещении
- receiver.ino
-
#include <Arduino.h> #include <SPI.h> #include <Ethernet.h> #include <ampline.h> byte mac = { 0x90, 0xA7, 0xDA, 0x0F, 0xBC, 0x75 }; char server = "narodmon.ru"; EthernetClient client; const int rfpin = 7; AmperkaLine rf(rfpin); void setup(void) { pinMode(rfpin, INPUT); pinMode(6, OUTPUT); Serial.begin(9600); Serial.println("Started."); } void loop(void) { static unsigned long pushtimeout = ; static float temp, humidity, voltage; unsigned long msg; int res; if((res = rf.receive(&msg)) == ) { temp = ((float)(msg&0xFF))2. - 40.; msg >>= 8; humidity = (float)(msg&0xFF); msg >>= 8; voltage = (float)(msg&0xFF) 256. * 1.2 * 10 * 1.1; digitalWrite(6, HIGH); Serial.print("Temp: "); Serial.print(temp); Serial.print(", humidity: "); Serial.print(humidity); Serial.print(", voltage: "); Serial.println(voltage); digitalWrite(6, LOW); } else Serial.println('E'); if(millis() - pushtimeout > 60000*5) { pushtimeout = millis(); Serial.println("Starting Ethernet..."); if (Ethernet.begin(mac) == ) { Serial.println("Failed to configure Ethernet using DHCP"); while(1) { } } delay(1000); Serial.println("connecting..."); if (client.connect(server, 8283)) { Serial.println("connected"); client.println("#90-A7-DA-0F-BC-75#Sensor#55.751775#37.616856#0.0"); client.print("#90A7DA0FBC7501#"); client.print(temp, DEC); client.println("#In"); client.print("#90A7DA0FBC7502#"); client.print(humidity, DEC); client.println("#Humidity"); client.print("#90A7DA0FBC7503#"); client.print(voltage, DEC); client.println("#Voltage"); client.println("##"); } else Serial.println("connection failed"); { unsigned long tm = millis(); while(millis() - tm < 5000) { if (client.available()) { char c = client.read(); Serial.print(c); } } } client.stop(); } }
Android
Теперь напишем простое приложение для Андроид, которое запрашивает, получает, декодирует JSON-данные и отображает информацию на экране.
Наше Android-приложение будет простым насколько это возможно, только сама суть технологии. Далее вокруг этого «скелета» уже можно будет наворачивать различные «красивости».
Вот скриншот того, что должно получиться в итоге
Как видим UI просто спартанский, основан на LinearLayout, ничего лишнего.
В верхней части TextView показывает ID датчиков и их метео-данные. Кнопка «Обновить» инициирует повторный запрос к веб-серверу. Далее в EditText расположена единственная настройка программы — это URL запроса в виде
Что необходимо отметить?
В манифест добавьте строки разрешающие интернет и проверку состояния сетевого соединения :
Работа с сетью и получение данных с веб-сайта происходит следующим образом.
Используем AsyncTask, чтобы создать фоновую задачу отдельно от главного потока пользовательского интерфейса. Эта фоновая задача берет URL запроса и использует его для создания .
После того, как соединение установлено, AsyncTask загружает содержимое веб-страницы (JSON) как InputStream. Далее InputStream преобразуется в строку, которая декодируется с помощью JSONObject и отображается в пользовательском интерфейсе методом .
В MainActivity.java измените URL на ваш :
он будет использоваться по умолчанию при первом запуске Android приложения.
Радиодатчики
Там, где не дотянуться Wi-Fi, нужно использовать альтернативные варианты передачи данных. В моём случае — это использование LoRa-модулей (в связке, например, с Arduino Nano.
Таких устройств у меня два — это датчик скорости и направления ветра (компас). Пока не буду останавливаться на этом в текущей статье, если будет интерес — напишу отдельно. Второе устройство — это вольтметр и два амперметра, для контроля работы ветряка, зарядки АКБ и потребления.
SX1278 |
Arduino Nano |
3.3V |
3.3V |
GROUND |
GROUND |
MOSI |
D10 |
MISO |
D11 |
SCK |
D13 |
NSS/ENABLE |
D12 |
DIO0 |
D2 |
RST |
D9 |
И, код, соответственно:
iot/arduino/*_meter/*_meter.ino
Достаточно просто, не правда ли?
Шаг третий. Подключаем ЖК-экран
Теперь я отучу свою метеостанцию от компьютера: добавлю собственный экранчик и выведу на него температуру в двух шкалах — Цельсия и Фаренгейта.
Из кода программы я уберу команды, которые вызывали последовательный порт и группировали данные для отправки на компьютер.
Вместо них добавлю команды для работы с LED-дисплеем: подключение библиотеки, определение контактов и формирование строк. Первая строка меняться не будет, а во вторую выведу сразу два значения температуры: в градусах Цельсия и Фаренгейта.
У нас получилась простая метеостанция, которая умеет работать самостоятельно и передавать данные на компьютер. Это самый простой кирпичик для создания умного дома. Такие устройства можно использовать для контроля температуры в комнатах и парниках, управления системами отопления и подогрева воды, в качестве противопожарной сигнализации. Всё зависит только от вашей фантазии.
Arduino: как сделать термометр
- После того, как вы поработали со своим ЖК-дисплеем, вы можете самостоятельно сделать небольшой термометр. Для этого вам также будет нужен NTC и резистор 10 кОм.
- Подключите все компоненты, как показано на рисунке.
- Теперь вам нужно в самом начале вашего кода вставить команду «int tempPin = 0;», чтобы Arduino знал, после какого (аналогового) контакта вы подключили NTC.
- Затем добавьте в void loop() команду «int tempReading = analogRead(tempPin);», а затем команду «double tempK = log(10000.0 * ((1024.0 / tempReading — 1)));», и еще команду «tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK );» без кавычек. Под переменной «tempK» была задана и сохранена температура в Кельвинах.
- Изменить это вы можете с помощью команды «float tempC = tempK — 273.15;» и легко конвертировать единицы измерения в Цельсии.
- Теперь добавьте (все еще в void loop) команду «lcd.setCursor (0, 0);» чтобы поместить курсор в начало. После этого вам понадобится команда «lcd.print (tempC)»; для отображения температуры на дисплее. Поскольку курсор теперь всегда будет размещаться в начале, вам не нужно будет дополнительно вставлять команду lcd.clear ().
Фото: компании-производители
- Мини-ПК Raspberry Pi 3 Model B+ сможет стать центром «умного» дома
- Xiaomi выпустила метеостанцию с E Ink-дисплеем всего за $9
Что понадобится
— микроконтроллер Arduino Uno
— термистор (терморезистор)
— сопротивление на 10 кОм
— семисегментный индикатор
— макетная плата
— соединительные провода «папа-папа»
Основой метеостанции станет термистор — элемент, сопротивление которого меняется в зависимости от температуры. Сначала я выведу информацию с сенсора на экран ноутбука, а когда разберусь со всеми этими вольтами, омами и градусами — добавлю ЖК-экран, чтобы станция работала и без компьютера.
Мы будем собирать устройство на макетной плате. Схему можно поправить за считанные мгновения и не придётся ничего перепаивать.
А как же камера?
Пока никак. Сделанные фото можно передавать на WeatherUnderground. Это сделать несложно через ftp
Однако, даже просто вручную передать данные на WU у меня не получилось ни разу. Судя по форумам техподдержки, данная фича работает плохо и сбоит.
Альтернативной является передача изображения на narodmon.ru,
Собственно, время от времени (раз в полчаса) дёргаем ручку /api/v1/capture_photo (которая зовёт take_photo). Например, будем звать через cron этот bash-скрипт:
На сервисе сразу появится снимок:
Плюс, не забываем время от времени (например раз в семь дней) чистить старые изображения:
Подключение SX1278 к Raspberry Pi
Для начала подключим к малинке радиомодуль.
Raspberry Pi |
SX1278 |
3.3V |
3.3V |
GROUND |
GROUND |
GPIO10 |
MOSI |
GPIO9 |
MISO |
GPIO11 |
SCK |
GPIO8 |
NSS/ENABLE |
GPIO4 |
DIO0 |
GPIO22 |
RST |
Соединяем пины Raspberry Pi и SX1278 как на картинке:
По поводу использования LoRa-модулей хочу обратить внимание на несколько моментов:
Перед подачей питания на модуль LoRa обязательно убедитесь, что к нему подключена антенна, иначе есть риск, что модуль сгорит!
На качество сигнала помимо антенны влияют правильные настройки, весьма важно, чтобы частоты приёмника и передатчика совпадали, а диапазон был свободен от шума (например игрушечных радиоуправляемых машинок)
Программа
Программа передатчика
Сперва рассмотрим программу передающей части:
Для передачи влажности и температуры в одном сообщении я соединяю их вместе. Сначала данные считываются в переменную как целые числа, потом целые числа преобразовываются в массив символов, а затем они соединяются друг с другом. На приемной стороне данные будут разделены на отдельные символы. Делая это, я ограничиваю себя двумя цифрами градусов. Если датчик находится в среде с температурой менее 10°C, я буду получать на дисплее символы мусора. Например, если температура составляет 20°C, а влажность – 45%, то будет передаваться сообщение 2045, и всё хорошо. Если температура равна 9°C, а влажность – 78%, то передастся сообщение 978x, где «x» – случайный символ. Поэтому, если вы будете собирать данный беспроводной термометр, я советую вам изменить программу для передачи правильных данных, когда температура будет меньше 10°C.
Программа приемника
Интересный способ использования библиотеки LiquidCrystal – это создание пользовательских символов. С помощью я создал символ градусов. Таким же способом вы можете создать и свои собственные символы. Чтобы создать пользовательский символ или значок, вам необходимо объявить его, как массив из восьми байт, и «нарисовать», какие пиксели будут включены (1 – включен, 0 – выключен).
В функции вы создаете его с помощью . принимает два аргумента: номер позиции для хранения символа и массив байт, в котором определено, какие пиксели будут отображаться. В нашем случае это . Затем символ выводится на LCD с помощью функции .
Пояснения к коду
- Очень часто бывает полезно обмениваться данными, например, с компьютером. В частности, для отладки работы устройства: можно, например, смотреть, какие значения принимают переменные.
-
В данном эксперименте мы знакомимся со стандартным объектом , который предназначен для работы с последовательным портом (UART) Arduino, и его методами (функциями, созданными для работы с данным объектом) , и , которые вызываются после точки, идущей за именем объекта:
-
чтобы обмениваться данными, нужно начать соединение, поэтому вызывается в
- отправляет содержимое . Если мы хотим отправить текст, можно просто заключить его в пару двойных кавычек: . Кириллица, скорее всего, будет отображаться некорректно.
- делает то же самое, только добавляет в конце невидимый символ новой строки.
-
- В и можно использовать второй необязательный параметр: выбор системы счисления, в которой выводить число (это может быть , , , для десятичной, двоичной, шестнадцатеричной и восьмеричной систем счисления соответственно) или количество знаков после запятой для дробных чисел.
Например,
Serial.println(18,BIN); Serial.print(3.14159,3);
в мониторе порта даст результат
10010 3.142
- Монитор порта, входящий в Arduino IDE, открывается через меню Сервис или сочетанием клавиш Ctrl+Shift+M. Следите за тем, чтобы в мониторе и в скетче была указана одинаковая скорость обмена данными, . Скорости 9600 бит в секунду обычно достаточно. Другие стандартные значения можете посмотреть в выпадающем меню справа внизу окна монитора порта.
- Вам не удастся использовать цифровые порты 0 и 1 одновременно с передачей данных по последовательному порту, потому что по ним также идет передача данных, как и через USB-порт платы.
- При запуске монитора порта скетч в микроконтроллере перезагружается и начинает работать с начала. Это удобно, если вам нельзя упустить какие-то данные, которые начинаю передаваться сразу же. Но в других ситуациях это может мешать, помните об этом нюансе!
- Если вы хотите читать какие-то данные в реальном времени, не забывайте делать хотя бы на 100 миллисекунд, иначе бегущие числа в мониторе будет невозможно разобрать. Вы можете отправлять данные и без задержки, а затем, к примеру, скопировать их для обработки в стороннем приложении.
- Последовательность выводится как символ табуляции (8 пробелов с выравниванием). Также вы можете использовать, например, последовательность для перевода строки. Если вы хотите использовать обратный слеш, его нужно экранировать вторым таким же: .
Как сделать метеостанцию на LM35
В следующем скетче для определения температуры был использован датчик LM35, подключенный к аналоговому порту. Для точности измерений температуры необходимо будет откалибровать датчик. В этом примере измеряется только температура, при этом данные отправляются на смартфон только в том случае, если произошло изменение температуры или нажата кнопка «Обновить» в приложении.
Скетч для метеостанции на Ардуино с LM35
#include <SoftwareSerial.h> // подключение библиотеки SoftwareSerial.h SoftwareSerial mySerial(2, 3); // указываем пины rx и tx соответственно int temp1; // освобождаем память для переменной "temp1" int temp2; // освобождаем память для переменной "temp2" int temp3; // освобождаем память для переменной "temp3" float temp; // освобождаем память для переменной "temp" byte val; // освобождаем память для переменной "val" String stringT = String("*"); void setup() { pinMode(A0, INPUT); // сенсор LM35 подключим к аналоговому входу A0 Serial.begin(9600); // запуск аппаратного последовательного порта mySerial.begin(9600); // запуск программного последовательного порта } void loop() { temp1 = analogRead(A0); // считываем значение с датчика delay(60000); temp2 = analogRead(A0); // повторно считываем значение с датчика temp3 = temp1 - temp2; // определяем, изменилась ли температура // отправляем сообщение только, когда изменилась температура if (temp3 != 0) { temp = ( temp2/1023.0 )*5.0*1000/10; // вычисляем значение температуры mySerial.println(temp + stringT); // отправляем температуру на телефон Serial.println(temp + stringT); // отправляем температуру на монитор Serial.println(""); } // отправляем сообщение, когда нажата кнопка "обновить" в приложении if (Serial.available()) // проверяем, поступают ли какие-то команды { val = Serial.read(); // переменная val равна полученной команде if (val == '1') { temp = ( temp2/1023.0 )*5.0*1000/10; // вычисляем значение температуры mySerial.println(temp + stringT); // отправляем температуру на телефон Serial.println(temp + stringT); // отправляем температуру на монитор Serial.println(""); } } }
Сборка метеостанции с дисплеем 1602 и DHT11
Для этого проекта нам потребуется:
- плата Arduino UNO (NANO);
- жидкокристаллический дисплей 1602 с I2C;
- цифровой датчик DHT11 или DHT22;
- провода «папа-мама», «папа-папа»;
- макетная плата (при необходимости).
К Arduino Nano и Uno все датчики и дисплей подключаются по одной схеме — распиновка и подключение уже рассматривались на нашем сайте, поэтому не будем подробно останавливаться на этом моменте. Если у вас есть вопросы, то посмотрите следующие записи: Подключение DHT11 к Ардуино и Подключение LCD 1602 к Ардуино. Соберите метеостанцию на Ардуино с дисплеем 1602 и dht11, как на схеме ниже.
Установка сервера
На Raspberry Pi загружаем Raspberry Pi OS Lite.
Далее устанавливаем статический адрес для нашей малинки:
Добавляем\правим строки на наш желаемый IP и IP наш роутер
Теперь включаем удалённый доступ через SSH, SPI (нужен для подключения LoRa), а так же Camera, если планируем её использовать.
Включаем:
-
SSH (если собираемся подключаться по SSH, а не только через клавиатуру)
-
SPI (если собираемся использовать LoRa)
-
Camera (если собираемся использовать камеру)
Убеждаемся, что стоит автологин при загрузке:
Выходим из raspi-config, перезагружаем:
Теперь у нас есть удалённый доступ к малинке, можем подключиться через ssh или можем продолжить через клавиатуру.
Вся логика сервера написана на Python3, поэтому ставим его:
Теперь осталось загрузить собственно мой проект H.O.M.E.:
В качестве веб-сервера я выбрал flask, на Хабре есть отличная серия статей, поэтому я не буду останавливаться на подробностях при работе с ним.
Копируем контент из папки с сервером:
Устанавливаем все зависимости:
Создаём базу данных из шаблона:
Собственно всё, теперь можем запустить сервер:
Но мы же хотим, чтобы сервер запускался при загрузке Raspberry Pi?
Тогда в конце /etc/rc.local, перед exit 0, добавляем вызов bash-скрипта:
Копируем этот скрипт на место:
Я так же считаю, что было бы неплохо иметь скрипт, который проверяет, жив ли ещё сервер, и если он мёртв, то перезапускает его. Копируем и его.
Добавляем в планировщик cron:
задание:
Архитектура
Самым простым и популярным решением для метеостанции является Arduino, однако подружить с его домашней сетью — это дополнительные девайсы\шилды, лишние деньги и сложность, а значит — время. Поэтому из коробки проще использовать модуль уже со встроенным Wi-Fi, например ESP8266 (NodeMCU) с подключенными сенсорами. Это достаточно удобно, что один и тот же модуль можно использовать и дома, и за окном. При желании даже можно его использовать в качестве сервера.
Но почему бы не проставить в центр системы лучше что-то помощнее? Благо у меня пылится без дела Raspberry Pi первой ревизии (но и любая другая подойдёт). Внутренние датчики можно подключить, в принципе через GPIO и к малинке напрямую, но у меня роутер с малинкой в одной комнате установлен, а мониторить нужно другую. Если у вас такой проблемы нет — то можно от одной NodeMCU избавиться. Малинка будет получать данные от датчиков, сохранять их в базе данных и при необходимости отображать. Так же к GPIO Raspberry Pi можно подцепить LoRa — приёмник и получать данные от удалённых за пределами Wi-Fi сети датчиков (и вот они Arduino). Ну, и наконец, малинка будет отправлять данные в облако.
Итого, нам понадобится:
-
Raspberry PI
-
ESP8266 (2шт. + 1шт. опционально)
-
BME280 (2 шт.)
-
Часы реального времени DS1302 (опционально)
-
OLED-дисплей 128х64 на SH1106 (опционально)
-
Датчик дождя на компараторе LM373 (опционально)
-
УФ-датчик GY-VEML6070 (опционально)
-
Raspberry Pi Camera (опционально)
-
Arduino Nano (2 шт., опционально)
-
SX1278 (3 шт., опционально)
-
Магнитный компас с чипом QMC5883L/HMC5883L (опционально)
-
Датчик освещённости (светодиодный) с компаратором LM737 (опционально)
-
Датчики напряжения до 25V (опционально)
-
Датчики тока ACS712 (опционально)
Датчик на Arduino Uno и плате расширения Troyka Shield
Рассмотрим еще одну погодную станцию. Ее особенности:
- использование цифрового метеосенсора troyka;
- термометр DS18B20;
- барометр Troyka V2.
- хранение данных на карточке MicroSD — для удобства их последующего анализа на любом устройстве.
Компоненты
Для проекта требуются:
- контроллер Arduino Uno;
- плата расширения Troyka Shield;
- метеодатчик;
- четырехразрядный цифровой дисплей-индикатор;
- барометр с troyka-блоком подтяжки;
- картридер и карточка micro-SD.
Порядок сборки
Система собирается по шагам.
- Установить плату расширения на Ардуино.
- Подключить к пинам шины I2C метеодатчик.
- Подсоединить дисплей в разъемы e-f на схеме. Пин CS идет на пин 10 микрокомпьютера Ардуино.
- Барометр вставляется в слот B, пины шины I2C.
- Термометр подключается в слот C, пин 4. Для его работы потребуется дополнительный модуль подтяжки.
- И, наконец, к слоту D и на пин 8 подключается картридер.
Что ещё можно сделать?
- Мы установили только сенсор температуры и влажности. Но у Teensy остаётся ещё много свободных ножек, т.ч. можно добавить разных датчиков: освещённости, атмосферного давления, скорости ветра и т.д.
- Teensy прямо на борту имеет часы реального времени (RTC). Для их работоспособности не хватает только кварца. Можно купить кварц на 32,768 КГц в любом магазине радиоэлементов и припаять его. Тогда можно пробуждать Teensy по будильнику RTC. Достоинство в том, что можно будить устройство чаще в те часы, когда нужны более точные показания. Например, в рабочее время будить устройство каждые 5 минут, а в остальное — каждые полчаса.