Реле переключается при достижении значения CO

Мне нужна помощь с кодом с использованием mq-7 и esp8266.

Компоненты, которые я использовал: MQ-7 (грел 48 часов) ЭСП8266 4-канальное реле вентилятор 24 В постоянного тока mb102

Все, что я хочу сделать, это mq-7, чтобы постоянно считывать значение co, а затем 4-канальное реле будет активироваться на основе значения ppm для управления скоростью вентилятора, используя разные входы Vin на каждом канале реле.

Я использую библиотеку mq7.h, и вот мой код для справки:

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <MQ7.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);
MQ7 mq7(A0,5.0);
const int relay1Pin = D6;
const int relay2Pin = D7;
const int relay3Pin = D8;
const float lambat_threshold = 10; //в промилле
const float med_threshold = 20; //в промилле
const float cepat_threshold = 30; //в промилле

void setup()
{
Serial.begin(115200);
pinMode(A0, INPUT);
pinMode(relay1Pin, OUTPUT);
pinMode(relay2Pin, OUTPUT);
pinMode(relay3Pin, OUTPUT);
digitalWrite(relay1Pin, LOW);
digitalWrite(relay2Pin, LOW);
digitalWrite(relay3Pin, LOW);
lcd.begin();
lcd.backlight();
lcd.setCursor(00,00);
 lcd.print("Cooked Hood CO");
 lcd.setCursor(00,1);
 lcd.print("Istiyo Budi");
 delay(2000);
 lcd.clear();
}

void loop()
{
 float co = mq7.getPPM();
 lcd.setCursor(1, 0);
 lcd.print("CO: ");
 lcd.print(co);
 lcd.print(" PPM");
 delay(1000);
   Serial.print(co);
   Serial.println(" PPM");
   if (co < lambat_threshold) {
   digitalWrite(relay1Pin, HIGH);
   digitalWrite(relay2Pin, LOW);
   digitalWrite(relay3Pin, LOW);
   lcd.setCursor(1, 1);
   lcd.print("Speed: LOW");
 } else if (co >= med_threshold) {
   digitalWrite(relay1Pin, LOW);
   digitalWrite(relay2Pin, HIGH);
   digitalWrite(relay3Pin, LOW);
   lcd.setCursor(1, 1);
   lcd.print("Speed: MED");
 } else if (co >= cepat_threshold) {
   digitalWrite(relay1Pin, LOW);
   digitalWrite(relay2Pin, LOW);
   digitalWrite(relay3Pin, HIGH);
   lcd.setCursor(1, 1);
   lcd.print("Speed: HIGH");
   delay(2000);
}
}

Проблема в том, что когда значение около 30 или больше, реле не переключается. Я сейчас застрял с этой проблемой.

, 👍0

Обсуждение

у вас логическая ошибка в коде... посмотрите, что произойдет, когда PPM будет равен 15, @jsotola


2 ответа


0

Когда co >= cepat_threshold, это также > med_threshold
Поменяйте местами тесты, начиная с самого высокого значения:

if (co >= cepat_threshold) {
    digitalWrite(relay1Pin, LOW);
    digitalWrite(relay2Pin, LOW);
    digitalWrite(relay3Pin, HIGH);
    lcd.setCursor(1, 1);
    lcd.print("Speed: HIGH");
} else if (co >= med_threshold) {
    digitalWrite(relay1Pin, LOW);
    digitalWrite(relay2Pin, HIGH);
    digitalWrite(relay3Pin, LOW);
    lcd.setCursor(1, 1);
    lcd.print("Speed: MED");
} else {
    digitalWrite(relay1Pin, HIGH);
    digitalWrite(relay2Pin, LOW);
    digitalWrite(relay3Pin, LOW);
    lcd.setCursor(1, 1);
    lcd.print("Speed: LOW");
}
,

0

Посмотрите на структуру ваших операторов if ... else (ваше «дерево решений»). Представьте, что произойдет, когда ваш датчик CO вернет значение 30 (например).

Ваш код сначала оценивает if (co < lambat_threshold), что неверно, поскольку значение labat_threshold равно 10, а co равно 30. Он перейдет к части else первый оператор if.

Затем он оценивает if (co >= med_threshold), который оценивается как true, поскольку med_threshold равен 20, а 30 больше 20. Затем он выполняет команды в этом блоке кода ( т.е. включите реле 2 и выключите остальные реле) и напечатайте «MED»; на дисплее.

Ваш код тогда пропустит последнюю часть вашего блока принятия решения (т.е. else if (co > cepat_threshold) ), поскольку этот фрагмент вашего кода идет после else часть оператора if, который уже принял значение true.

Самый простой способ решить эту проблему — поменять местами части if (co >= med_threshold) и if (co >= cepat_threshold) вашего дерева решений. .

,