Суббота, 18.05.2024
Завод горного оборудования
Меню сайта
Google_Translate
Категории раздела
Мои статьи [124]
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Рейтинг@Mail.ru

Яндекс.Метрика
Главная » Статьи » Мои статьи

Метеостанция NodeMCU на BME280 и SSD1306 с индикацией времени

  

За основу взят проект robotchip.ru/meteostantsiya-na-bme280-i-esp8266/. Он выводит показания датчика BME280 на веб-страницу в браузер. В проект добавлен дисплей SSD1306 (dmitrysnotes.ru/domashnyaya-meteostanciya-na-esp8266-i-datchike-bme280) для вывода показаний температуры, влажности и атмосферного давления. Также добавлен NTP клиент (radioprog.ru/post/910) для вывода на дисплей текущего времени вашей часовой зоны.

Вначале на макетной плате соберите схему, показанную на рисунке:

Подразумевается, что среда Arduino IDE установлена и в список плат добавлена NodeMCU 1.0 (ESP-12E Module).
Для работы скетча необходимы библиотеки Adafruit_BME280.h, Adafruit_Sensor.h, SSD1306.h. Как установить их, описано на dmitrysnotes.ru/domashnyaya-meteostanciya-na-esp8266-i-datchike-bme280. Библиотеку ESP8266WiFi.h можно скачать с martyncurrey.com/download/esp8266wifi-library/. В скачанном списке библиотек есть WiFiUdp.h. Как установить NTPClient.h, описано на radioprog.ru/post/910.

Также скетч и библиотеки можно скачать в Каталоге файлов.
Запустите Arduino IDE и выберите Файл -> Новый. В окне удалите текст предлагаемой заготовки скетча и вставьте текст скетча bme_ntp.ino.

Скетч bme_ntp_day.ino

/*
  Тестировалось на Arduino IDE 1.8.19
  Дата тестирования 14.01.2024г.
*/

#include <ESP8266WiFi.h>                                // Подключаем библиотеку ESP8266WiFi
#include <Wire.h>                                       // Подключаем библиотеку Wire
#include <Adafruit_BME280.h>                            // Подключаем библиотеку Adafruit_BME280
#include <Adafruit_Sensor.h>                            // Подключаем библиотеку Adafruit_Sensor
#include "SSD1306.h"                     // Подключаем OLED SSD1306
#include <NTPClient.h>
#include <WiFiUdp.h>


#define SDA 14
#define SCL 12
#define I2C 0x3C

SSD1306 display (I2C, SDA, SCL);

const long utcOffsetInSeconds = 32400;     // timezone +9 (Chita):  9*60*60=32400

char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

// Определение NTP-клиента для получения времени
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

#define SEALEVELPRESSURE_HPA (1013.25)                  // Задаем высоту

Adafruit_BME280 bme;                                    // Установка связи по интерфейсу I2C

const char* ssid = "*******";          // Название Вашей WiFi сети
const char* password = "************";     // Пароль от Вашей WiFi сети

WiFiServer server(80);                                  // Указываем порт Web-сервера
String header;

void setup() {
  display.init();
  display.flipScreenVertically();
  display.clear();
  display.display();


  Serial.begin(115200);                                 // Скорость передачи 115200
  bool status;

  if (!bme.begin(0x76)) {                               // Проверка инициализации датчика
    //  Serial.println("Could not find a valid BME280 sensor, check wiring!"); // Печать об ошибке инициализации
    while (1);                                          // Зацикливаем
  }

  Serial.print("Connecting to ");                       // Отправка в Serial port
  Serial.println(ssid);                                 // Отправка в Serial port
  WiFi.begin(ssid, password);                           // Подключение к WiFi Сети
  while (WiFi.status() != WL_CONNECTED) {               // Проверка подключения к WiFi сети
    delay(500);                                         // Пауза
    Serial.print(".");                                  // Отправка в Serial port
  }

  Serial.println("");                                   // Отправка в Serial port
  Serial.println("WiFi connected.");                    // Отправка в Serial port
  Serial.print("IP address: ");                         // Отправка в Serial port
  Serial.println(WiFi.localIP());                       // Отправка в Serial port
  server.begin();
  timeClient.begin();
}

