Перейти к основному содержимому

Настольная метеостанция на Arduino Uno

Эта метеостанция измеряет температуру, относительную влажность и атмосферное давление датчиком BME280. Arduino выводит значения на символьный дисплей 20×4 и раз в десять минут сравнивает давление с предыдущим значением.

Реальный вывод температуры, влажности, давления и графика на дисплей 20×4

Фото работающей метеостанции: ragingradish, Arduino Project Hub. В нашем варианте вывод упрощён, чтобы полностью поместиться в один понятный скетч.

Результат

На дисплее постоянно видны:

Temp:   23.4 C
Hum: 45.2 %
Press: 1008.6 hPa
Trend: stable

Надпись rising означает рост давления более чем на 0,5 гПа за десять минут, falling — такое же снижение, stable — меньшее изменение. Это только наблюдение за тенденцией, а не самостоятельный прогноз погоды.

Детали

ДетальКоличествоТочная конфигурация
Arduino Uno R31плата на ATmega328P
BME2801Adafruit BME280 breakout, product 2652, допускает питание и логику 5 В
LCD 2004A1символьный дисплей 20×4 на контроллере HD44780, без I2C-переходника
Потенциометр 10 кОм1настройка контраста
Резистор 220 Ом1подсветка дисплея
Макетная плата и провода1 наборсоединения без пайки
USB-кабель и USB-блок 5 В1питание после программирования

Здесь указан конкретный модуль Adafruit, потому что безымянные платы GY-BME280 бывают рассчитаны только на 3,3 В. Не заменяйте модуль, пока не проверите схему питания и уровни логики его платы.

Как устроен проект

BME280 передаёт данные по I2C: у Arduino Uno это выводы A4 (SDA) и A5 (SCL). Дисплей подключён четырёхбитной параллельной шиной. Поэтому датчик использует только две сигнальные линии, а дисплей — шесть.

Проект питается от USB. Напряжения выше 5 В и отдельный источник не нужны.

Схема BME280

На плате Adafruit подписи могут быть Vin, GND, SCK, SDI.

BME280Arduino Uno
Vin5V
GNDGND
SCKA5 / SCL
SDIA4 / SDA

Выводы SDO и CS не подключайте. Код сначала проверяет адрес 0x76, затем 0x77.

Схема дисплея 20×4

Смотрите на дисплей со стороны символов, а ряд из 16 выводов держите сверху или снизу согласно маркировке платы. Ориентируйтесь по номерам, а не по положению на фотографии.

Вывод LCDНазваниеПодключение
1VSSGND
2VDD5V
3VOсредний вывод потенциометра 10 кОм
4RSArduino D7
5RWGND
6EArduino D8
7–10D0–D3не подключать
11D4Arduino D9
12D5Arduino D10
13D6Arduino D11
14D7Arduino D12
15A / LED+5V через 220 Ом
16K / LED-GND

Один крайний вывод потенциометра подключите к 5V, второй — к GND, средний — к VO дисплея.

Сборка

  1. При отключённом USB соберите цепи питания 5V и GND на макетной плате.
  2. Подключите LCD, затем потенциометр и резистор подсветки.
  3. Подключите BME280 четырьмя проводами.
  4. Проверьте каждое соединение по таблице от источника к приёмнику.
  5. Датчик разместите на проводах длиной 10–20 см в стороне от Arduino и подсветки: нагретая плата завышает температуру.
  6. Не закрывайте отверстие датчика клеем, скотчем или корпусом без вентиляции.
  7. Только после проверки подключите USB.

Библиотеки

В Arduino IDE откройте Инструменты → Управлять библиотеками и установите:

  • Adafruit BME280 Library;
  • Adafruit Unified Sensor.

Библиотека LiquidCrystal входит в стандартную поставку Arduino IDE.

Программа

#include <Wire.h>
#include <LiquidCrystal.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
Adafruit_BME280 bme;

const unsigned long READ_PERIOD_MS = 2000;
const unsigned long TREND_PERIOD_MS = 10UL * 60UL * 1000UL;
const float TREND_THRESHOLD_HPA = 0.5;

unsigned long lastReadAt = 0;
unsigned long referenceAt = 0;
float referencePressure = 0;
const char *trendText = "waiting";

void printValue(byte row, const char *label, float value, const char *unit) {
lcd.setCursor(0, row);
lcd.print(label);
lcd.print(value, 1);
lcd.print(unit);
lcd.print(" ");
}

void setup() {
Serial.begin(9600);
lcd.begin(20, 4);
lcd.clear();
lcd.print("Weather station");
lcd.setCursor(0, 1);
lcd.print("BME280 search...");

bool found = bme.begin(0x76);
if (!found) found = bme.begin(0x77);

if (!found) {
lcd.clear();
lcd.print("BME280 not found");
lcd.setCursor(0, 1);
lcd.print("Check A4/A5");
while (true) delay(100);
}

referencePressure = bme.readPressure() / 100.0F;
referenceAt = millis();
lcd.clear();
}

void loop() {
unsigned long now = millis();
if (now - lastReadAt < READ_PERIOD_MS) return;
lastReadAt = now;

float temperature = bme.readTemperature();
float humidity = bme.readHumidity();
float pressure = bme.readPressure() / 100.0F;

if (now - referenceAt >= TREND_PERIOD_MS) {
float change = pressure - referencePressure;
if (change > TREND_THRESHOLD_HPA) {
trendText = "rising";
} else if (change < -TREND_THRESHOLD_HPA) {
trendText = "falling";
} else {
trendText = "stable";
}
referencePressure = pressure;
referenceAt = now;
}

printValue(0, "Temp: ", temperature, " C");
printValue(1, "Hum: ", humidity, " %");
printValue(2, "Press: ", pressure, " hPa");
lcd.setCursor(0, 3);
lcd.print("Trend: ");
lcd.print(trendText);
lcd.print(" ");

Serial.print("T=");
Serial.print(temperature, 2);
Serial.print(" C, H=");
Serial.print(humidity, 2);
Serial.print(" %, P=");
Serial.print(pressure, 2);
Serial.println(" hPa");
}

Первый запуск

  1. В Arduino IDE выберите плату Arduino Uno и правильный порт.
  2. Загрузите скетч и откройте монитор порта на 9600 бод.
  3. Если подсветка горит, но букв нет, медленно вращайте потенциометр контраста.
  4. Через несколько секунд должны появиться три измерения и Trend: waiting.
  5. Сравните температуру с комнатным термометром после 10 минут работы.
  6. Подышите рядом с датчиком, не касаясь его: влажность должна вырасти и затем постепенно вернуться.
  7. Через десять минут строка тренда сменится на rising, falling или stable.

Размещение и проверка

Для комнатных измерений закрепите BME280 на открытой боковой стенке корпуса. Не ставьте станцию:

  • на солнце;
  • над батареей отопления;
  • рядом с увлажнителем;
  • вплотную к Arduino или подсветке;
  • в закрытую коробку без отверстий.

Чтобы проверить самонагрев, сравните температуру сразу после включения и через 20 минут. Если она заметно растёт только у станции, удлините провода датчика и отнесите его дальше от плат.

Диагностика

Сообщение или симптомЧто проверить
BME280 not foundSDA на A4, SCL на A5, питание, адрес 0x76/0x77
Подсветка есть, текста нетпотенциометр VO, выводы RS и E, порядок D4–D7
Чёрные прямоугольники вместо текстапрограмма не запущена или неверно подключены сигнальные линии LCD
Влажность всегда 0куплен BMP280, а не BME280; BMP280 влажность не измеряет
Температура завышенадатчик слишком близко к Arduino, регулятору или подсветке
Значения скачут при касанииплохой контакт макетной платы или слишком длинные I2C-провода

Практика

  1. Измерьте температуру в трёх местах комнаты после пяти минут выдержки.
  2. Сравните влажность до и после десятиминутного проветривания.
  3. Записывайте давление каждый час и сравните ручную таблицу с направлением строки Trend.

Проверьте себя

  • Какие три величины измеряет BME280?
  • Почему датчик нельзя ставить рядом с нагретой платой?
  • Для чего дисплею нужен потенциометр?
  • Почему BMP280 нельзя считать полной заменой BME280?
  • Что именно сравнивает программа для определения тренда?

Словарь статьи

  • BME280 — цифровой датчик температуры, влажности и давления.
  • I2C — двухпроводная шина данных SDA и SCL.
  • HD44780 — распространённый контроллер символьных дисплеев.
  • гПа (hPa) — гектопаскаль, единица атмосферного давления.
  • Тренд — направление изменения величины за выбранный промежуток.

Связанные темы

Источники