пока что давление высота температура со2 и время. показатели со2 немного не совпадают надо калибровку сделать или коеффициент добавить/ показатели не совпадают с домашним тестером 730ppm на бытовом приборе а на есп32 694ppm вот нашел как калибровать эти датчики. надо один раз сделать на свежем воздухе
// --- РУЧНАЯ КАЛИБРОВКА MH-Z19B НА 400 PPM ---
// Выполняйте ТОЛЬКО на свежем воздухе!
void calibrateMHZ19B() {
byte calibrateCmd[9] = {0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78};
CO2_Serial.write(calibrateCmd, 9);
Serial.println("Команда калибровки отправлена. Уровень CO₂ зафиксирован как 400 ppm.");
}
// В setup() раскомментируйте на время калибровки:
// calibrateMHZ19B();
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <LiquidCrystal_I2C.h>
#include <RtcDS3231.h>
#include <HardwareSerial.h>
// Датчики
Adafruit_BMP085 bmp;
HardwareSerial CO2_Serial(2); // RX=16, TX=17
LiquidCrystal_I2C lcd(0x27, 20, 4); // Проверь адрес: 0x27 или 0x3F
RtcDS3231<TwoWire> Rtc(Wire);
// Интервалы
const unsigned long SENSOR_INTERVAL = 5000; // 5 сек для BMP и CO2
unsigned long lastRead = 0;
// Глобальные переменные
float bmpTemp = 0.0;
float pressurePa = 0.0;
float altitudeM = 0.0;
int co2_ppm = 0;
bool co2_valid = false;
void setup() {
Serial.begin(115200);
Wire.begin();
// BMP085
if (!bmp.begin()) {
Serial.println("Ошибка: BMP085 не найден!");
while (1) delay(10);
}
// CO2
CO2_Serial.begin(9600, SERIAL_8N1, 16, 17);
Serial.println("MH-Z19B запущен");
// LCD
lcd.init();
lcd.backlight();
lcd.print("Загрузка...");
// RTC
Rtc.Begin();
if (!Rtc.IsDateTimeValid()) {
Serial.println("RTC: устанавливаю время компиляции");
Rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__));
}
delay(1500);
lcd.clear();
}
void loop() {
unsigned long currentMillis = millis();
// Каждые 5 секунд читаем BMP и запрашиваем CO2
if (currentMillis - lastRead >= SENSOR_INTERVAL) {
lastRead = currentMillis;
// --- BMP085 ---
bmpTemp = bmp.readTemperature();
pressurePa = bmp.readPressure();
altitudeM = bmp.readAltitude(); // по умолчанию 101325 Па
// Вывод в Serial
Serial.print("Temperature = "); Serial.print(bmpTemp); Serial.println(" *C");
Serial.print("Pressure = "); Serial.print(pressurePa); Serial.println(" Pa");
Serial.print("Altitude = "); Serial.print(altitudeM); Serial.println(" m");
// --- CO2 ---
byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
CO2_Serial.write(cmd, 9);
delay(100);
co2_valid = false;
if (CO2_Serial.available() >= 9) {
byte response[9];
CO2_Serial.readBytes(response, 9);
if (response[0] == 0xFF && response[1] == 0x86) {
byte sum = 0;
for (int i = 1; i < 8; i++) sum += response[i];
sum = 255 - sum + 1;
if (sum == response[8]) {
co2_ppm = (response[2] << 8) | response[3];
co2_valid = true;
Serial.print("CO2: "); Serial.print(co2_ppm); Serial.println(" ppm");
}
}
}
Serial.println();
}
// Обновляем LCD каждую секунду
static unsigned long lastLCD = 0;
if (currentMillis - lastLCD >= 1000) {
lastLCD = currentMillis;
RtcDateTime now = Rtc.GetDateTime();
// Перевод давления в мм рт. ст.
float pressure_mmHg = pressurePa / 133.322;
// Строка 0: Время
lcd.setCursor(0, 0);
lcd.print("Time:");
lcd.printf("%02u:%02u:%02u", now.Hour(), now.Minute(), now.Second());
// Строка 1: Температура и высота
lcd.setCursor(0, 1);
lcd.printf("T:%.1fC H:%.0fm", bmpTemp, altitudeM);
// Строка 2: Давление в мм рт. ст.
lcd.setCursor(0, 2);
lcd.printf("P:%.0fmmHg", pressure_mmHg);
// Строка 3: CO2
lcd.setCursor(0, 3);
if (co2_valid) {
lcd.printf("CO2: %d ppm", co2_ppm);
} else {
lcd.print("CO2: --");
}
}
delay(10);
}
код рабочий но еще много чего добавить надо. потом появится датчик GP2Y1010AU0F, CJMCU-6814, ZE08-CH2O и сон через модуль TPL5110
Блог только запустил, все статьи генерирую через нейросеть т.к. лень, возможны ошибки. Просто чтобы вы знали и не запускали ядерный реактор по моим статьям ))
Если у вас есть вопросы, или Нашли неточность? пишите в коментах — вместе поправим и сделаем статью более качественной. Я лично объясню нюансы из практики.
Комментарии
Пока нет комментариев. Будьте первым!