Метеостанция на BME280 и ESP8266
В этой статье расскажу, как создать небольшую метеостанцию дома, используя BME280 и NodeMCU (ESP8266). Контроллер NodeMCU v.2 (ESP8266) будет считывать показания температуры, влажности, давления и высоту (рассчитанную) с датчика BME280 и полученные данный отобразить в WEB странице. В качестве среды разработки используем Arduino IDE
Необходимые детали:
► Контроллер NodeMCU v.2 (ESP8266) x 1 шт.
► Провода DuPont, 2,54 мм, 20 см x 1 шт.
► Датчик атмосферного давления, влажности и температуры BME280 x 1 шт.
Подключение
В примере используем контроллер NodeMCU v.2 (ESP8266) и датчик BME280, с последнего будем считывать показания температуры, влажности и давления. Для подключения BME280 к ESP8266, нужно контакты SDA и SCL подключить, как показано на принципиальной схеме ниже.
Установка библиотек
Для работы скетча необходимо две библиотеки «Adafruit_Sensor.h« и «Adafruit_BME280.h», которые не входят в в среду разработки IDE Arduino, нужно дополнительно установить их, скачать можно в конце статьи или воспользоваться «Менеджером Библиотек«, для этого перейдите в «Скетч» -> «Включить библиотеку» -> «Управлять библиотеками..».
Для установки «Adafruit_Sensor.h«, введите «Adafruit Unified Sensor » в поле поиска, прокрутите вниз, что бы найти и установите ее.
Для установки Adafruit_BME280.h , введите «Adafruit_BME280, она одна, установите ее.
Так же, не забываем что необходимо установить NodeMCU в среду разработки Arduino IDE, для этого воспользуйтесь этой статьей. После установки библиотек перезапустите, среду разработки Arduino IDE.
Программа
Теперь, у нас все готово, копируем скетч в Arduino IDE или скачайте готовый файл и загружаем его в NodeMCU, незабываем указать свои данные сети.
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
/* Тестировалось на Arduino IDE 1.8.5 Дата тестирования 03.10.2019г. */ #include <ESP8266WiFi.h> // Подключаем библиотеку ESP8266WiFi #include <Wire.h> // Подключаем библиотеку Wire #include <Adafruit_BME280.h> // Подключаем библиотеку Adafruit_BME280 #include <Adafruit_Sensor.h> // Подключаем библиотеку Adafruit_Sensor #define SEALEVELPRESSURE_HPA (1013.25) // Задаем высоту Adafruit_BME280 bme; // Установка связи по интерфейсу I2C const char* ssid = "Название Вашей WiFi сети"; // Название Вашей WiFi сети const char* password = "Пароль от Вашей WiFi сети"; // Пароль от Вашей WiFi сети WiFiServer server(80); // Указываем порт Web-сервера String header; void setup() { 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.println("IP address: "); // Отправка в Serial port Serial.println(WiFi.localIP()); // Отправка в Serial port server.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() / 100.0F); client.println(" hPa</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("<tr><td>Влажность</td><td><span class=\"sensor\">"); client.println(bme.readHumidity()); client.println(" %</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(""); } } |
Определение IP (ESP8266):
Теперь необходимо узнать IP модуля, для этого открываем «Мониторинг порта» с выставленной скоростью «115200», в моем случаи сеть выдала «192.168.2.107».
Открываем любой браузер (компьютер должен находиться в той же сети, что и ESP8266 модуль), вводим IP-адрес (192.168.2.107) и нажимаем Enter.
Описание скетча:
Первым делом, включаем библиотеку работы с ESP8266 и необходимые библиотеки для работы с датчиком BME280.
1 2 3 4 |
#include <ESP8266WiFi.h> #include <Wire.h> #include <Adafruit_BME280.h> #include <Adafruit_Sensor.h> |
Следующая строка определяет переменную для сохранения давления на уровне моря.
1 |
#define SEALEVELPRESSURE_HPA (1013.25) |
Далее, создаем Adafruit_BME280 с именем bme, который по умолчанию устанавливает связь с датчиком по I2C.
1 |
Adafruit_BME280 bme; |
В следующих строках указываем свою Wi-Fi сеть и пароль в внутри двойных кавычек.
1 2 |
const char* ssid = "Название Вашей WiFi сети"; const char* password = "Пароль от Вашей WiFi сети"; |
Затем устанавливаете веб-сервер на порте 80 и создаем переменную для хранения заголовка HTTP-запроса.
1 2 |
WiFiServer server(80); String header; |
В «setup ()» мы запускаем последовательную связь со скоростью 115200 бод.
1 |
Serial.begin(115200); |
В следующий строках, мы проверяет, инициализацию датчика BME280
1 2 3 4 |
if (!bme.begin(0x76)) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1); } |
Далее, начинаем Wi-Fi соединение с «WiFi.begin (ssid, пароль)», если соединение успешно, печатается IP-адрес.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); server.begin(); } |
В «void loop()» прослушиваем входящих клиентов.
1 |
WiFiClient client = server.available(); |
Когда запрос получен от клиента, мы сохраним входящие данные, цикл while будет работать до тех пор, пока подключен клиент.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
if (client) { Serial.println("New Client."); String currentLine = ""; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); header += c; if (c == '\n') { if (currentLine.length() == 0) { client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html "); client.println("Connection: close"); client.println("Refresh: 10"); client.println(); |
Далее, мы будем отправлять клиенту данные с помощью выражения «client.println ()».
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 27 28 |
client.println("<!DOCTYPE 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() / 100.0F); client.println(" hPa</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("<tr><td>Влажность</td><td><span class=\"sensor\">"); client.println(bme.readHumidity()); client.println(" %</span></td></tr>"); client.println("</body></html>"); |
В конце, мы прекращаем соединение с клиентом.
1 2 3 4 |
header = ""; client.stop(); Serial.println("Client disconnected."); Serial.println(""); |
Если есть вопросы пишите.
сылки
Документация на BME280
Библиотека Adafruit BME280 Library
Библиотека Adafruit Unified Sensor
Документация на ESP8266
Документация на ESP-12F
Драйвер CP2102
Купить на Aliexpress
Плата NodeMCU V2
Провода DuPont, 2,54 мм, 20 см
Датчик атмосферного давления, влажности и температуры BME280
Купить в Самаре и области
Плата NodeMCU V2
Провода DuPont, 2,54 мм, 20 см
Датчик атмосферного давления, влажности и температуры BME280
Спасибо огромное за Ваш труд. Собрал данную метеостанцию на ESP-01.Всё работает.Единственное. что надо сделать для ESP-01 — переназначить выводы SDL,SCL.
Выложите пожалуйста скетч и библиотеку, не получается подружить ESP-01 и BME280.
Спасибо большое. Без танцев с бубном сразу заработало (ESP-12F Witty cloud. Никак не получается запустить через дисплей OLed 1.3″ SH1106 I2C. Какие только библиотеки ему не подсовывал… Даже не моргнул ни разу. Наверное бракованный попался
С ФИФИ тоже отличная задумка!!! Я пока не могу состыковать ВМЕ 280 по I2S с интернет-модулем W5500.Все тесты проходят,пинги тоже.IP-адрес ловит через интру.
ВМЕ 280 по I2S с модулем W5500 cо стыковать не получается.Исходник пытаюсь взять
att= 44300.0*(1.0-pow(pres/101325,0.1415));//0,1903 Высота
//att = (1.0-pow(pres/101325,0.1903))/0.0000225577+20;
client->print(«Temperatura: «);
client->print(temp-0);
client->print(«°»+ String(tempUnit == BME280::TempUnit_Celsius ? ‘C’ :’F’));
client->print(«\t\tVLAGA: «);
client->print(hum,2);// вывод влажности на СОМ (hum);после запятой знак 10-100ки
client->print(«% RH»);
client->print(«\t\tDavlenie: «);
client->print(pres/132.99);//вывод давления на СОМ;
client->print(» mm/RTS»);
client->print(«\t\tVyisota: «);//Высота по формуле
client->print(att);
client->println(» M.nad morem»);
delay(2000);//задержка буду рад за помощь и за ранее спасибо!!!
Спасибо, заработало.Ещё бы в мм ртутного столба давление показывалось.
Cкетч перестал работать после переустановки Windows 7. Проверку проходит, а в самом конце установки пишет, что не подключен порт. Порт соответственно подключен. Как исправить — не знаю.
Здравствуйте! У меня почему то в мониторе порта,бегут только точки? Хотя когда заливаю примес с ардуино иде ,для этого датчик,все работает как надо.
Пока эти библиотеки не подгрузил,не заработало.
#include
#include
#include
Спасибо, заработало.Ещё бы в мм ртутного столба давление показывалось.
1 hPa = 0.75006375541921 mmHg
client.println(bme.readPressure() / 100.0F * 0.75006375541921);
Спасибо , хороший проект заработало сразу. Подскажите пожалуйста как поправить скетч чтобы у метеостанции был статический IP
IP адреса раздает роутер. нужно в панели управления роутером установить для этого устройства постоянный адрес
Подскажите, почему, когда соединение разрывается , неважно через WiFi или мобильный интернет, потом подключится не возможно. Что за ограничение?
2 — 3 раза подключится с разных ip потом их не видит. Кто сталкивался с таким на этом проекте?
Модуль перегрузишь, временно работает. Модуль и датчик такой как в проекте! В чём подвох?
Здравствуйте. Сергей, вы сами пишете код для метеостанции? Есть возможность пообщаться на почте?
Здравствуйте, на данный момент по коду не смогу помочь