Делаем метеостанцию на базе arduino

Виды датчиков

Для измерения параметров среды часто применяют три вида сенсоров:

  • 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.

Порядок сборки

Система собирается по шагам.

  1. Установить плату расширения на Ардуино.
  2. Подключить к пинам шины I2C метеодатчик.
  3. Подсоединить дисплей в разъемы e-f на схеме. Пин CS идет на пин 10 микрокомпьютера Ардуино.
  4. Барометр вставляется в слот B, пины шины I2C.
  5. Термометр подключается в слот C, пин 4. Для его работы потребуется дополнительный модуль подтяжки.
  6. И, наконец, к слоту D и на пин 8 подключается картридер.

Что ещё можно сделать?

  1. Мы установили только сенсор температуры и влажности. Но у Teensy остаётся ещё много свободных ножек, т.ч. можно добавить разных датчиков: освещённости, атмосферного давления, скорости ветра и т.д.
  2. Teensy прямо на борту имеет часы реального времени (RTC). Для их работоспособности не хватает только кварца. Можно купить кварц на 32,768 КГц в любом магазине радиоэлементов и припаять его. Тогда можно пробуждать Teensy по будильнику RTC. Достоинство в том, что можно будить устройство чаще в те часы, когда нужны более точные показания. Например, в рабочее время будить устройство каждые 5 минут, а в остальное — каждые полчаса.
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector