Помощь проектом слишком быстрого переключения реле водяного насоса.
У меня возникли проблемы с моим проектом.
Я использую датчик уровня воды с двумя выходами: вентилятор на 5 В и водяной насос. Вот схема подключения .
Что я хочу сделать с этим проектом:
- Когда уровень воды достигает 2 см, включается водяной насос, а вентилятор выключается.
- Когда уровень воды составляет менее 2 см, водяной насос выключается и включается вентилятор.
Проблема в том, что когда уровень воды ниже порогового значения, показания датчика весьма нестабильны, из-за чего реле переключается слишком быстро (посмотреть видео).
Как устранить эту проблему?
#include <Wire.h>
#include <Blynk.h>
#include <LiquidCrystal_I2C.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
//Инициализируем ЖК-дисплей
LiquidCrystal_I2C lcd(0x27, 16, 2);
char auth[] = "xxx";//Введите токен аутентификации
char ssid[] = "xxx";//Введите имя WIFI
char pass[] = "xxx";//Введите пароль WIFI
BlynkTimer timer;
#define pinSensor A0
#define PIN_RELAY_1 D3
#define PIN_RELAY_2 D4
const int startThreshold = 2; // откачка должна начаться при startThreshold [см] и выше
const int stopThreshold = 1; // перекачка должна начаться при стоп-пороге [см] и ниже
int sensorValue = 0; // целое число показаний датчика
float tinggiAir = 0; // высота воды
float sensorVoltage = 0; // датчик напряжения
int nilaiMax = 686; // максимальное значение датчика после его полного погружения в воду
float panjangSensor = 4.0 ; // высота датчика в см
enum StatusType {CHECKLEVEL, LEVELHIGH, PUMPING};
StatusType status = LEVELHIGH; // Начнем с LEVELHIGH, чтобы проверить уровень и правильно настроить отображение
void setup() {
Serial.begin(115200);
lcd.begin();
Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);
lcd.backlight();
pinMode(PIN_RELAY_1, OUTPUT);
pinMode(PIN_RELAY_2, OUTPUT);
digitalWrite(PIN_RELAY_1, LOW);
digitalWrite(PIN_RELAY_2, LOW);
lcd.setCursor(0, 0);
lcd.print("Water level");
lcd.setCursor(4, 1);
lcd.print("Monitoring");
delay(1000);
lcd.clear();
timer.setInterval(100L, wLevel);
}
void wLevel() {
sensorValue = analogRead(pinSensor);
tinggiAir = sensorValue*panjangSensor/nilaiMax;
sensorVoltage = sensorValue*5.0/686;
}
void loop() {
Blynk.run();
timer.run();
handleStatus();
}
void handleStatus() {
switch (status) {
case CHECKLEVEL:
// Ждем уровня выше порога
if (tinggiAir >= startThreshold) { // если wlevel больше, чем startThreshold [см], то
status = LEVELHIGH;
Serial.println("LEVELHIGH");
}
break;
case LEVELHIGH:
levelIsHigh();
break;
case PUMPING:
if (tinggiAir < stopThreshold) { // если wlevel меньше, чем stopThreshold [см] (используйте гистерезис!), то
levelIsLowAgain();
status = CHECKLEVEL;
Serial.println("CHECKLEVEL");
}
break;
}
displayValues();
}
void displayValues() {
static int oldSensorValue = -1; // переменная для хранения значения показания датчика в целочисленной форме
float oldTinggiAir = -1; // переменная для хранения уровня воды
float oldSensorVoltage = -1; // для хранения значения уровня воды
if (oldSensorValue != sensorValue ||
oldTinggiAir != tinggiAir ||
oldSensorVoltage != sensorVoltage) {
Serial.print("Sensor Value = ");
Serial.println(sensorValue);
Serial.print("Sensor Voltage = ");
Serial.println(sensorVoltage);
Serial.print("Tinggi Air = ");
Serial.println(tinggiAir);
Serial.println();
// Отображение ЖК-дисплея
lcd.setCursor(0, 0);
lcd.print("WLevel:");
lcd.print(tinggiAir);
lcd.setCursor(12, 0);
lcd.print("cm");
oldSensorValue = sensorValue;
oldTinggiAir = tinggiAir;
oldSensorVoltage = sensorVoltage;
Blynk.virtualWrite(V0, tinggiAir);
}
}
void levelIsHigh() {
digitalWrite(PIN_RELAY_1, HIGH);
digitalWrite(PIN_RELAY_2, LOW);
lcd.setCursor(0, 1);
lcd.print("F:OFF P:ON");
Blynk.logEvent("wlevel", "wLevel more than 2cm");
status = PUMPING;
Serial.println("PUMPING");
}
void levelIsLowAgain() {
digitalWrite(PIN_RELAY_1, LOW);
digitalWrite(PIN_RELAY_2, HIGH);
lcd.setCursor(0, 1);
lcd.print("F:ON P:OFF");
status = CHECKLEVEL;
Serial.println("CHECKLEVEL");
}
@jeonsann, 👍1
Обсуждение1 ответ
Проблема заключается в самой спецификации. По вашим правилам, что должен делать насос, если уровень воды ровно 2 см? Конечно, не существует такого понятия, как точные физические измерения. Но вы должны понимать, что каждая система измерения зашумлена. Шум – это факт жизни, с которым вам приходится иметь дело, играя с оборудованием. Вы можете попробуйте сделать его меньше (путем фильтрации), но он всегда будет там. Сейчас вопрос в том, что делать насосу, если разница между уровень воды и необходимые 2 см меньше амплитуды шума?
Стандартное решение, предложенное КМИВ, – реализовать некоторые гистерезис. Вы определяете два пороговых значения: один для включения насоса. и еще один, нижний порог его отключения. Когда будут показания между этими двумя порогами вы живете один насос, в каком бы то ни было заявите, что это было раньше.
В псевдокоде:
const float low_threshold = 1.9;
const float high_threshold = 2.1;
void loop() {
float water_level = get_level_reading();
if (water_level < low_threshold)
turn_pump_off();
if (water_level > high_threshold)
turn_pump_on();
}
Если разница между этими порогами больше, чем шум амплитуда, шум не будет мешать вашей системе.
- ESP8266 отключается через несколько часов
- Добавление WiFi к моему замку клавиатуры Arduino
- Как заставить 5-вольтовое реле работать с NodeMCU
- Простой запрос GET с ESP8266HTTPClient
- Esp8266 Vin контакт
- Правильный PIN для активации беспроводного реле с ESP8266 ESP-01
- Управление реле 5В с помощью Wemos D1 R1
- Чтение данных из Google Таблиц с помощью Nodemcu
Вы можете считать несколько значений с датчика уровня и усреднить их, чтобы получить более стабильные показания., @StarCat
И добавим немного гистерезиса, @KIIV
Попробуйте устранить дребезг датчика на несколько секунд, если вам не нужен более быстрый ответ., @Gil
Вы предпочитаете *программное решение* или *аппаратное решение*? Если аппаратное обеспечение, вам нужно найти компаратор (или операционный усилитель) — возможно, на вашем ESP8266 или отдельное аппаратное обеспечение. [REF1](https://circuitcellar.com/resources/comparator-hysteresis-2/), [REF2](https://www.electronics-tutorials.ws/opamp/op-amp-comparator.html)., @Seamus