Не пойму как реализовать таймер.
- Войдите на сайт для отправки комментариев
Вс, 09/02/2020 - 02:57
Здравствуйте. Подскажите как сделать защиту от перелива по времени.
задача простая набирается бак если вдруг с датчиком проблема, т.е. бак не набрался за определенное время то реле отключается.
Moderator : пожалуйста, вставьте код правильно (возможно, новым сообщением в тему),
Зашел в тупик ничего не могу придумать.
Во первых, вставьте код по правилам форума. (в новом сообщении, т.к. первое сообщение нельзя редактировать)
В вторых, что значит зашли в тупик? Какой результат на деле у вас получается? Предоставьте схему соединения ардуино, реле и датчиков которые висят на EMPTYPin и FULLPin и когда(в какой момент процесса наполнения резервуара) по вашей задумке каждый датчик должен переходить из состояния LOW в HIGH и наоборот?
По вашей логике, как может быть что резервуар одновременно и пуст и полон ? elseif(EMPTY == HIGH && FULL == HIGH)?
Все логично. Следующая строка должна быть lcd.print "я/или ты/поломалсо. Звони в жэк/вызывай санитаров/.
А если серьезно, то такое возможно. Имена переменных дурацкие ток. Лучше обозвать lowerSensor и upperSensor, например.
Традиционно замечаю, что поплавковый механизм от унитаза стоит 200р.
У Вас это уже в привычку входит. Или это профессианальное?
const int EMPTYPin = 7; // нижний датчик: const int FULLPin = 8; // верхний датчик: const int Relay = 13; // реле: int EMPTY = 0; // переменная нижий уровень: int FULL = 0; // переменная верхний уровень: unsigned long times=0; void setup() { pinMode(Relay, OUTPUT); // initialize the Relay pin as an output: pinMode(EMPTYPin, INPUT); // initialize the EMPTYPin pin as an input: pinMode(FULLPin, INPUT); // initialize the FULLPin pin as an input: } void loop() { EMPTY = digitalRead (EMPTYPin); FULL = digitalRead (FULLPin); if (EMPTY == LOW && FULL == LOW) { // здесь включаем реле: digitalWrite(Relay, HIGH); times=millis(); } else if (EMPTY == HIGH && FULL == HIGH) { // здесь выключаем реле при наполнении: digitalWrite(Relay, LOW); } if (millis() - times >= 3000 ) { // здесь реле должно отключиться если прошло больше времени чем times: digitalWrite(Relay, LOW); delay (9000000000000); } }Резервуар пустой LOW полный HIGH.
Извиняюсь за имена переменных. Культуру написания переменных воспитывать годами надо.
на мой взгляд коротко и понятно.
Так а насчет вопроса Как?
По идее все должно выло работать нормально. Т.Е. само наполнение происходит как положено. Когда поплавок опустился в низ, оба датчика LOW, реле включилось. Поплавок поднялся, оба датчика HIGH, реле отключилось. При подаче питания все работает после того как реле стало LOW, т.е. отключилось таймер считает 3 секунды и уходит в аварию, а должен включаться после HIGH/
для начала определиться со временем наполнения к примеру
Для начала надо точно определиться - с какого момента считать. С EMPTY или с FULL.
Я думаю с соответствия условиям во время подачи питания? Т.Е. соответствует 1 условиям то реле включено,
а если другим то отключено.
для начала определиться со временем наполнения к примеру
Так у меня часов нет. Простой счетчик работающий от millis(), реле включилось, счетчик сбросился.
Я думаю с соответствия условиям во время подачи питания?
Вот поэтому все один раз и работает.
т.е. ваша ардуина включается вместе с насосом и должна или засечь FULL или выключить движок через 3 секунды?
#define SECONDS(x) ((x) * 1000UL) #define MINUTES(x) (SECONDS(x) * 60UL) #define HOURS(x) (MINUTES(x) * 60UL) #define DAYS(x) (HOURS(x) * 24UL) #define WEEKS(x) (DAYS(x) * 7UL) unsigned long interval = MINUTES(5); const int EMPTYPin = 7; // нижний датчик: const int FULLPin = 8; // верхний датчик: const int Relay = 13; // реле: int EMPTY = 0; // переменная нижий уровень: int FULL = 0; // переменная верхний уровень: unsigned long times=0; //byte flagtimer = 0; // в качестве флага можно использовать состояние реле void setup() { pinMode(Relay, OUTPUT); // initialize the Relay pin as an output: pinMode(EMPTYPin, INPUT); // initialize the EMPTYPin pin as an input: pinMode(FULLPin, INPUT); // initialize the FULLPin pin as an input: } void loop() { EMPTY = digitalRead (EMPTYPin); FULL = digitalRead (FULLPin); if(!EMPTY && !digitalRead(Relay)){ // здесь включаем реле: digitalWrite(Relay, HIGH); times=millis(); } if(FULL && digitalRead(Relay)){ // здесь выключаем по датчику digitalWrite(Relay, LOW); } if(millis()- times >= interval && digitalRead(Relay)){ // здесь выключаем по времени digitalWrite(Relay, LOW); } }понял про что говорилось. Спасибо за труд. Не пойму одного у Вас идет опрос идет одного датчика с привязкой к состоянию реле. Я так пробовал, не получилось.
Сейчас пробую ваш скетч тоже не правильно работает.За идею огромное спасибо. Буду сегодня пробовать.
Извиняюсь, но надо на работу.
состояние датчиков я принимал как включено, поправь если это не так, то-есть при достижении уровня в нижнем датчике -HIGH, аналогично и верхний, в системах ON это включено, а не наоборот, как у тебя )))
Делал исходя из фактических значений.
Здесь 4 состояния, но удовлетворяют условиям 2, когда оба датчика LOW (поплавок ВНИЗУ) включаем насос, когда оба HIGH (поплавок вверху)отключаем, именно оба датчика, потому что поплавок поднимает шток снизу вверх перекрывая сначала нижний , затем верхний. Промежуточные состояния игнорируются. А если вдруг, после включения реле, поплавок не дошел до верха за заданный период времени то отключаем выполнение программы с флагом аварии.
Без части отвечающей за временную составляющую все работает как надо. С учетом естественно механники. Как только начинаешь вставлять время, начинаются танцы.
Так это выглядит.
https://postimg.cc/yD78fQw8
https://i.postimg.cc/V6xLpNyh/image.png
Так это выглядит.
https://postimg.cc/yD78fQw8
https://i.postimg.cc/V6xLpNyh/image.png
Поменял значение на нижнем датчике, обязано работать, мог бы и сам это сделать, пост #13
Пардон. Прощёлкал. Теперь работает идеально. Но свой костыль с delay всё же вставил :-) Иначе опять по кругу запускает.
#define SECONDS(x) ((x) * 1000UL) #define MINUTES(x) (SECONDS(x) * 60UL) #define HOURS(x) (MINUTES(x) * 60UL) #define DAYS(x) (HOURS(x) * 24UL) #define WEEKS(x) (DAYS(x) * 7UL) unsigned long interval = MINUTES(1); const int EMPTYPin = 7; // нижний датчик: const int FULLPin = 8; // верхний датчик: const int Relay = 13; // реле: int EMPTY = 0; // переменная нижий уровень: int FULL = 0; // переменная верхний уровень: unsigned long times=0; //byte flagtimer = 0; // в качестве флага можно использовать состояние реле void setup() { pinMode(Relay, OUTPUT); // initialize the Relay pin as an output: pinMode(EMPTYPin, INPUT); // initialize the EMPTYPin pin as an input: pinMode(FULLPin, INPUT); // initialize the FULLPin pin as an input: } void loop() { EMPTY = digitalRead (EMPTYPin); FULL = digitalRead (FULLPin); if(!EMPTY && !digitalRead(Relay)){ // здесь включаем реле: digitalWrite(Relay, HIGH); times=millis(); } if(FULL && digitalRead(Relay)){ // здесь выключаем по датчику digitalWrite(Relay, LOW); } if(millis()- times >= interval && digitalRead(Relay)){ // здесь выключаем по времени digitalWrite(Relay, LOW); delay (9000000000000); } }СПАСИБО!!!!!!!
delay потом поменяю на цикл с диодом типа индикации.
Если рядом живете, с меня пиво. Я в Воронежской области.
На кой весь этот цирк с ардуиной при таком дилее?
Да просто поплавкового механизма от унитаза нет.
Это вроде как индикация ошибки. потом сделаю моргающий светодиод, вроде же написал.
Охренеть куда написал. Извиняюсь.
не может он повторно запускаться если нижний датчик не в нуле, а если вообще нужно, чтобы разово отработал мотор и не зависимо от датчиков загорелась авария если не достигнут верхний датчик выставляйте флаг и включаете его в условия запуска
А если авария нижнего датчика? Лучше пусть так. Надёжней. Ещё раз Спасибо! Вроде задача не сложная, но если не занимаешься этим часто, то и не простая.
Без разницы, зачем Вы воткнули это чудо - delay (9000000000000);
Но функция delay принимает аргумент типа Unsigned long, максимальное значение - 4 294 967 295. Так что, если бы Вам действительно была нужна именно такая задержка (9000000000000) Вас бы ждал сюрприз. Может и сейчас ждёт.
А зачем delay (9000000000000)? Есть прекрасная штука while(1);. Да и пищалку надо при аварии включить или светодиодик типа ERRORpin. А еще лучше while(1) if(buttonRESET) break;
А вообще любят у нас гланды через ж*пу... Посмотрите как работают электромеханические средства и их программируйте. Навскидку без паранойи:
void loop() { if(digitalRead (EMPTYPin)){ digitalWrite(Relay, HIGH); //тута запомнить текущий миллис while(!digitalRead (FULLPin)){ //вот тута можно прописать защиту по времени } digitalWrite(Relay, LOW); } }С паранойей - в строку 2 добавить
Получилось как - то так.
#define SECONDS(x) ((x) * 1000UL) #define MINUTES(x) (SECONDS(x) * 60UL) #define HOURS(x) (MINUTES(x) * 60UL) #define DAYS(x) (HOURS(x) * 24UL) #define WEEKS(x) (DAYS(x) * 7UL) unsigned long interval = MINUTES(1); const int EMPTYPin = 7; // нижний датчик: const int FULLPin = 8; // верхний датчик: const int Relay = 4; // реле: const int ResButton = 6; // кнопка сброса: const int Light = 13 ; // светодиод: int EMPTY = 0; // переменная нижий уровень: int FULL = 0; // переменная верхний уровень: unsigned long times=0; //byte flagtimer = 0; // в качестве флага можно использовать состояние реле void setup() { pinMode(Relay, OUTPUT); // initialize the Relay pin as an output: pinMode(Light, OUTPUT); // initialize the Light pin as an output: pinMode(EMPTYPin, INPUT); // initialize the EMPTYPin pin as an input: pinMode(FULLPin, INPUT); // initialize the FULLPin pin as an input: pinMode(ResButton, INPUT); // initialize the ResButton pin as an input: } void loop() { EMPTY = digitalRead (EMPTYPin); FULL = digitalRead (FULLPin); digitalWrite (Light,LOW); if (!EMPTY && !digitalRead(Relay)){ // здесь включаем реле: digitalWrite(Relay, HIGH); times=millis(); } if (FULL && digitalRead(Relay)){ // здесь выключаем по датчику digitalWrite(Relay, LOW); } if (millis()- times >= interval && digitalRead(Relay)){ // здесь выключаем по времени digitalWrite(Relay, LOW); while(!digitalRead(Relay)) { digitalWrite(Light, HIGH); // потому как на время уже пофигу поэтому delay delay(500); digitalWrite(Light, LOW); delay(500); if(digitalRead(ResButton)== HIGH) { break; } } } }можешь же когда захочешь )))
#include <Sim800l.h> #include <Wire.h> // Подключаем библиотеку Wire #include <Adafruit_Sensor.h> // Подключаем библиотеку Adafruit_Sensor #include <Adafruit_BME280.h> // Подключаем библиотеку Adafruit_BME280: pin= SCL(A5),pin=SDA(A4) #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); // Выводы SIM800L Tx & Rx подключены к выводам Arduino 3 и 2 #define SEALEVELPRESSURE_HPA (1013.25) // Задаем высоту Adafruit_BME280 bme; #define SECONDS(x) ((x) * 1000UL) #define MINUTES(x) (SECONDS(x) * 60UL) #define HOURS(x) (MINUTES(x) * 60UL) #define DAYS(x) (HOURS(x) * 24UL) #define WEEKS(x) (DAYS(x) * 7UL) unsigned long interval = MINUTES(1); char incomingByte; String inputString; int relay_1 = A0; // Вывод управления реле 1 int relay_2 = A1; // Вывод управления реле 2 //int pin = SCL(A5) // Вывод управления BME280 //int pin = SDA(A4) // Вывод управления BME280 float t; float p; float h; unsigned long times=0; unsigned long relay1OnMillis = 0; // время включения реле 1 unsigned long relay2OnMillis = 0; // время включения реле 2 const unsigned long relay1AutoOffinterval = 1000; // время автоотключение реле 1 в миллисекундах. (5000 = 5 секунд, 0 - АВТОВЫКЛЮЧЕНИЕ ВЫКЛЮЧЕНО) const unsigned long relay2AutoOffinterval = 4000; // время автоотключение реле 2 в миллисекундах. (5000 = 5 секунд, 0 - АВТОВЫКЛЮЧЕНИЕ ВЫКЛЮЧЕНО) // флаги, поднимаемые при включении реле, если их нужно автовыключить bool relay1AutoOff = false; bool relay2AutoOff = false; void setup() { pinMode(relay_1, OUTPUT); // Установим вывод как выход digitalWrite(relay_1, HIGH); // Устанавливаем высокий уровень pinMode(relay_2, OUTPUT); // Установим вывод как выход digitalWrite(relay_2, HIGH); // Устанавливаем высокий уровень Serial.begin(9600); mySerial.begin(9600); bme.begin(0x76); while (!mySerial.available()) { // Зацикливаем и ждем инициализацию SIM800L mySerial.println("AT"); // Отправка команды AT delay(1000); // Пауза Serial.println("Connecting…"); // Печатаем текст } Serial.println("Connected!"); // Печатаем текст mySerial.println("AT+CMGF=1"); // Отправка команды AT+CMGF=1 delay(1000); // Пауза mySerial.println("AT+CNMI=1,2,0,0,0"); // Отправка команды AT+CNMI=1,2,0,0,0 delay(1000); // Пауза mySerial.println("AT+CMGL=\"REC UNREAD\""); } void loop() { { //если автоключение реле включено и прошло заданное время автоотключения { { if (millis()- times >= interval && digitalRead(relay1AutoOffinterval)) // здесь выключаем по времени if (millis()- times >= interval && digitalRead(relay2AutoOffinterval)) // здесь выключаем по времени if (relay1AutoOff && millis() - relay1OnMillis >= relay1AutoOffinterval) { digitalWrite(relay_1, HIGH); //отключаем реле relay1AutoOff = false; // опускаем флаг "автоотключить реле" } if (relay2AutoOff && millis() - relay2OnMillis >= relay2AutoOffinterval) { digitalWrite(relay_2, HIGH); //отключаем реле relay2AutoOff = false; // опускаем флаг "автооключить реле" } if (mySerial.available()) { // Проверяем, если есть доступные данные delay(100); // Пауза while (mySerial.available()) { // Проверяем, есть ли еще данные. incomingByte = mySerial.read(); // Считываем байт и записываем в переменную incomingByte inputString += incomingByte; // Записываем считанный байт в массив inputString } delay(10); // Пауза Serial.println(inputString); // Отправка в "Мониторинг порта" считанные данные inputString.toUpperCase(); // Меняем все буквы на заглавные if (inputString.indexOf("DATA") > -1){ // Проверяем полученные данные t = bme.readTemperature(); h = bme.readHumidity(); p = (bme.readPressure() / 133.3F); sms(String("Temperature: " + String(t) + "*C " + " Humidity: " + String(h) + " % " + " Pressure: " + String(p) + "hPa"), String("+79227905354")); // Отправка SMS } if (inputString.indexOf("ON1") > -1) { // Проверяем полученные данные, если ON_1 включаем реле 1 digitalWrite(relay_1, LOW); if (relay1AutoOffinterval > 0) { //если включено автооключение { taimes = millis(); //запоминаем, когда реле включилось relay1AutoOff = true; //поднимаем флаг "автоотключить реле" } sms(String("Relay 1 - ON"), String("+89227905354")); } // Отправка SMS if (inputString.indexOf("OFF1") > -1) { // Проверяем полученные данные, если OFF_1 выклюем реле 1 digitalWrite(relay_1, HIGH); sms(String("Relay 1 - OFF"), String("+79227905354")); }// Отправка SMS if (inputString.indexOf("ON2") > -1) { // Проверяем полученные данные, если ON_2 включаем реле 2 digitalWrite(relay_2, LOW); if (relay2AutoOffinterval > 0) { times = millis(); relay2AutoOff = true; } sms(String("Relay 2 - ON"), String("+79227905354")); } // Отправка SMS if (inputString.indexOf("OFF2") > -1) { // Проверяем полученные данные, если OFF_2 выключаем реле 2 digitalWrite(relay_2, HIGH);{ } { sms(String("Relay 2 - OFF"), String("+79227905354")); } // Отправка SMS delay(50);} if (inputString.indexOf("OK") == -1) { mySerial.println("AT+CMGDA=\"DEL ALL\""); delay(1000); } inputString = ""; } } void sms(String text, String phone) // Процедура Отправка SMS { Serial.println("SMS send started"); mySerial.println("AT+CMGS=\"" + phone + "\""); delay(500); mySerial.print(text); delay(500); mySerial.print((char)26); delay(500); Serial.println("SMS send complete"); delay(2000); }Помогите исправит ошибки ГУРУ АРДУИНО уже сижу полдня но не как не могу исправить проблему. Не знаю правильно я дописал таймер отключения но компилятор постоянно выдает новые ошибки. Сейчас выделяет строку 131 что смс не был обьявлен в этом объеме. что то я уже совсем не могу понять в чем проблема. Если кому нетрудно подскажите что с этим делать? Заранее благодарю.
geka0110,
Все переменные и функции должны быть объявлено до использования.
Для людей с плохим зрением - до использования.
Для блондинок - они выше должны быть объявлены, чем используются.
Вы используете свою sms в 131 строке, а объявлена она у Вас в 142.
Взять книгу Кернигана и Ритчи (ссылка есть в разделе "Песочница") и читать, по ходу дела запуская и разбирая все примеры. И пока этот процесс не закончится - не лезть программировать что-то ещё.
Я бы Вам посоветовал отдельно разобраться с программой управления, а отдельно с СМС. Потом это объединить. Если это не скопирастенная программа, то Вам несложно будет разделить эти вещи и протестировать по отдельности. Если скопирастили - обратитесь к автору.
сам ты Блондинка если такой умный взял бы и помог.
сам не хрена не шаришь только такое писать умеешь.
Умники сидите тут а за помощью обратился все заднюю .
сам ты Блондинка если такой умный взял бы и помог.
сам не хрена не шаришь только такое писать умеешь.
Умники сидите тут а за помощью обратился все заднюю .
Вы, наверное, читаете по слогам или зациклены на ЧСВ. Вам доступно объяснили, что подпрограмму sms() надо перетащить на 39-ю строку. Вы ЭТО СДЕЛАЛИ? НЕТ? Так какого х*ра возмущаетесь?
взял бы и помог.
А я что, не помог? Не объяснил? Что-то осталось непонятным?
Мда, беру назад свои слова о блондинках и извиняюсь перед ними за невольную клевету. Объяснение:
Вы используете свою sms в 131 строке, а объявлена она у Вас в 142.