void loop() {
  WiFiClient client = server.available();               // Получаем данные, посылаемые клиентом

  if (client) {
    Serial.println("New Client.");                      // Отправка "Новый клиент"
    String currentLine = "";                            // Создаем строку для хранения входящих данных от клиента
    while (client.connected()) {                        // Пока есть соединение с клиентом
      if (client.available()) {                         // Если клиент активен
        char c = client.read();                         // Считываем посылаемую информацию в переменную "с"
        Serial.write(c);                                // Отправка в Serial port
        header += c;
        if (c == '\n') {                                // Вывод HTML страницы
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");          // Стандартный заголовок HT
            client.println("Content-type:text/html ");
            client.println("Connection: close");        // Соединение будет закрыто после завершения ответа
            client.println("Refresh: 10");              // Автоматическое обновление каждые 10 сек
            client.println();

            client.println("<!DOCTYPE html><html>");    // Веб-страница создается с использованием HTML
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<meta charset='UTF-8'>");   // Делаем русскую кодировку
            client.println("<link rel=\"icon\" href=\"data:,\">");

            client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}");
            client.println("table { border-collapse: collapse; width:40%; margin-left:auto; margin-right:auto; }");
            client.println("th { padding: 12px; background-color: #0043af; color: white; }");
            client.println("tr { border: 1px solid #ddd; padding: 12px; }");
            client.println("tr:hover { background-color: #bcbcbc; }");
            client.println("td { border: none; padding: 12px; }");
            client.println(".sensor { color:white; font-weight: bold; background-color: #bcbcbc; padding: 1px; }");

            client.println("</style></head><body><h1>Метеостанция на BME280 и ESP8266</h1>");
            client.println("<table><tr><th>Параметр</th><th>Показания</th></tr>");
            client.println("<tr><td>Температура</td><td><span class=\"sensor\">");
            client.println(bme.readTemperature());
            client.println(" *C</span></td></tr>");
            client.println("<tr><td>Давление</td><td><span class=\"sensor\">");
            client.println(bme.readPressure() * 0.0075F);
            client.println(" mmHg</span></td></tr>");

            client.println("<tr><td>Влажность</td><td><span class=\"sensor\">");
            client.println(bme.readHumidity());
            client.println(" %</span></td></tr>");

            client.println("<tr><td>Приблизительная высота над уровнем моря</td><td><span class=\"sensor\">");
            client.println(bme.readAltitude(SEALEVELPRESSURE_HPA));
            client.println(" m</span></td></tr>");
            client.println("</body></html>");

            client.println();
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    header = "";
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");

  }

  timeClient.update();

  Serial.print(daysOfTheWeek[timeClient.getDay()]);
  Serial.print(", ");
  Serial.print(timeClient.getHours());

  Serial.print(":");
  Serial.print(timeClient.getMinutes());

  Serial.print(":");
  Serial.println(timeClient.getSeconds());
  //Serial.println(timeClient.getFormattedTime());


  float tempC = bme.readTemperature();
  float humidity = bme.readHumidity();
  float pressuremmHg = bme.readPressure() * 0.007500616;         // перевод атм. давления Pa в mmHg

  display.clear();
  display.setFont(ArialMT_Plain_16);
  display.drawString(20, 1, String(daysOfTheWeek[timeClient.getDay()]) + " " + String(timeClient.getHours()) + " : " + String(timeClient.getMinutes()));
  display.setFont(ArialMT_Plain_10);
  display.drawString(5, 22, "Temperature = " + String(tempC) + " *C");
  display.drawString(5, 35, "Humidity = " + String(humidity) + " %");
  display.drawString(5, 48, "Pressure = " + String(pressuremmHg) + " mmHg");
  display.display();

  delay (5000);
}

В скетче вместо звездочек пропишите название и пароль вашей Wi-Fi сети. Также для NTP клиента вам нужно рассчитать константу utcOffsetInSeconds для вашей часовой зоны. Как рассчитать, описано в [3]. У меня поправка относительно UTC времени равна +9 (зона Читы, Якутска), поэтому константа получилась 9*60*60 = 32400.

Если скетч не работает, то попробуйте подобрать адреса устройств на шине I2C (0x3D для SSD1306 или 0x77 для BME280). Загрузите скетч I2C_Scanner.ino для сканирования адресов устройств на шине I2C и замените в скетче bme_ntp_day.ino адреса на свои. Как просканировать адреса, описано в статье Arduino метеостанция на BMP180, DHT11 и LCD1602.

IP адрес веб-страницы метеостанции выводится в сообщениях монитора порта.

Информация на дисплее SSD1306 обновляется каждые 5 секунд, на веб-странице — каждые 10 секунд.
При необходимости вы можете настроить вывод в градусах Фаренгейта и давления в гПа. Как это сделать, можно прочитать на ресурсе [2].

В результате у вас получились часы с выводом данных о погоде. Дни недели выводятся тремя символами по-английски Sun (Sunday - воскресенье), Mon (Monday - понедельник), Tue (Tuesday - вторник), Wed (Wednesday - среда), Thu (Thursday - четверг), Fri (Friday - пятница), Sat (Saturday - суббота).

Чтобы получить доступ к веб-странице через интернет, вам надо сделать дополнительные настройки. В роутере домашней сети вам нужно закрепить за NodeMCU постоянный (статический) IP адрес, также надо настроить для NodeMCU проброс порта 80 (port forwarding). На каком-нибудь динамическом DNS сервисе зарегистрировать домен для вашей веб-страницы. Как это настроить, подробно описано в статье Как получить доступ по интернету к датчикам в квартире.
Но тут есть одна закавыка. DNS сервис предлагает установить утилиту, которая периодически посылает на сервис текущий IP адрес. Когда провайдер выдаст вашему роутеру другой IP адрес, утилита сообщит новый IP адрес на DNS сервис. Сервис заменит устаревший IP адрес на текущий на DNS серверах. Вашему домену (имени сайта) будет соответствовать уже новый IP адрес и ваше устройство снова будет доступно в интернете. На NodeMCU нет возможности установить такую утилиту, но если у вас в сети есть компьютер Windows или Linux (Raspberry Pi), то вы можете установить эту утилиту на один из этих компьютеров. Он должен быть практически постоянно включен. Проще всего использовать Raspberry Pi или подобный компьютер. Как настроить доступ из интернета на Raspberry Pi, также написано в статье Как получить доступ по интернету к датчикам в квартире.

Скачать скетч и библиотеки

Последнее изменение 14.01.2024

Использованные ресурсы

1. https://robotchip.ru/meteostantsiya-na-bme280-i-esp8266/
2. https://dmitrysnotes.ru/domashnyaya-meteostanciya-na-esp8266-i-datchike-bme280
3. https://radioprog.ru/post/910
4. https://blog.squix.org/wp-content/uploads/2018/09/esp8266weatherstationgettingstartedguide-20180911.pdf
5. Internet_of_Things_with_ESP8266, Marco_Schwartz 2016 Packt Publishing 226 p.
6. Интернет вещей с ESP8266, Шварц Марко, Пер. с англ. — СПб.: БХВ-Петербург, 2018 192 с.
7. http://www.martyncurrey.com/download/esp8266wifi-library/
8. https://lastminuteengineers.com/esp8266-ntp-server-date-time-tutorial/

Категория: Мои статьи | Добавил: zgo (11.09.2021)
Просмотров: 1757 | Комментарии: 11 | Теги: веб погода, clock, часы, web page weather, метеостанция, BME280, NodeMCU, SSD1306, weather station | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
Поиск
Друзья сайта
  • Создать сайт
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Все проекты компании
  • Сайт завода zgo.ucoz.ru
  • Забайкальский край
    Дарасун
    Яндекс.Погода


    Хостинг Ucoz опять навязал видеорекламу, но обещает - "мы настроили систему так, чтобы в сутки на уникального посетителя приходилось не более двух показов."
    Совет, как не смотреть видеорекламу.

    Или используйте Uran - браузер от Ucoz без рекламы Скачать

    или подключите к браузеру блокировщик рекламы, например, Adblock Plus или uBlock Origin

    Универсальный декодер кириллицы



    Защита, контроль, управление.


    Ваш IP адрес IP informer

    DONATE (поддержи автора)
    Все статьи авторские, при использовании прошу ссылаться на сайт
    Copyright Дарасунский завод горного оборудования © 2004 - 2024
    Бесплатный конструктор сайтов - uCoz