Ошибка при попытке динамического моделирования температуры
Я пытаюсь смоделировать динамическую температуру, используя небольшой набор данных с помощью ESP32. Я только что понял, что реле не меняет состояние, если есть какое-то изменение температуры выше или ниже порога.
Если температура начинает опускаться ниже моделируемой, реле включается, но как только оно достигает температуры модели или превышает ее, состояние не меняется, и система прогревается до следующей модели.
Я что-то упускаю в своем коде?
#include <OneWire.h>
#include <DallasTemperature.h>
#include <NTPClient.h>
#include <WiFi.h>
#include <WiFiUdp.h>
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 7200, 60000); //UTC+1 (Europe)
unsigned long current_time;
#define WIFI_AP "xxxxx"
#define WIFI_PASSWORD "xxxxx"
//WiFi SETUP
WiFiClient wifiClient;
int status = WL_IDLE_STATUS;
unsigned long lastSend;
const int oneWireBus1 = 0;
OneWire oneWire1 (oneWireBus1);
DallasTemperature sensors1 (&oneWire1);
const int relay1 = 02;
struct SetPoint {
unsigned long time;
float temperature;
};
#define DATA_SIZE 17
SetPoint scen1[DATA_SIZE] = {
{1622652330,26.97},//18h
{1622652390,25.62},
{1622678400,24.87},
{1622689200,24.16},
{1622700000,23.86},
{1622710800,25.17},
{1622721600,26.41},
{1622732400,27.22},
{1622743200,26.78},
{1622754000,25.83},
{1622764800,25.1},
{1622775600,24.6},
{1622786400,24.24},
{1622797200,26.81},
{1622808000,29.35},
{1622818800,29.38},
{1622829600,30.5}
};
unsigned int pos = 0;
void setup() {
Serial.begin(115200);
sensors1.begin();
pinMode(relay1, OUTPUT);
InitWiFi();
lastSend = 0;
timeClient.begin();
void loop() {
sensors1.requestTemperatures();
float temperature1 = sensors1.getTempCByIndex(0);
timeClient.update();
long current_time = timeClient.getEpochTime();
if (pos < DATA_SIZE && current_time >= scen1[pos].time) {
if (temperature1 < scen1[pos].temperature) {
digitalWrite (relay1, HIGH);
}
else if (temperature1 > scen1[pos].temperature) {
digitalWrite (relay1, LOW);
}
pos++;
}
Serial.println(timeClient.getEpochTime());
Serial.println(timeClient.getFormattedTime());
Serial.println(pos);
Serial.println(scen1[pos].temperature);
Serial.println(scen1[pos-1].temperature);
Serial.print("Temperature Censius - Sensor 1: ");
Serial.print(temperature1);
Serial.println(" ºC ");
delay(3000);
}
(ОБНОВЛЕНИЕ)
Замена первого if
на while
ничего не меняет.
Код работает при выводе if
/ else if
из вложенного if
, но в этом случае я не могу увеличить время (pos++
также комментируется) и определить ограничения в соответствии с размером массива.
// if (pos < DATA_SIZE && current_time >= scen1[pos].time) {
if ((temperature1 < scen1[pos].temperature)&& (current_time >= scen1[pos].time)) {
digitalWrite (relay1, HIGH);
}
else if ((temperature1 > scen1[pos].temperature)&&(current_time >= scen1[pos].time)) {
digitalWrite (relay1, LOW);
}
// pos++;
// }
@s_tatus3, 👍2
Обсуждение1 ответ
Лучший ответ:
Я должен удалить pos++
из оператора if, чтобы digitalWrite снова работал в соответствии с захваченной температурой:
if (pos < DATA_SIZE && current_time >= scen1[pos].time) {
if (temperature1 < scen1[pos].temperature) {
digitalWrite (relay1, HIGH);
}
else if (temperature1 > scen1[pos].temperature) {
digitalWrite (relay1, LOW);
}
}
Очевидно, что это не время обновления, и система застревает во времени 0 массива.
(ОБНОВЛЕНИЕ)
Как хорошо заметил Дэйв Ньютон, предыдущее наблюдение бессмысленно, чтобы действительно решить проблему.
Проблема была устранена с помощью оператора if, который управляет реле изнутри оператора, управляющего временем.
Теперь я могу смоделировать временной интервал, определенный с помощью массива, и использовать температуру (также присутствующую в массиве) для включения/выключения реле, которое управляет нагревателем и имитирует температуру окружающей среды:
Сначала я создал функцию, которая будет работать как термостат:
void set_thermostat() {
sensors1.requestTemperatures();
float temperature1 = sensors1.getTempCByIndex(0);
if (temperature1 < scen1[pos].temperature) {
digitalWrite (relay1, HIGH);
}
else if (temperature1 > scen1[pos].temperature) {
digitalWrite (relay1, LOW);
}
}
Тогда я могу это сделать в функции цикла
, вне оператора, который увеличивает время, основываясь на том, которое определено массивом:
if (pos < DATA_SIZE && current_time >= scen1[pos].times) {
pos++;
}
set_thermostat();
Это воспроизводит именно то, что я искал, с контролем температуры в реальном времени, сравнивая температуру окружающей среды с моделью.
Таким образом, он проходит через петлю, что все еще означает, что сравнение времени терпит неудачу. Отсюда и неоднократное предложение проверить свои предположения, посмотрев на время. Мы никак не можем помочь вам, не зная, какие значения данных сравниваются, и вы не станете ими делиться. Это не ответ на проблему, это обходной путь, который ломает программу., @Dave Newton
Спасибо. Да, я проверил "таймс". Я сравнил current_time
и scen1[pos].time
. Упростил код и проверил, равен ли current_time или больше scen1[pos].time
. Выход правильный (с использованием разных времен и интервалов). Поэтому я ожидаю, что заявление будет работать нормально. Я не знаю, означает ли проверка предположений что-то еще из того, что я уже сделал., @s_tatus3
Я имел в виду, что *мы* не можем проверить ваши предположения или предоставить какой-либо значимый вклад, не зная, что происходит на самом деле. Сравнения обычно просто работают, поэтому, если удаление pos++
"исправляет" его (ergo pos < DATA_SIZE
forever) это означает, что есть проблема в сравнении времени. Но мы не можем видеть ни одно из сравниваемых значений, поэтому все, что мы можем сделать, это догадаться., @Dave Newton
Я вижу и согласен. Обновил ответ решением (это действительно воспроизводит то, что я хочу)., @s_tatus3
- Подключите реле 5 В к плате ESP32 WROVER B
- Для управления переключением реле в nextion с помощью микроконтроллера esp32
- ESP32 прекращает цикл после двух циклов
- Нужна документация для почвенного датчика от DIYmore
- ESP32 изо всех сил пытается последовательно запустить 4- канальный релейный модуль 5 В
- esp32 аварийно завершает работу при попытке разыменования значения указателя
- Ошибка выполнения ESP32 в массиве 2d
- Частое включение и выключение в SSR
Попробовал заменить " if " на "while" на " while (pos < DATA_SIZE && current_time >= scen1[pos].time)`. Но никаких изменений, @s_tatus3
Еще, если "может быть просто" еще
. Я бы начал с того, что убедился, что вводится оператор "если", а затем проверил бы вменяемость двух температур в сравнении. также может быть полезно настроить испытательную установку, которая сжимает время и подделывает данные датчика., @Dave NewtonСпасибо, @DaveNewton. Да, изменил "else if", используя только "else", но, похоже, работает аналогично. Кроме того, время сжатия (в моем случае я установил интервал 1 минута и 2 минуты) реле не меняется с моделируемыми временными данными., @s_tatus3
Поэтому я думаю, что сброс
temperature1
иscen1[pos].temperature
был бы хорошей идеей для проверки всех предположений. В данный момент нет ничего очевидного, что бросалось бы мне в глаза. (Переход отelse if
кelse
не был исправлением, просто упрощением.) Я бы нормализовал все значения времени до "unsigned long" (в настоящее время вы смешиваете сравнения "long" и "unsigned long", но старший бит не установлен, поэтому не имеет значения., @Dave NewtonМне удалось отбросить
if (pos < DATA_SIZE && current_time >= scen1[pos].time) "и использовать только" if " и
if else/
else`. Я сохранил как "temperature1", так и "scen1[pos].temperature", и цикл работает нормально. Таким образом, я мог бы определить, в чем проблема. Очевидно, теперь я должен увидеть, как добавить оператор/цикл для времени, @s_tatus3Я не уверен, что вы только что сказали, но если вы сравниваете жестко закодированное время с фактическим временем, вам может быть лучше иметь только time *offsets* в
scen1.time
и добавлять известное смещение "реального"времени, чтобы они были в будущем. Мне не очень понятно, что вы пытаетесь здесь сделать, но если вы пытаетесь что-то проверить, то я бы не использовал ничего "реального", кроме простой проверки разницы во времени на борту., @Dave NewtonСпасибо, @DaveNewton. Извини, я не совсем ясно выразился. Просто обновил пост с предыдущей информацией, так что теперь легче показать, как я тестировал и в чем текущая проблема., @s_tatus3
Таким образом, сравнение времени, скорее всего, терпит неудачу (или оно очень быстро проходит через цикл, если время всегда >=). Следовательно, вычеркните значения сравнения, чтобы проверить предположения., @Dave Newton