Метеостанция на ардуино своими руками

Ардуино. Метеостанция на LCD 1602 и DHT11

Ардуино. Метеостанция с дисплеем LCD 1602 и DHT22 После сборки схемы, загрузите в микроконтроллер следующий скетч (здесь ссылка на скачивание архива со скетчем для метеостанции и необходимыми библиотеками). Информация с датчика DHT22 выводиться будет на монитор порта Arduino IDE и на жидкокристаллический дисплей 1602a, для отображения информации использован русский шрифт для LCD и символы (в скетче есть подробные комментарии).

Скетч для метеостанции с DHT11 на Ардуино

#include <Wire.h> // библиотека для протокола IIC #include <LiquidCrystal_I2C.h> // подключаем библиотеку LCD IIC LiquidCrystal_I2C lcd(0x27,20,2); // присваиваем имя lcd для дисплея #include «DHT.h» // подключаем библиотеку для DHT11 DHT dht(2, DHT11); // к какому порту подключаем датчик // создаем символ градуса и присваиваем имя «gradus» byte gradus = { 0b01100,0b10010,0b10010,0b01100,0b00000,0b00000,0b00000,0b00000 }; // создаем русскую букву «П» byte P = { 0b11111,0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b00000 }; // создаем русскую букву «У» byte Y = { 0b10001,0b10001,0b10001,0b01111,0b00001,0b00001,0b01110,0b00000 }; // создаем русскую букву «Л» byte L = { 0b00111,0b01001,0b10001,0b10001,0b10001,0b10001,0b10001,0b00000 }; // создаем русскую букву «Ж» byte ZH = { 0b10101,0b10101,0b10101,0b01110,0b10101,0b10101,0b10101,0b00000 }; // создаем русскую букву «Ь» byte znak = { 0b10000,0b10000,0b10000,0b11110,0b10001,0b10001,0b11110,0b00000 }; void setup() { Serial.begin(9600); // запуск последовательного порта lcd.init(); // инициализация LCD дисплея lcd.backlight(); // включение подсветки дисплея lcd.createChar(1, gradus); lcd.createChar(2, P); lcd.createChar(3, Y); lcd.createChar(4, L); lcd.createChar(5, ZH); lcd.createChar(6, znak); } void loop() { // если нужны точные значение, то используйте float, вместо byte byte h = dht.readHumidity(); // считываем значение температуры byte t = dht.readTemperature(); // считываем значение влажности Serial.print(«Temperature: «); Serial.println(t); // отправляем значение температуры на монитор Serial.print(«Humidity: «); Serial.println(h); // отправляем значение температуры на монитор Serial.println(» «); // пустая строка lcd.setCursor(0,0); // ставим курсор на 1 символ первой строки lcd.print(«TEM»); // используем латинские буквы lcd.print(char(2)); // выводим русскую букву «П» lcd.print(«EPAT»); // используем латинские буквы lcd.print(char(3)); // выводим русскую букву «У» lcd.print(«PA: «); // используем латинские буквы lcd.print(t); // выводим значение температуры на LCD lcd.print(char(1)); // выводим знак градуса lcd.setCursor(2,1); // ставим курсор на 3 символ второй строки lcd.print(«B»); // используем латинские буквы lcd.print(char(4)); // выводим русскую букву «Л» lcd.print(«A»); // используем латинские буквы lcd.print(char(5)); // выводим русскую букву «Ж» lcd.print(«HOCT»); // используем латинские буквы lcd.print(char(6)); // выводим русскую букву «Ь» lcd.print(«: «); // используем латинские буквы lcd.print(h); // выводим значение влажности на LCD lcd.print(«%»); // выводим знак процент delay(1000); }

Пояснения к коду:

  1. в скетче можно использовать до 8 русских букв и символов, при необходимости заменяйте буквы из кириллицы — латинскими буквами;
  2. скорость обновления данных замените на необходимое значение.

Заключение. Мы рассмотрели, как сделать простую домашнюю метеостанцию на Ардуино c дисплеем 1602а и датчиком температуры и влажности воздуха DHT11. Данный проект можно доработать, добавив к схеме еще больше датчиков для анализа метеоусловий. Также можно сделать беспроводную метеостанцию на Arduino Uno, используя блютуз или радио модули для передачи информации на расстояние.

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

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

Подключение датчика bmp180 к Ардуино

Для этого занятия нам потребуется:

  • плата Arduino Uno / Arduino Nano / Arduino Mega;
  • датчик давления BMP180 (GY-68);
  • дисплей LCD 1602;
  • провода «папа-мама».

