Wemos D1 не работает с MH-Z19B (датчик CO2)
Я хочу подключить датчик CO2 к Wemos D1. Я бы хотел, чтобы он работал через UART (RX, TX), а не через штырь PWM. Я столкнулся с многочисленными библиотеками на Github, но не могу заставить их работать. Я подключил следующие вещи:
Я перепробовал множество фрагментов со всего Интернета и множество библиотек на Github, но не могу заставить их работать. Ради этого вопроса я собираюсь использовать эту расширенную библиотеку.
Это мой код:
#include <Arduino.h>
#include "MHZ19.h" // включаем основную библиотеку
#include <SoftwareSerial.h> // Удалить, если используется устройство, не совместимое с библиотекой HardwareSerial или не-uno.
#define RX_PIN D1 // вывод Rx, к которому подключен вывод MHZ19 Tx
#define TX_PIN D2 // вывод Tx, к которому подключен вывод MHZ19 Rx
#define BAUDRATE 9600 // Исходный для датчика (не менять)
MHZ19 myMHZ19; // Конструктор класса MH-Z19
SoftwareSerial mySerial(RX_PIN, TX_PIN); // Пример Uno
//Серийный номер аппаратного обеспечения mySerial(1); // Пример ESP32
unsigned long getDataTimer = 0; // Переменная для хранения интервала таймера
void setup()
{
Serial.begin(9600); // Для ESP32 baudarte составляет 115200 и т. д.
mySerial.begin(BAUDRATE); // Пример Uno: начать поток со скоростью передачи MHZ19
//mySerial.begin(BAUDRATE, SERIAL_8N1, RX_PIN, TX_PIN); // Пример ESP32
myMHZ19.begin(mySerial); // *Важно, передайте ссылку на поток
myMHZ19.autoCalibration(); // Включаем автоматическую калибровку (отключаем с помощью autoCalibration(false))
}
void loop(){
if (millis() - getDataTimer >= 2000) // Проверяем, истек ли интервал (эквивалент неблокирующей задержки())
{
int CO2; // Буфер для CO2
/* note: getCO2() default is command "CO2 Unlimited". This returns the correct CO2 reading even
if below background CO2 levels or above range (useful to validate sensor). You can use the
usual documented command with getCO2(false) */
CO2 = myMHZ19.getCO2(); // Запрос CO2 (в ppm)
Serial.print("CO2 (ppm): ");
Serial.println(CO2);
int8_t Temp; // Буфер для температуры
Temp = myMHZ19.getTemperature(); // Запросить температуру (по Цельсию)
Serial.print("Temperature (C): ");
Serial.println(Temp);
getDataTimer = millis(); // Интервал обновления
}
}
Я постоянно получаю это:
19:39:59.750 -> !Error: Timed out waiting for response
19:39:59.784 -> !ERROR: Failed to verify connection(1) to sensor. Failed to stablise
19:39:59.853 -> !ERROR: Initial communication errorCode recieved
19:40:00.272 -> !Error: Timed out waiting for response
19:40:00.758 -> !Error: Timed out waiting for response
19:40:00.792 -> CO2 (ppm): 0
19:40:01.280 -> !Error: Timed out waiting for response
19:40:01.315 -> Temperature (C): -17
Я что-то неправильно подключаю или что делаю не так?
ИЗМЕНИТЬ: Версия с использованием только серийника вместо библиотеки, которая тоже не работает:
#include <SoftwareSerial.h>
SoftwareSerial co2Serial(3, 1);
unsigned long startTime = millis();
void setup() {
Serial.begin(9600);
co2Serial.begin(9600);
pinMode(9, INPUT);
}
void loop() {
Serial.println("------------------------------");
Serial.print("Time from start: ");
Serial.print((millis() - startTime) / 1000);
Serial.println(" s");
int ppm_uart = readCO2UART();
delay(5000);
}
int readCO2UART(){
byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
byte response[9]; // для ответа
Serial.println("Sending CO2 request...");
co2Serial.write(cmd, 9); //запрос PPM CO2
// очистить буфер
memset(response, 0, 9);
int i = 0;
while (co2Serial.available() == 0) {
Serial.print("Waiting for response ");
Serial.print(i);
Serial.println(" s");
delay(1000);
i++;
}
if (co2Serial.available() > 0) {
co2Serial.readBytes(response, 9);
}
// распечатать ответ в шестнадцатеричном формате
for (int i = 0; i < 9; i++) {
Serial.print(String(response[i], HEX));
Serial.print(" ");
}
Serial.println("");
// контрольная сумма
byte check = getCheckSum(response);
if (response[8] != check) {
Serial.println("Checksum not OK!");
Serial.print("Received: ");
Serial.println(response[8]);
Serial.print("Should be: ");
Serial.println(check);
}
// ч/млн
int ppm_uart = 256 * (int)response[2] + response[3];
Serial.print("PPM UART: ");
Serial.println(ppm_uart);
// временная
byte temp = response[4] - 40;
Serial.print("Temperature? ");
Serial.println(temp);
// положение дел
byte status = response[5];
Serial.print("Status? ");
Serial.println(status);
if (status == 0x40) {
Serial.println("Status OK");
}
return ppm_uart;
}
byte getCheckSum(byte *packet) {
byte i;
unsigned char checksum = 0;
for (i = 1; i < 8; i++) {
checksum += packet[i];
}
checksum = 0xff - checksum;
checksum += 1;
return checksum;
}
@Mark D, 👍1
Обсуждение1 ответ
Я знаю, что уже поздно отвечать. Что помогло мне при работе с WEMOS D1 mini и MH-Z19C, так это переназначение используемых программных контактов SoftwareSerial co2Serial(D1, D2); В этом случае второй опубликованный скетч работает, по крайней мере, для меня.
Проблема может заключаться в том, что ESP8266 использует аппаратные последовательные линии для подключения к мосту USB-to-Serial (обычно CH340 или CP2102 в большинстве конструкций), что означает, что вы можете столкнуться с проблемами, если захотите использовать ту же последовательную линию. для более чем одного устройства.
- Какие входные контакты я могу использовать на ESP8266 NodeMCU
- ESP8266 не может подключиться к брокеру MQTT
- Однонаправленная связь между NodeMCU и Arduino выплевывает мусор
- Ошибка программного сброса wdt на NodeMCU (ESP8266)
- Отправьте несколько значений из Arduino Uno в nodeMCU, используя последовательный порт.
- NODEMCU 1.0 HX711 Тензодатчик читает странный текст
- Как защитить ссылку/URL-адрес формы ESP-12E для управления светодиодом
- Ультразвуковой датчик (HC-SR04), регистрирующий случайное расстояние
Вы ведь знаете, что вам нужно скрестить RX и TX с коммуникациями UART, не так ли? TX подключается к RX, а RX подключается к TX., @Majenko
Я знаю, пробовал и так, и так (на этой картинке неправильно нарисовал), ни один не работает, @Mark D
вы пытались отправить команды без использования библиотеки MHZ19?, @jsotola
Да, тоже нет ответа, смотрите правку, @Mark D