Событие millis()
- Войдите на сайт для отправки комментариев
Вс, 03/04/2022 - 21:03
Всем привет. Не могу реализовать событие по времени. Суть такая. На экране каждую секунду выводится время, температура и влажность в помещении. Каждые 5 секунда должен включаться насос на 3 секунды и выключиться. Код привел. Время идет, температура и влажность меняется, все выводится на экран. А функция Watering не работает. Подскажите в чем ошибка
#include <Wire.h>
#include <DHT.h>
#include <iarduino_OLED_txt.h>
#include <iarduino_RTC.h>
#include <Adafruit_Sensor.h>
#define Pump_1 8
#define SENSOR_1 A2
#define MIN_S1 535
#define MAX_S1 215
#define Humidity_1 60
#define Pump_2 9
#define SENSOR_2 A3
#define MIN_S2 535
#define MAX_S2 215
#define Humidity_2 60
#define DHTPIN 2
#define DHTTYPE DHT22
iarduino_RTC time(RTC_DS1302, 10, 8, 9);
iarduino_OLED_txt myOLED(0x3C);
DHT dht(DHTPIN, DHTTYPE);
void Watch (void); // Объявляем функцию в которой будут выполняться действия зависящие от состояния энкодера и режима
void TempAndHumidity (void); // Объявляем функцию в которой будет обновляться информация дисплея в зависимости от режима, подрежима, выбранного таймера и значений массива valArray
void Watering (void);
String str_airtemp;
String str_airhumidity;
String str_humidity_S1;
String str_humidity_S2;
String str_CurrentTime;
extern uint8_t MediumFontRus[];
extern uint8_t SmallFontRus[];
unsigned long start_timer, end_timer;
uint32_t sensor_1, sensor_2;
uint32_t raw = 0;
uint32_t wait = 5 * 1000; //Прерывание
uint32_t pumping = 1 * 1000; //Время полива
uint32_t vkl = 1;
uint32_t otkl = 0;
const char* strM="JanFebMarAprMayJunJulAugSepOctNovDec"; // Определяем массив всех вариантов текстового представления текущего месяца.
const char* sysT=__TIME__; // Получаем время компиляции скетча в формате "SS:MM:HH".
const char* sysD=__DATE__; // Получаем дату компиляции скетча в формате "MMM:DD:YYYY", где МММ - текстовое представление текущего месяца, например: Jul.
// Парсим полученные значения sysT и sysD в массив i: // Определяем массив «i» из 6 элементов типа int, содержащий следующие значения: секунды, минуты, часы, день, месяц и год компиляции скетча.
const int i[6] {(sysT[6]-48)*10+(sysT[7]-48), (sysT[3]-48)*10+(sysT[4]-48), (sysT[0]-48)*10+(sysT[1]-48), (sysD[4]-48)*10+(sysD[5]-48), ((int)memmem(strM,36,sysD,3)+3-(int)&strM[0])/3, (sysD[9]-48)*10+(sysD[10]-48)};
void setup() {
Serial.begin(9600);
time.begin();
//time.settime(i[0],i[1],i[2],i[3],i[4],i[5]);
time.settime(__TIME__);
myOLED.begin();
myOLED.setFont(MediumFontRus);
dht.begin();
}
void loop() {
if(millis() % 1000 == 0)
{
Watch();
TempAndHumidity();
delay(1);
}
if(millis() % 5000 == 0)
{
Watering();
delay(1);
}
}
void Watch (void)
{
myOLED.print(time.gettime("H:i:s"), OLED_C, 1);
}
void TempAndHumidity (void)
{
int AirTemp = round(dht.readTemperature());
str_airtemp = "Темп:" + String(AirTemp) + "*C";
myOLED.print(str_airtemp,OLED_C,4);
int AirHumidity = round(dht.readHumidity());
str_airhumidity = "Влаж:" + String(AirHumidity) + "%";
myOLED.print(str_airhumidity,OLED_C,7);
}
void Watering (void)
{start_timer = millis();
digitalWrite(Pump_1,vkl);//насос включается
Serial.println(String(time.gettime("H:i:s"))+"-Включился");
if (millis() - start_timer >= 3000) //полив
{
digitalWrite(Pump_1,otkl); //насос выключается
Serial.println(String(time.gettime("H:i:s"))+"-Отлючился");
}
}
Эти комментарии не читайте, забыл убрать
Вот так никогда не делайте
millis() может проскочить мимо (тем более, что у Вас длительные операции с датчиками) и никогда на быть кратным 5000.
Делайте, как Вы делайте в строке №103.
Даже интересно каким образом условие в строке 103 может выполнится, учитывая строку 99 ?
Ну и опять же как сказал Петрович, если в строке 65 выражение в круглых скобках будет истинным, то никогда не выполнится строка 73, потому что там и delay(1) и куча тяжёлых функции.
ТС, учись программировать правильно, а не как ютубные рукожопы-сантехники.
Сначала проверки датчиков/таймеров, расчеты и взвод флагов.
А в конце по флагам действия с исполняющими устройствами. Количество ошибок сразу сократится и отслеживать оставшиеся будет проще.
Вот так никогда не делайте
millis() может проскочить мимо (тем более, что у Вас длительные операции с датчиками) и никогда на быть кратным 5000.
Делайте, как Вы делайте в строке №103.
Так тоже не надо, он сначала переменную к миллис приводит, а потом пытается проверить ее на условие millis()-start_timer>=3000.
Включим насос и никогда не выключим...
Соседи будут рады такому автополиву.
http://arduino.ru/forum/programmirovanie/upravlenie-neskolkimi-protsessa...
как оно сейчас "работает" знаю, а как сделать что работало как надо, догадаться не могу
к сожалению не помогло(
Что не помогло то? Выкладывай....
к сожалению не помогло(
Если это про ссылку выше, то естественно - там нет готового кода поливатора. Там про организацию работы нескольких процессов. В твоем случае процессов два - вывод информации на экран и управление насосом. Прочитай, вникни, разберись и сделай так, как там описано.
void Watering (void) { if(millis() - start_timer >= 5000) { sensor_1 = analogRead(SENSOR_1); // Читаем "сырые" данные с датчика, sensor_1 = map(sensor_1, MIN_S1, MAX_S1, 0, 100); // адаптируем значения от 0 до 100 sensor_2 = analogRead(SENSOR_2); // Читаем "сырые" данные с датчика, sensor_2 = map(sensor_2, MIN_S2, MAX_S2, 0, 100); // адаптируем значения от 0 до 100 str_humidity_S1 = "Влажность датчика 1 = " + String(sensor_1) + "%"; str_humidity_S2 = "Влажность датчика 2 = " + String(sensor_2) + "%"; start_timer = millis(); state = 1; digitalWrite(Pump_1,state);//насос включается Serial.println(String(time.gettime("H:i:s"))+"-Включился"); } if(state == 1 && millis() - start_timer >= pumping) //полив { state = 0; digitalWrite(Pump_1,state); //насос выключается Serial.println(String(time.gettime("H:i:s"))+"-Отключился"); } Получилось так. Но так наверно не очень грамотно. И появилась преблемка, что секунды на дисплее в момент включения насоса "00". Например, секунды идут: 01,02,03,04, в момент включения насоса 00, 06,07,08,09,00,11 и т.д.void setup() { Serial.begin(9600); time.begin(); //time.settime(i[0],i[1],i[2],i[3],i[4],i[5]); time.settime(__TIME__); myOLED.begin(); myOLED.setFont(MediumFontRus); dht.begin(); } void loop() { if (millis() - currentTime > 1000) { currentTime = millis(); Watch(); TempAndHumidity(); } Watering(); } void Watch (void) { myOLED.print(time.gettime("H:i:s"), OLED_C, 1); } void TempAndHumidity (void) { int AirTemp = round(dht.readTemperature()); str_airtemp = "Темп:" + String(AirTemp) + "*C"; myOLED.print(str_airtemp,OLED_C,4); int AirHumidity = round(dht.readHumidity()); str_airhumidity = "Влаж:" + String(AirHumidity) + "%"; myOLED.print(str_airhumidity,OLED_C,7); } void Watering (void) { if(millis() - start_timer >= 5000) { sensor_1 = analogRead(SENSOR_1); // Читаем "сырые" данные с датчика, sensor_1 = map(sensor_1, MIN_S1, MAX_S1, 0, 100); // адаптируем значения от 0 до 100 sensor_2 = analogRead(SENSOR_2); // Читаем "сырые" данные с датчика, sensor_2 = map(sensor_2, MIN_S2, MAX_S2, 0, 100); // адаптируем значения от 0 до 100 str_humidity_S1 = "Влажность датчика 1 = " + String(sensor_1) + "%"; str_humidity_S2 = "Влажность датчика 2 = " + String(sensor_2) + "%"; start_timer = millis(); state = 1; digitalWrite(Pump_1,state);//насос включается Serial.println(String(time.gettime("H:i:s"))+"-Включился"); } if(state == 1 && millis() - start_timer >= pumping) //полив { state = 0; digitalWrite(Pump_1,state); //насос выключается Serial.println(String(time.gettime("H:i:s"))+"-Отлючился"); } }Хоть немножко то правильно? грамотнее?
Работает? Что еще-то нужно? ))
ЗЫ: на помпе нужно бы конденсатор припаять. Примерно на 100нФ (это с маркировкой 104). Дабы помехи давить
Конденсатор поставлю, как только насос придет)
Работает, но в момент запуска насоса, на часах вместо секунд 00 показывает. Значит что-то не так. Да и потом, надо чтобы правильно работало и код красивый был. А не, пардон, га*нокод какой-то
Конденсатор поставлю, как только насос придет)
Работает, но в момент запуска насоса, на часах вместо секунд 00 показывает. Значит что-то не так. Да и потом, надо чтобы правильно работало и код красивый был. А не, пардон, га*нокод какой-то
Т.е. сейчас насоса нет?
Насчет нуля ничего не скажу - не вижу используемых библиотек. Наверное, что-то не так ))
Красивый код - это со временем придет. Возможно. Да и потом любой "спец" может любой код говнокодом обозвать )))
Насоса пока нет, едет) пока только 2 датчика влажности почвы есть.
Библиотеки:
И получается вот такое:
Не больно хвалят эту библиотеку
Если в коде все верно, буду копать в сторону библиотек! Спасибо огромное, Уважаемый v258)
По логу уже вижу, что на все про все уходит 5 секунд, а по условию вроде должно быть 5 + 3 = 8 секунд. Или нет?
Опрос датчиков проводится каждые 5 секунд. Если значение датчика ниже заданного, на 3 секунды включается насос.
Если значение датчика ниже заданного, на 3 секунды включается насос.
Нету в коде никакого если. Насос включается каждые пять секунд в любом случае
Пардон, ввожу в заблуждение. Это то, что хочу реализовать. Сейчас для понимания как функция миллис работает пытаюсь реализовать, чтобы каждые 5 секунд включался насос на 3 секунды.
Ну это получилось
еще раз спасибо!)
Точно! А на вопрос "какое же это говно?" ответит, "не знаю, в сортах говна не разбираюсь" :-)