Метеостанция на ардуино своими руками
Как подключить датчик давления bmp180 к Arduino

BMP180 (GY-68) Arduino Uno Arduino Nano Arduino Mega
GND GND GND GND
VIN 5V 5V 5V
SDA A4 A4 20
SCL A5 A5 21

Подключение к микроконтроллеру Ардуино осуществляется по интерфейсу I2C. Контакты SCL / SDA и питание модуля выведены на группу контактов. Кроме того, для работы с датчиком потребуется установить библиотеку BMP180 Breakout Arduino Library, которая позволяет упросить работу с модулем. Команды для bmp180 (bmp080) и gy-68 одинаковые, так что библиотека подойдет для всех перечисленных барометров.

Дисплей 16×4 LCD1604

Подробнее о дисплее и работе с ним погуглите «Работа с символьными ЖКИ на базе HD44780». Отметим, что нужно внимательно отнестись к полярности подключения питания к ЖК-индикатору и чтобы напряжение питания было в диапазоне +4,5…5,5 В. Невнимательное отношение к этому может привести к выходу индикатора из строя!

Пин LCD 1604 Arduino MEGA Arduino UNO Описание
VSS GND GND GND
VDD 5 V 5 V 4,7 — 5,3V
RS 22 4 Высокий уровень означает, что сигнал на выходах DB0—DB7 является данными, низкий — командой
RW GND GND Определяет направление данных (чтение/запись). Так как операция чтения данных из индикатора обычно бывает невостребованной, то можно установить постоянно на этом входе низкий уровень
E 23 5 Импульс длительностью не менее 500 мс на этом выводе определяет сигнал для чтения/записи данных с выводов DB0-DB7, RS и WR
DB4 24 8 Входящие/исходящие данные
DB5 25 9
DB6 26 10
DB7 27 11
LED A+ +5V или резистор 220 Ом → +5VLED-A
LED B- GND
V0 GND или подстроечник на 10кОм

Программная инициализация будет выглядеть так:

Температура, влажность DHT11

Подключение датчика температуры и влажности DHT11 (SainSmart). Датчик расположите лицевой стороной вверх, выводы будут описаны слева направо.

DHT11 Arduino Mega
DATA Digital pin 2 (PWM) (см. ниже DHTPIN)
VCC 3,3—5 В (рекомендуется 5 В, лучше внешнее питание)
GND GND

Программная инициализация

Барометр BMP180

Подключение датчика атмосферного давления BMP180 (барометр) + температура по интерфейсу I2C/TWI.

BMP180 Arduino Mega
VCC не подключен
GND GND
SCL 21 (SCL)
SDA 20 (SDA)
3,3 3,3 В

Для UNO: A4 (SDA), A5 (SCL).

nRF24L01+

Краткие характеристики:

  • Диапазон частот 2,401 — 2,4835 Ггц
  • 126 каналов. Нулевой канал начинается с 2400 Мгц и далее с шагом 1 Мгц, например 70 канал находится соответственно на 2470 Мгц. При установке скорости передачи 2Mbps занимается ширина канала в 2 Мгц
  • Питание 1,9 — 3,6 В (рекомендуется 3,3 В)

Вот распиновка модуля.

Некоторые советуют сразу же припаять керамический конденсатор 100nF (можно 1µF, 10µF) на выводы питания RF для избежания электрических помех.

Распиновка nRF24L01+ (смотреть сверху платы там где чип, пины должны быть внизу) :

пин 2 3,3V пин 4 CSN пин 6 MOSI пин 8 IRQ
пин 1 GND пин 3 CE пин 5 SCK пин 7 MISO

Подключение для метеостанции:

Arduino Mega nRF24L01+
3,3 В VCC пин 2 (лучше внешнее питание)
пин D8 CE пин 3 (chip enable in)
SS пин D53 CSN пин 4 (chip select in)
SCK пин D52 SCK пин 5 (SPI clock in)
MOSI пин D51 SDI пин 6 (SPI Data in)
MISO пин D50 SDO пин 7 (SPI data out)
IRQ пин 8 (Interrupt output) не подсоединен
GND GND пин 1 (ground in)
Популярные статьи  Инверторный генератор — как устроен и работает

Программирование радиомодуля будет подробно описано в программной части.

ESP8266

Распиновка ESP8266 (смотреть сверху платы там где чипы, пины должны быть внизу):

