Таймер включения нагрузки на 10 минут на ARDUINO UNO
- Войдите на сайт для отправки комментариев
Пт, 18/04/2014 - 23:09
Добрый день.
Подскажите, как можно решить следующую задачу. Необходимо запрограммировать включение мотора от кнопки ровно на 10 минут, не используя функцию delay(), т.е. цикл loop не должен
останавливаться.
В любой момент двигатель можно выключить и включать этой же кнопкой, но он автоматически
должен отключаться через 10 мин после включения. В качестве индикатора включения насоса
будет служить индикатор LED13.
Вот моя заготовка программы:
// Таймер включения мотора на 10 минут
//
const int buttonPOWER = 7; // Кнопка включения и выключения мотора, 10k на землю.
const int LedPOWER = 13; // Выход на реле мотора
// Переменные для работы с кнопкой
int buttonStatePOWER = 0;
int old_val = 0;
int state = 0;
int StartMotor = 0; // Маркер запуск мотора
long previousMillisMotor = 0; // Засекаем время на момент включения Мотора
void setup() {
pinMode(buttonPOWER, INPUT);
pinMode(LedPOWER, OUTPUT);
digitalWrite(LedPOWER, LOW);
Serial.begin(9600); // монитор порта для диагностики
}
void loop() {
// -----Организация включения кнопки POWER с защитой от дребезга контактов---
buttonStatePOWER = digitalRead(buttonPOWER);
if ((buttonStatePOWER == HIGH)&&(old_val == LOW)) {
state = 1 - state;
delay(200);
}
old_val = buttonStatePOWER;
if (state == 1) {
if ((StartMotor == 0)&&(old_val == HIGH)) { unsigned long previousMillisMotor = millis();
// Засечка времени
Serial.println("StartMotor=1");
Serial.println(previousMillisMotor); // смотрим время засечки
}
StartMotor=1;
} else
{ StartMotor=0; Serial.println("StartMotor=0");}
// -------------------------------------------------------
//--------------Управление мотором------------------------
if (StartMotor == 1) {
digitalWrite(LedPOWER, HIGH); // включение мотора
// далее, действия при включении мотора
// опрос теплового и т.д.
}
}
Для этой задачи использую ARDUINO UNO R3 с контроллером ATmega8 c загруженным bootloader'om на внутренний кварц 8 МГц.
Нельзя просто так взять
и написать понятно.
Пробуем обдумать, чего надо от программы. Я так понимаю:
1. Вкл/выкл двигателя, + показать состояние светиком на D13. Надо: одна переменная bool.
2. Всё равно выкл через 10 минут. Надо:
- с допустимой ошибкой в единицы секунд - по millis(), то есть одна переменная unsigned long, или
- с допустимой ошибкой меньше секунды - тогда надо RTC (например 1307), часовой кварц и все дела
3. послать в сериал, по факту действия.
Итак, в случае версии с milis() будет так:
#define pin_led (13) #define pin_motor (12) #define pin_btn (7) unsigned long last_on; boolean state_on; void setup(){ pinMode(pin_led,OUTPUT); // peripheral configuration pinMode(pin_motor,OUTPUT); pinMode(pin_btn,INPUT_PULLUP); Serial.begin(9600); last_on=0; state_on=false; // initial state (off) changestate(); } void changestate(){ digitalWrite(pin_led,state_on); digitalWrite(pin_led,state_on); if(state_on){ Serial.println('Motor state: ON'); Serial.print('On time:'); Serial.println(last_on,DEC); }else{ Serial.println('Motor state: OFF'); } delay(1500); } void loop(){ if(state_on){ // motor on if(digitalRead(pin_btn)==LOW){ // button pressed state_on=false; changestate(); } if(millis()-last_on>=600000){ // time expired (600000 ms = 10 min) state_on=false; changestate(); } }else{ // motor off if(digitalRead(pin_btn)==LOW){ // button pressed state_on=true; last_on=millis(); changestate(); } } }В случае версии на часах - нужна библиотека, и собсно часы. Заводим переменную типа, ну скажем long. Хотя чё мелочиться, можно и unsigned long. Читаем из часов минуты, секунды, пишем в эту переменную по формуле минуты*60+секунды. Прибавляем 600, потом каждый раз читаем из часов, считаем по той же формуле другую переменную такого же типа, сравниваем. Всё остальное будет такое же.
Delay в функции changestate() - защита от повторного срабатывания цикла, тогда следующее действие кнопки выполнится не раньше 1500 мс. Если убрать, то двиг может включиться и тут же выключиться, т. к. loop() выполняется достаточно быстро, чтобы успеть обработать условие несколько раз за то время, пока жмут кнопку.
std, огромное спасибо за пример, пришлось немного подкорректировать код после вставки в Arduino:
Serial.println('Motor state: ON');
на
Serial.println("Motor state: ON");
иначе вместо текста в COM порт почему то передавались какие то цифры:
благодаря вашему коду нашел у себя ошибку из за чего у меня не работало:
В секции описания переменной в моем коде было const unsigned long TimePower=1000*60*10; 10 мин.
TimePower почему то вычислялся как 10176 !
Исправил TimePower=600000;
стало нормально
//--------------Управление мотором------------------------ if (StartMotor == 1) { digitalWrite(LedPOWER, HIGH); // включение мотора //---- Функция выключения через 10 минут-------------------- currentTime = millis(); // считываем текущее время if (currentTime >= (previousMillisMotor+TimePower)) // сравниваем текущий таймер с переменной previousMillisMotor + 10 мин. { StartMotor == 0; // Здесь тоже была ошибка StartMotor = 0; previousMillisMotor = currentTime; // в previousMillisMotor записываем новое значение } //---------------------------------------------------------- // далее, действия при включении мотора // опрос теплового и т.д. } if (StartMotor == 0) { digitalWrite(LedPOWER, LOW); // выключение мотора // далее, действия при выключении мотора } }Добрый день!
Как ваш таймер? Откорректированный счетч можете выложить?
доброго времени суток. Подскажите пожалуййста что и как делаю не так.
Задача: включить 3 реле по температуре. Код написан на один светодио, как пример, сигнализирует о срабатывании одного реле. То есть при понижении температуры ниже 39 градусов включить реле с задержеой по времени 15 секунд первое реле, 30 секунд .
второе. 3 реле включить одновременно с первыйм, ну и чтобы вывод температуры на дисплей был постоянно
int ledPin = 6 ; // Светодиод подключенный к вход/выходу 12 #define ONE_WIRE_BUS 5 // пин 5 к которому подключен датчик OneWire oneWire(ONE_WIRE_BUS); // настройка объекта oneWire для связи с любым устройством OneWire DallasTemperature sensors(&oneWire);// передать ссылку на oneWire библиотеке DallasTemperature void draw(void) { // настрока дисплея u8g.setFont(u8g_font_gdr30); u8g.setPrintPos(20, 31); u8g.print(sensors.getTempCByIndex(0)); } void setup(void){ sensors.begin(); // запустить библиотеку Serial.begin(9600); pinMode(ledPin, OUTPUT); // устанавливает режим работы - выход digitalWrite(ledPin, LOW); // устанавливаем в выключенное положение } void loop(void){ sensors.requestTemperatures(); // отправить команду для получения температуры Serial.println(sensors.getTempCByIndex(0)); // напечатать температуру в градусах Цельсия u8g.firstPage(); do { draw(); } while( u8g.nextPage() ); while((sensors.getTempCByIndex(0) <= 30)){ // условие, температура меньше 30 сделать... delay(15000); // задержка времени по включению digitalWrite(ledPin, HIGH); //включить реле break; // вернуться в цикл } // while((sensors.getTempCByIndex(0) >= 30)){ // digitalWrite(ledPin, LOW); // } // if((sensors.getTempCByIndex(0) <= 30)) // условие, если температуру меньше указанного значения то... // digitalWrite(ledPin, HIGH); // строка деййствия условия if((sensors.getTempCByIndex(0) >= 31)) // условие, если температуру меньше указанного значения то... digitalWrite(ledPin, LOW); // строка деййствия условия delay(500); }Подскажите пожалуййста что и как делаю не так.
все
ЭТО ПРОСТО ЛОЛ,
надо включить ТРИ РЕЛЕ, но код написан на ОДИН СВЕТОДИОД?
ага, и все это на примере одного светодиода? :)
Ghost33 - вы реально такой тупой или просто троллите форум? - в любом случае отвечать вам по существу нет смысла.
Выложите реальный код на три реле, а не "для примера". Нахрена кто-то должен тратить время на разбор "примера", не имеющего ничего общего с реальностью?