Здесь могла бы быть реклама
Она помогает блогу развиваться.
Кажется, сегодня она немного загрустила.

Главная страница » DIY проекты » Домашняя метеостанция с графиками: ESP32 + InfluxDB + Grafana
Домашняя метеостанция с графиками: ESP32 + InfluxDB + Grafana
DIY проекты

Домашняя метеостанция с графиками: ESP32 + InfluxDB + Grafana

31.03.2026 198
Домашняя метеостанция с графиками: ESP32 + InfluxDB + Grafana

Создаём домашнюю метеостанцию на ESP32 с хранением данных в InfluxDB и наглядными графиками в Grafana.

Всем привет! Сегодня мы соберём проект, который идеально сочетает DIY-электронику и визуализацию данных — полноценную домашнюю метеостанцию. Мы не просто получим текущие показания, а построим исторические графики температуры, влажности и давления, которые будут храниться годами. Всё это на базе доступного микроконтроллера ESP32 и мощной, но бесплатной связки InfluxDB и Grafana, развернутой на одноплатном компьютере.

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

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

Аппаратная часть

  1. Плата ESP32 (любая, например, DevKit V1). Отличный выбор благодаря встроенному Wi-Fi и достаточной мощности. Если вы в раздумьях, что взять, у меня есть подробное сравнение ESP32 vs ESP8266: Что выбрать для своего DIY-проекта в 2024 году.
  2. Датчик BME280. Компактный и точный сенсор, измеряющий температуру, влажность и атмосферное давление по цифровому интерфейсу I2C (или SPI). Это наш «метеорологический центр». Кстати, если хотите глубже погрузиться в работу с этим датчиком, посмотрите статью ESP32 и три в одном: измеряем температуру, влажность и давление на одной плате.
  3. Макетная плата и провода для соединений.
  4. Одноплатник для сервера (Raspberry Pi, Orange Pi, NanoPi). На нём будут работать база данных и система графиков. Для такого проекта хватит даже маломощной платы вроде Orange Pi Zero 3.

Программная часть

  1. InfluxDB 2.x — высокопроизводительная база данных, созданная специально для хранения временных рядов (time-series data). Идеальна для показаний датчиков.
  2. Grafana — платформа для аналитики и визуализации. С её помощью мы создадим красивые и информативные дашиборды.
  3. Arduino IDE или PlatformIO для программирования ESP32.

Схема подключения

Подключение датчика BME280 по интерфейсу I2C очень простое. Нам нужно всего 4 провода.

ESP32 (DevKit)   ->   BME280
3.3V (3V3)       ->   VCC
GND              ->   GND
GPIO 21          ->   SDA
GPIO 22          ->   SCL

Важно: Датчик BME280 питается от 3.3В! Подача 5В его убьёт. Убедитесь, что вы подключили VCC к правильному пину на ESP32.

Часть 1: Настройка сервера (InfluxDB + Grafana)

Я буду использовать для примера Raspberry Pi с установленной ОС Raspberry Pi OS (Debian). Для других одноплатников на базе Arm, таких как Orange Pi или NanoPi, процесс будет аналогичным, особенно если вы используете Armbian: универсальная ОС для одноплатников — установка и настройка.

Установка InfluxDB 2.x

Открываем терминал на нашем одноплатнике и выполняем команды.

# Добавляем репозиторий InfluxData
wget -q https://repos.influxdata.com/influxdata-archive.key
echo '23a1c8836f0afc5ed24e0486339d7cc8f6790b83886c4c96995b88a061c5bb5d influxdata-archive.key' | sha256sum -c && cat influxdata-archive.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive.gpg > /dev/null
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list

# Обновляем список пакетов и устанавливаем InfluxDB 2
sudo apt update
sudo apt install influxdb2 -y

# Запускаем службу и добавляем в автозагрузку
sudo systemctl start influxdb
sudo systemctl enable influxdb

Проверяем, что служба работает:

sudo systemctl status influxdb

Вы должны увидеть статус active (running).