GND GPIO2 GPIO0 RX
TX CH_PD RESET VCC

Подключение ESP8266 для метеостанции:

ESP8266 Arduino Mega
TX 10 пин (SoftwareSerial RX)
RX 11 пин (SoftwareSerial TX)
VCC 3,3 В
GND GND
CH_PD Через резистор 10К к 3,3 В Arduino
GPI0 Необязательно. Через резистор 10К к 3,3 В Arduino
GPI2 Необязательно. Через резистор 10К к 3,3 В Arduino

КДПВ

Центральный блок в сборе. «Материнскую плату» вырезал из картонной коробки из-под обуви и к ней винтиками на 3 прикрутил всё остальное.

Как видим в этом месте всё питание осуществляется от пинов Ардуино, т.е. к блоку питания напрямую ничего не идёт, и пока мощи хватает.

Вроде всё. Ничего не забыл.

Паяйте, соединяйте. В следующей части будет приведен рабочий скетч для центрального блока и наша метеостанция уже что-то покажет.

Исходный код

Код автономной части

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

Код:

Копируем этот код и вставляем в IDE

#include <LCD_1602_RUS.h> // подключаем библиотеку для датчика
LCD_1602_RUS lcd(0x27, 20, 4); // определяем адрес дисплея и его размер
#include <DHT.h> // подключаем библиотеку для датчика
DHT dht(2, DHT11); // сообщаем на каком порту будет датчик

void setup()
{
lcd.init(); // Инициализация дисплея
lcd.backlight(); // Подключение подсветки
lcd.clear(); // Чистим дисплей
dht.begin(); // запускаем датчик DHT11
}
void loop()
{
float h = dht.readHumidity(); // считываем температуру (t)
float t = dht.readTemperature(); // и влажность (h)
lcd.setCursor(0, 0); // Устанавливаем курср на нулевую символ и нулевой строки
lcd.print(«Влажн. :»); // выводим надпись «Влажн.:»
lcd.print(h,1); // выводим значение влажности с одним символом после запятой
lcd.print(» %»); // выволим знак процента
lcd.setCursor(0, 1); // Устанавливаем курср на нулевой символ первой строки
lcd.print(«Темпер.:»); // выводим надпись «Темпер.:»
lcd.print(t,1); // выводим значение влажности с одним символом после запятой
lcd.print(«\337C»); // выволим знак градуса (337 символ в талице) и «С»
delay(2000); // ждём 2000 микросикенд (2 секунды)
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

#include <LCD_1602_RUS.h>         // подключаем библиотеку для датчика

LCD_1602_RUS lcd(0x27,20,4);// определяем адрес дисплея и его размер

#include <DHT.h>                  // подключаем библиотеку для датчика

DHT dht(2,DHT11);// сообщаем на каком порту будет датчик

voidsetup()

{

lcd.init();// Инициализация дисплея  

lcd.backlight();// Подключение подсветки

lcd.clear();// Чистим дисплей

dht.begin();// запускаем датчик DHT11

}

voidloop()

{

floath=dht.readHumidity();// считываем температуру (t)

floatt=dht.readTemperature();// и влажность (h)

lcd.setCursor(,);// Устанавливаем курср на нулевую символ и нулевой строки

lcd.print(«Влажн. :»);// выводим надпись «Влажн.:»

lcd.print(h,1);// выводим значение влажности с одним символом после запятой

lcd.print(» %»);// выволим знак процента

lcd.setCursor(,1);// Устанавливаем курср на нулевой символ первой строки  

lcd.print(«Темпер.:»);// выводим надпись «Темпер.:»

lcd.print(t,1);// выводим значение влажности с одним символом после запятой

lcd.print(«\337C»);// выволим знак градуса (337 символ в талице) и «С»

delay(2000);// ждём 2000 микросикенд (2 секунды)

}

Копируем его в поле для кода IDE:

и жмём загрузить:

Кнопка «загрузить»
Загрузка завершена

Ждём несколько секунд и наша метеостанция работает:

Метеостанция работает

Барометр на Ардуино своими руками

#include <Wire.h>
#include <SFE_BMP180.h>

SFE_BMP180 pressure; // создаем объект pressure
#define ALTITUDE 1655.0 // высота офиса SparkFun, штат Колорадо, в метрах

void setup(){
   Serial.begin(9600);  // запускаем монитор порта
   pressure.begin();     // запускаем датчик давления
}

void loop(){
   char status;
   double T,P,p0,a;

   // для точного измерения, следует знать высоту, на которой производятся замеры
   // в этом примере используется константа ALTITUDE
   Serial.println();
   Serial.print("provided altitude: ");
   Serial.print(ALTITUDE,0);
   Serial.println(" meters");
  
   // перед измерением давления, следует узнать температуру
   // если запрос успешен, то возвращается время ожидания в миллисекундах
   // если запрос на измерение температуры не успешен, то возвращается 0
   status = pressure.startTemperature();
   if (status != 0){
      delay(status);

      // результат измерения температуры сохраняется в переменной T
      status = pressure.getTemperature(T);
      if (status != 0){
         Serial.print("temperature: ");
         Serial.print(T,2);
         Serial.println(" deg C");

         // запускаем измерение давления
         // если запрос успешен, возвращается время ожидания в миллисекундах
         // если запрос на измерение давления не успешен, возвращается 0
         status = pressure.startPressure(3);
         if (status != 0){
            delay(status);

            status = pressure.getPressure(P,T);
            if (status != 0){
               Serial.print("absolute pressure: ");
               Serial.print(P,2);
               Serial.print(" mb, ");
               Serial.print(P*0.0295333727,2);
               Serial.println(" inHg");

              // датчик bmp180 возвращает абсолютное давление, которое зависит от высоты
              // параметры: P = абсолютное давление в мб, ALTITUDE = текущая высота в м.
              // результат: p0 = давление с компенсацией на уровне моря в мбар
              p0 = pressure.sealevel(P,ALTITUDE);
              Serial.print("relative (sea-level) pressure: ");
              Serial.print(p0,2);
              Serial.print(" mb, ");
              Serial.print(p0*0.0295333727,2);
              Serial.println(" inHg");
           }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");

  delay(5000);
}

Пояснения к коду:

  1. чтобы убрать влияние высоты при измерении атмосферного давления, используйте функцию уровня моря и текущую высоту;
  2. скачать библиотеку SFE_BMP180.h для работы с датчиком атмосферного давления BMP180 Arduino можно на нашем сайте здесь.
Популярные статьи  Тормозные режимы работы двигателя с последовательным возбуждением

Шаг третий. Подключаем ЖК-экран

Теперь я отучу свою метеостанцию от компьютера: добавлю собственный экранчик и выведу на него температуру в двух шкалах — Цельсия и Фаренгейта.

Метеостанция на ардуино своими руками

Из кода программы я уберу команды, которые вызывали последовательный порт и группировали данные для отправки на компьютер.

Вместо них добавлю команды для работы с LED-дисплеем: подключение библиотеки, определение контактов и формирование строк. Первая строка меняться не будет, а во вторую выведу сразу два значения температуры: в градусах Цельсия и Фаренгейта.

У нас получилась простая метеостанция, которая умеет работать самостоятельно и передавать данные на компьютер. Это самый простой кирпичик для создания умного дома. Такие устройства можно использовать для контроля температуры в комнатах и парниках, управления системами отопления и подогрева воды, в качестве противопожарной сигнализации. Всё зависит только от вашей фантазии.

Метеостанция на ардуино своими руками

Станция с датчиком давления

Следующая модель будет уметь определять:

  • влажность и температуру;
  • уровень высоты;
  • атмосферное давление.

Компоненты

Для сборки потребуются:

  • сенсор DHT22;
  • датчик давления BMP180;
  • плата Ардуино Нано;
  • lcd-экран с блоком I2C;
  • резистор 10 кОм;
  • плата макетная;
  • припой;
  • 40-контактный однорядный разъем;
  • соединительные провода.

Придется паять и работать с контактами, поэтому также необходим паяльник и плоскогубцы.

Сенсор давления

Таковым послужит барометрический датчик с интерфейсом I2C BMP180. Он станет контролировать абсолютное значение параметра вокруг себя.  Падение обычно сигнализирует о приближении грозы и наступлении дождя (поскольку им сопутствует область низкого давления), а увеличение, наоборот, говорит о прохождении области низкого давления и наступлении ясной сухой погоды.

Давление всегда зависит от высоты над уровнем моря и погодных условий в зоне измерения. Но в нашем случае измеряется относительное — как если бы метеостанция находилась на уровне моря.

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

Еще один важный момент — светочувствительность. Благодаря силикону в конструктиве BMP180 он способен улавливать попадающий через отверстие в корпусе микрочипа свет и нагреваться. Максимально точные измерения потребуют изоляции от окружающего света.

BMP180 соединяется через шину I2C по следующей схеме:

A4 — SDA;

A5 — SCL;

3.3V — VCC;

GND — GND.

Сборка

Процесс сборки начинается с монтажа однорядных разъемов для DHT22 и Arduino:

От вывода DATA к GND припаян резистор на 10 кОм.

Далее монтируется разъем для BMP180 (питаться датчик будет от линии 3.3 В). Компоненты соединяются шиной I2C.

На последнем этапе та же шина соединяется с дисплеем.

Так выглядит домашняя метеостанция в сборе:

Пример вывода информации об атмосферном давлении:

Программный код

Для работы понадобятся скетч Ардуино и библиотеки датчиков. Все они доступны в приложениях к статье.

Текст скетча можно скачать здесь: https://cloud.mail.ru/public/piwT/gew8pPv7M

Как сделать метеостанцию на 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("");
}
  }

}

Android

Теперь напишем простое приложение для Андроид, которое запрашивает, получает, декодирует JSON-данные и отображает информацию на экране.

Наше Android-приложение будет простым насколько это возможно, только сама суть технологии. Далее вокруг этого «скелета» уже можно будет наворачивать различные «красивости».

Вот скриншот того, что должно получиться в итоге

Как видим UI просто спартанский, основан на LinearLayout, ничего лишнего.

В верхней части TextView показывает ID датчиков и их метео-данные. Кнопка «Обновить» инициирует повторный запрос к веб-серверу. Далее в EditText расположена единственная настройка программы — это URL запроса в виде

Что необходимо отметить?

В манифест добавьте строки разрешающие интернет и проверку состояния сетевого соединения :

Работа с сетью и получение данных с веб-сайта происходит следующим образом.

Используем AsyncTask, чтобы создать фоновую задачу отдельно от главного потока пользовательского интерфейса. Эта фоновая задача берет URL запроса и использует его для создания .

После того, как соединение установлено, AsyncTask загружает содержимое веб-страницы (JSON) как InputStream. Далее InputStream преобразуется в строку, которая декодируется с помощью JSONObject и отображается в пользовательском интерфейсе методом .

В MainActivity.java измените URL на ваш :

он будет использоваться по умолчанию при первом запуске Android приложения.

PHP и веб-сервер

Все настройки веб-интерфейса хранятся в . Измените его в соответствии с вашими настройками базы данных.

Задайте свой часовой пояс в формате PHP

Все доступные часовые пояса описаны здесь.

Задайте свой секретный ключ для доступа (в виде числа) который должен совпадать с константой из скетча

В нашем веб-сервере нет авторизации, входа по паролю, это усложнило бы всю конструкцию. Для прототипа это не нужно. Поэтому вся защита построена на файле , отсутствии и на этом секретном ключе для доступа.

Основной PHP скрипт принимает простой HTTP GET запрос с данными и сохраняет их в соответствующие таблицы базы данных. Если ключ не совпадает, то запрос будет отвергнут.

Скрипт используется для просмотра таблиц данных и содержит гиперссылки на остальные скрипты веб-интерфейса. Вызывайте его так

Например

выводит простые таблички, где надо помнить, что :

  • датчик с id 11 это домашний датчик на сервере,
  • датчик с id 20 это заоконный датчик.

Скрипт содержит функции, общие для всех PHP скриптов.

Скрипт отвечает за рисование графиков при помощи Google Charts. Вот, например, график питающего напряжения заоконного датчика. Напряжение повышается в солнечный день за счёт солнечной же батареи и затем блок питания на аккумуляторах постепенно разряжается.

экспортирует данные из таблиц базы данных MySQL в файл формата CSV. Для дальнейшего импорта и анализа в электронных таблицах.

Популярные статьи  Регулирование частоты в энергосистеме

экспортирует данные о напряжении питания заоконного датчика из базы данных MySQL в файл формата CSV. Полезно для отладки.

очищает все таблицы, т.е. удаляет все наши данные. Полезно для отладки. На этот скрипт нет ссылок из , поэтому вызывать его надо по прямой ссылке в адресной строке браузера с указанием .

При приёме данных повсеместно используется функция для предотвращения попадания в БД некорректных значений.

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

ESP8266, WiFi и передача данных

И вот теперь возвращаемся к скетчу , к той его части, которая соединяется с точкой доступа WiFi и отсылает данные на веб-сервер.

Как я уже писал, мне не удалось найти нормальную библиотеку для Arduino для управления модулем ESP8266 с помощью AT команд, пришлось «колхозить» самому. Напомню так же, что вам придется прошить в ESP8266-01 прошивку определённой версии. И теперь когда всё готово, разберём как это работает.

Для доступа к веб серверу в скетче необходимо изменить вот эти константы

В в функции сначала производится переключение ESP8266 в режим Station, т.е. он начинает работать как WiFi клиент

и далее следует подключение к точке доступа

Если подключения не происходит, то попытка повторяется (однократно)

Затем выбирается режим одиночного подключения TCP/IP

При отсылке данных от датчиков типа DHT на вебсервер используется функция с указанием типа данных как

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

На вход функция принимает строку HTTP GET запроса и отправляет её по назначению на веб-сервер.

Внутри себя проверяет доступность ESP модуля, посылая ему команду «AT», далее проверяется подключение к WiFi и производится переподключение, если необходимо. Затем отправляются данные и соединение TCP закрывается.

Android приложение

В наше время, когда уже каждый может мигать светодиодом, никакой метеостанцией никого не удивишь. Но если поделка умеет связываться с сервером через WiFi, имеет веб-морду и мобильное приложение, то это уже кое-что! Под сервером здесь имеется в виду конечно же сервер приложений, т.е. в нашем случае это PHP-обвязка и СУБД MySQL. Не достаёт вишенки на торте, а именно приложения под Android написанием которого мы сейчас и займёмся.

Что это такое?

Наша метеостанция будет состоять из двух устройств: компактного автономного
устройства, измеряющего погодные показатели, и устройства-ретранслятора,
получающего эти показатели и отправляющего их на «народный мониторинг».
Устройства будут связываться по беспроводному каналу связи на частоте 433 МГц.
Автономная часть будет питаться от трёх пальчиковых батареек и сможет
просуществовать на одном комплекте батарей до года при периоде опроса датчиков
в 20 мин.

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

Скетч

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, чтобы построить графики
}