Теперь нужно завершить первоначальную настройку. Откройте браузер и перейдите по адресу http://ВАШ_IP_ОДНОПЛАТНИКА:8086.

  1. Создайте первого пользователя (username, password).
  2. Создайте первую организацию (например, home) и бакет (bucket). Бакет — это контейнер для данных. Назовём его sensors_data.
  3. Запишите или сгенерируйте Токен (Token). Он понадобится ESP32 для записи данных. Сохраните его в надёжном месте!

Установка Grafana

Установка также выполняется из официального репозитория.

# Устанавливаем необходимые зависимости
sudo apt install -y software-properties-common wget

# Добавляем ключ и репозиторий Grafana
sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list

# Устанавливаем Grafana
sudo apt update
sudo apt install grafana -y

# Запускаем службу и добавляем в автозагрузку
sudo systemctl start grafana-server
sudo systemctl enable grafana-server

Проверяем статус:

sudo systemctl status grafana-server

Теперь Grafana доступна по адресу http://ВАШ_IP_ОДНОПЛАТНИКА:3000. Стандартные логин и пароль — admin / admin. Система сразу попросит их сменить.

Часть 2: Прошивка для ESP32

Мы напишем скетч, который будет считывать данные с BME280 и отправлять их в InfluxDB по протоколу HTTP API (InfluxDB Line Protocol).

Подготовка среды и библиотек

  1. В Arduino IDE добавьте поддержку плат ESP32 через Файл -> Настройки -> Дополнительные ссылки для менеджера плат.
  2. Установите необходимые библиотеки через Инструменты -> Управлять библиотеками...:
    • Adafruit BME280 Library (для работы с датчиком)
    • Adafruit Unified Sensor (зависимость для BME280)
    • WiFi (встроенная)
    • HTTPClient (встроенная)

Код прошивки (скетч)

Создайте новый скетч и полностью замените его содержимое на код ниже. Не забудьте подставить свои данные!

#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

// ========== НАСТРОЙКИ ==========
// 1. Данные вашей Wi-Fi сети
const char* ssid = "ВАШ_SSID";
const char* password = "ВАШ_ПАРОЛЬ";

// 2. Данные вашего InfluxDB 2.x
const char* influxDBUrl = "http://ВАШ_IP_ОДНОПЛАТНИКА:8086"; // Адрес сервера
const char* influxDBToken = "ВАШ_ТОКЕН_ПОЛЬЗОВАТЕЛЯ"; // Токен с правами записи
const char* influxDBOrg = "home"; // Название организации
const char* influxDBBucket = "sensors_data"; // Название бакета

// 3. Настройки датчика и интервалов
#define SEALEVELPRESSURE_HPA (1013.25) // Давление на уровне моря для расчёта высоты
#define SENSOR_ID "esp32_balcony" // Уникальное имя для этой метеостанции
#define MEASUREMENT_INTERVAL 60000 // Интервал отправки данных в миллисекундах (60 сек)
// ===============================

// Объект датчика
Adafruit_BME280 bme;

// Таймер для отслеживания интервала
unsigned long lastSendTime = 0;

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("n=== Запуск домашней метеостанции ===");

  // Инициализация датчика BME280
  bool bme_status = bme.begin(0x76); // Адрес 0x76. Если не работает, попробуйте 0x77
  if (!bme_status) {
    Serial.println("ОШИБКА: Не удалось найти датчик BME280! Проверьте схему подключения.");
    while (1); // Останавливаем выполнение
  }
  Serial.println("Датчик BME280 инициализирован.");

  // Подключение к Wi-Fi
  WiFi.begin(ssid, password);
  Serial.print("Подключение к Wi-Fi ");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("nПодключено к Wi-Fi!");
  Serial.print("IP-адрес: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // Проверяем, пришло ли время отправлять данные
  if (millis() - lastSendTime >= MEASUREMENT_INTERVAL) {
    // Считываем данные с датчика
    float temperature = bme.readTemperature();
    float humidity = bme.readHumidity();
    float pressure_hPa = bme.readPressure() / 100.0F;
    float altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);

    // Формируем строку данных в формате InfluxDB Line Protocol
    // Формат: measurement,tag_set field_set timestamp
    String dataToSend = "environment,sensor_id=";
    dataToSend += SENSOR_ID;
    dataToSend += " temperature=";
    dataToSend += String(temperature);
    dataToSend += ",humidity=";
    dataToSend += String(humidity);
    dataToSend += ",pressure=";
    dataToSend += String(pressure_hPa);
    dataToSend += ",altitude=";
    dataToSend += String(altitude);
    // Timestamp добавляется сервером автоматически

    // Отправляем данные в InfluxDB
    sendToInfluxDB(dataToSend);

    // Обновляем время последней отправки
    lastSendTime = millis();
  }

  // Небольшая задержка для стабильности
  delay(100);
}

void sendToInfluxDB(String payload) {
  // Проверяем подключение к Wi-Fi
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;

    // Формируем полный URL для записи в API v2
    String fullUrl = String(influxDBUrl);
    fullUrl += "/api/v2/write?org=";
    fullUrl += influxDBOrg;
    fullUrl += "&bucket=";
    fullUrl += influxDBBucket;
    fullUrl += "&precision=s";

    http.begin(fullUrl);
    http.addHeader("Content-Type", "text/plain");
    http.addHeader("Authorization", "Token " + String(influxDBToken));

    Serial.print("Отправка данных: ");
    Serial.println(payload);
    int httpResponseCode = http.POST(payload);

    if (httpResponseCode > 0) {
      Serial.print("Код ответа HTTP: ");
      Serial.println(httpResponseCode);
      if (httpResponseCode == 204) { // 204 No Content - успешная запись
        Serial.println("Данные успешно отправлены в InfluxDB!");
      }
    } else {
      Serial.print("ОШИБКА при отправке: ");
      Serial.println(httpResponseCode);
      Serial.println(http.errorToString(httpResponseCode));
    }
    http.end();
  } else {
    Serial.println("ОШИБКА: Нет подключения к Wi-Fi.");
  }
}

Пояснения и типичные ошибки

  • Адрес датчика (0x76 или 0x77): У BME280 может быть два адреса. Если датчик не инициализируется, закомментируйте строку с 0x76 и раскомментируйте следующую (обычно она есть в примерах библиотеки Adafruit) или просто попробуйте 0x77.
  • Токен InfluxDB: Убедитесь, что токен имеет права на запись в указанный бакет (sensors_data). Ошибка 401 Unauthorized говорит о проблеме с токеном.
  • Блокировка брандмауэра: Если ESP32 не может подключиться к порту 8086, проверьте настройки брандмауэра на одноплатнике (sudo ufw status). Нужно разрешить порт: sudo ufw allow 8086/tcp.
  • Стабильность Wi-Fi: В коде нет жёсткой перезагрузки при потере связи. В реальном проекте стоит добавить проверку WiFi.status() и переподключение.

Загрузите скетч в ESP32 и откройте Монитор порта (Serial Monitor). Вы должны увидеть процесс подключения и периодические сообщения об успешной отправке данных.

Часть 3: Настройка дашборда в Grafana

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

  1. Добавьте источник данных (Data Source).

    • В Grafana перейдите в Configuration (значок шестерёнки) -> Data Sources.
    • Нажмите Add data source и выберите InfluxDB.
    • Выберите метод доступа Flux (актуально для InfluxDB 2.x).
    • В настройках укажите:
      • URL: http://localhost:8086 (если Grafana на том же сервере).
      • Organization: home
      • Token: тот же токен, что использовали для ESP32.
      • Нажмите Save & test. Должно появиться сообщение об успешном подключении.
  2. Создайте новый дашборд (Dashboard).

    • Нажмите Create (знак плюса) -> Dashboard.
    • Нажмите Add visualization.
  3. Напишите первый запрос (Query) на языке Flux.

    • В выпадающем списке выберите ваш источник данных InfluxDB.
    • В редакторе запросов вставьте следующий Flux-запрос для температуры:
from(bucket: "sensors_data")
  |> range(start: -1h)
  |> filter(fn: (r) => r["_measurement"] == "environment")
  |> filter(fn: (r) => r["sensor_id"] == "esp32_balcony")
  |> filter(fn: (r) => r["_field"] == "temperature")
  |> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
  |> yield(name: "mean")

Что делает этот запрос: * from(bucket: "sensors_data") — выбирает наш бакет. * range(start: -1h) — берёт данные за последний час. * Три фильтра filter — выбирают нужное измерение, конкретный датчик и поле "температура". * aggregateWindow(...) — усредняет значения за каждую минуту для сглаживания графика. * yield(...) — выводит результат.

  1. Настройте визуализацию.

    • В правой панели в разделе Visualization выберите Time series.
    • Во вкладке Panel options задайте понятное название, например, "Температура на балконе".
    • Во вкладке Field можно настроить единицы измерения (°C) и количество десятичных знаков.
  2. Добавьте остальные графики.

    • Нажмите кнопку Add в верхней панели дашборда и выберите Visualization.
    • Создайте новые панели для влажности (humidity) и давления (pressure), скопировав запрос и изменив поле в фильтре filter(fn: (r) => r["_field"] == "humidity").
    • Расположите панели на дашборде удобным образом.
  3. Сохраните дашборд. Нажмите Save в верхней панели и дайте ему имя, например, "Домашняя метеостанция".

Проверка результата

После того как всё настроено и ESP32 работает несколько минут, выполните финальную проверку:

  1. В InfluxDB UI (http://IP:8086):

    • Перейдите в раздел Data Explorer.
    • Выберите бакет sensors_data.
    • Выполните простой запрос: from(bucket: "sensors_data") |> range(start: -5m). Вы должны увидеть сырые данные, поступающие от ESP32.
  2. В Grafana:

    • Обновите ваш дашборд. На графиках должны появиться линии с данными.
    • Поиграйте с диапазоном времени (правый верхний угол дашборда). Посмотрите данные за 6

Понравилась статья?

Поставьте лайк и сохраните полезный материал в закладки.

Комментарии (0)
Добавить комментарий
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
Мониторинг качества воздуха: CO2, PM2.5 и VOC своими руками на ESP32
DIY проекты
31.03.2026
Мониторинг качества воздуха: CO2, PM2.5 и VOC своими руками на ESP32
Соберите систему мониторинга качества воздуха своими руками на ESP32. Измеряйте CO2, PM2.5 и VOC. Подробное руководство: схема, код, интеграция с Home Assistant.
Как печатать резьбу на 3D-принтере: зазоры, допуски и настройки для болтов и гаек
DIY проекты
09.09.2026
Как печатать резьбу на 3D-принтере: зазоры, допуски и настройки для болтов и гаек
Практическое руководство по печати резьбы на FDM-принтере: расчёт зазоров и допусков для PLA, PETG и ABS, настройки слайсера, калибровочная печать и типичные ошибки.
DIY умный звонок с камерой на ESP32-CAM и Home Assistant
DIY проекты
31.03.2026
DIY умный звонок с камерой на ESP32-CAM и Home Assistant
Собираем умный дверной звонок на ESP32-CAM с камерой, уведомлениями и интеграцией в Home Assistant.
Умный аквариум своими руками: автодолив, контроль температуры и освещение по расписанию
DIY проекты
31.03.2026
Умный аквариум своими руками: автодолив, контроль температуры и освещение по расписанию
Собираем умный аквариум с автодоливом, контролем температуры и освещением по расписанию.
Умная теплица на ESP32 и Raspberry Pi: автоматизация от А до Я
DIY проекты
31.03.2026
Умная теплица на ESP32 и Raspberry Pi: автоматизация от А до Я
Собираем умную теплицу на ESP32 и Raspberry Pi: датчики, полив, освещение, автоматика и удалённый контроль.
Умный счётчик электроэнергии своими руками: мониторинг потребления в реальном времени
DIY проекты
31.03.2026
Умный счётчик электроэнергии своими руками: мониторинг потребления в реальном времени
Пошаговое руководство: как собрать умный счётчик для мониторинга потребления энергии в реальном времени с ESP32, MQTT и Home Assistant. DIY проект для умного дома.

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