Что понадобится

    — микроконтроллер Arduino Uno
    — термистор (терморезистор)
    — сопротивление на 10 кОм
    — семисегментный индикатор
    — макетная плата
    — соединительные провода «папа-папа»

Метеостанция на ардуино своими руками

Основой метеостанции станет термистор — элемент, сопротивление которого меняется в зависимости от температуры. Сначала я выведу информацию с сенсора на экран ноутбука, а когда разберусь со всеми этими вольтами, омами и градусами — добавлю ЖК-экран, чтобы станция работала и без компьютера.

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

Общий принцип работы

Измеряющая данные окружающей среды метеостанция на Ардуино состоит из нескольких основных компонентов:

  • собственно плата управления Arduino (например, Uno). На нее поступает информация со внешних датчиков, контроллер выполняет вычисления и выводит информацию на экран;
  • электронный дисплей — служит для отображения поступивших с контроллера данных в понятной человекочитаемой форме;
  • сенсор влажности температуры. В подобных схемах популярны датчики DHT11 и DHT22. Они регистрируют данные среды и отдают их контроллеру;
  • макетная плата — основа для сборки всех компонентов. На ней фиксируются все элементы метеостанции, по ней же прокладываются электрические соединения;
  • соединительные провода — с «оголенными» концами под пайку или оснащенные штекерами.

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

HTTP GET и JSON

Вопрос, который нужно решить в первую очередь — это каким образом будет происходить передача данных от веб-сервера к Андроид-приложению.

Придумывать тут ничего не нужно, всё уже придумано за нас — это HTTP GET и JSON.

В нашем случае простой GET запрос к веб-серверу можно составить и отладить вручную, пока Андроид приложение ещё не готово.

В Java и в Android есть готовые библиотеки для обработки данных в формате JSON. JSON текстовый формат, читается человеком, что полезно для отладки.

Для того, чтобы сформировать текущие данные от датчиков метеостанции создадим на веб-сервере новый PHP скрипт last-data-to-json.php.

Вызов скрипта :

где , как мы помним, это секретный ключ доступа к БД.

Пример ответа в формате JSON :

Необходимо напомнить, что у нас 3 датчика. Их ID и тип (DHT или BMP) жёстко закодированы по всему коду метеостанции. Такой способ хардкордного кодирования идеологически неверен, но для наколенного прототипа (где необходимо быстрое и простое решение) это разумный компромисс.

Скрипт берет из БД самые последние данные от этих разнотипных датчиков и упаковывает в формат JSON. Выборка данных из БД «с конца» просходит таким способом :

Оцените статью
Добавить комментарии

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: