Включить реле на определенное время, а затем выключить

oleg09
Offline
Зарегистрирован: 19.11.2015

Доброго  времени суток уважаемые форумчане!

Не так давно озадачился внедрением CarPC в свое авто. В начале управление питанием было полуручное, но теперь решил использовать arduino pro micro для автоматизации. Имеется скетч, в котором реле управляющее экраном включается/выключается при соблюдении определенных условий. Никак не могу разобраться как поправить скетч для того чтобы реле, при соблюдении того или другого условия включалось на определенное время, а затем выключалось. Буду благодарен за любую помощь. Код прикладываю...


//Добавление библиотек из состава avr 
#include <avr/sleep.h>  //библиотека для засыпания устройства http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html 
#include <avr/power.h>  //библиотека включения/выключения различных устройств, портов usb, и т п, например для энергосбережения

//Объявление переменных и присвоение им значений
int ACCPin = 2; // Пин АСС 
int sleepStatus = 0; // Переменная для хранения статуса (спим, проснулись)

//Объявление констант и их значений, на которые будут они заменены при компиляции.
#define pinKIS1 7       // пин управления питанием HUB
#define relePinTablet 9 // OTG + датчик холла
#define ONKIS 100       // время включения HUB
#define ONTablet 2000   // время включения планшета
#define OFFKIS 10000    // время задержки выключения HUB
#define OFFTablet 5000  // время выключения планшета

//Объявление переменных и присвоение им значений
unsigned long duration, off = 0; // Время включения и выключения
boolean stateACC, relestate1, relestate2;          //Объявляем переменные stateACC - статус наличия ACC
                                                   //Объявляем переменные relestate1 - статус питания хаба
                                                   //Объявляем переменные relestate2 - статус включения экрана (датчик холла)
                                                          


void wakeUpNow()                 // Функция, сработает после пробуждения
{
  if (sleepStatus)               // Если мы спали,
     {
       sleep_disable();             // то первое, что нужно сделать после просыпания - выключить спящий режим
       sleepStatus = 0;             // В переменную заносим статус бодрствования
       detachInterrupt(1);          // Выключаем прерывание - при нормальном режиме wakeUpNow() не будет вызываться
     }
}


void setup()       //Функция setup() вызывается, когда стартует скетч. Используется для инициализации переменных, определения режимов работы выводов, запуска используемых библиотек и т.д. Функция setup запускает только один раз, после каждой подачи питания или сброса платы Arduino.
{
  pinMode(ACCPin, INPUT);                    //Установка режима работы пина 2 (ACCPin) в режим входа
  attachInterrupt(1, wakeUpNow, FALLING);    //Используем прерывание 1 (pin 2) для выполнения функции wakeUpNow  При появлении сигнала FALLING (изменение сигана с высокого уровня на низкий) 
                                             // на прерывании 1, происходит выполнение функции  wakeUpNow  (прерывание 1 на входе 2 только для Леонардо, у других плат может быть иначе)
  pinMode(pinKIS1, OUTPUT);                  //7 пин выход - управляет работой хаба
  pinMode(relePinTablet, OUTPUT);            //9 пин выход - управляет датчиком холла и отг
}

void sleepNow()                              // Функция увода ардуины в спячку.
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);       // Здесь устанавливается режим сна
  sleep_enable();                            // Включаем sleep-бит в регистре mcucr. Теперь возможен слип 
      
  attachInterrupt(1, wakeUpNow, FALLING);    // Используем прерывание 1 (pin 2) для выполнения функции wakeUpNow при появлении низкого уровня на пине 2
  
  sleepStatus = 1;                           // В переменную заносим статус сна
  sleep_mode();                              // Здесь устройство перейдет в режим сна!!!
  //-------------------------ПОСЛЕ ПРОСЫПАНИЯ ВЫПОЛНЕНИЕ КОДА ПРОДОЛЖИТСЯ ОТСЮДА!!!--------------------------//
}


void loop()       //Функция выполняющаяся по кругу в активном состоянии Arduino
{
  Power(); //Вызываем функцию управления питанием
  delay(10);  //Задержка 10мс (0,01секунды)
}

//Функция управления питанием
void Power() 
{
   if (!digitalRead(ACCPin)&&stateACC)   //Если появился АСС (есть земля на пине АСС, а до этого в переменной stateACC была "1", те ACC не было)
      {
        stateACC=0;                      //записываем статус АСС "0", те ACC есть
        duration = millis();             //Запоминаем текущее время(с момента включения)
      }

   if (digitalRead(ACCPin)&&!stateACC)   //Если пропал АСС (на пине АСС +5в, а до этого в переменной stateACC не была "1", те ACC был)
      {
        stateACC=1;                      //записываем статус асс выкл
        off = millis();                  //сохраняем время отключения асс
      }

   if(!digitalRead(ACCPin) && !stateACC && millis ()-duration > ONKIS)  //Если прошло более 0,1 сек с момента прявления ACC (АСС есть и был до этого, и время с момента включения более 0.1 сек)
      {
        digitalWrite(pinKIS1, HIGH);     //включаем хаб
        relestate1 = 1;                  //записываем статус хаба - включен
      }

   if(!digitalRead(ACCPin) && !stateACC && millis ()-duration > ONTablet) //Если прошло более 2 сек с момента появления ACC Если ACC есть и был до этого, и время с момента включения более 2 сек 
      {
        digitalWrite(relePinTablet, HIGH);//включаем экран и отг
        relestate2 = 1;                   //записываем статус включения экрана
      }

   if(digitalRead(ACCPin) && stateACC &&  millis ()-off > OFFTablet)  //Если нет АСС, не было и прошло 5 сек с момента его откл-я                                                               
      {
        digitalWrite(relePinTablet, LOW); //тушим экран
        relestate2 = 0;                   //сохраняем состояние экрана выкл
      }
      
   if(digitalRead(ACCPin) && stateACC && millis () -off> OFFKIS)  // Если нет АСС, не было и прошло 10 сек с момента его откл-я 
      {
        digitalWrite(pinKIS1, LOW);       //отключаем хаб
        relestate1 = 0;                   //записываем статус хаба выкл
        delay(100);                       //задержка 0,1сек
        sleepNow();                       //вызываем функцию засыпания
      } 
}

 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

попробуйте на основе этого


const int led = 13;
unsigned long previousMillis = 0;
unsigned long interval = 10000;   //время в мс удержания включенным
int sw = 0; 

void setup() {
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

void loop() {
  unsigned long currentMillis = millis();
  switch (sw) {
    case 0:
      if (currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
        sw = 1;
      }
      else {
        digitalWrite(led, HIGH);
      }
      break;
    case 1:
      digitalWrite(led, LOW);
      break;
  }
}

 

oleg09
Offline
Зарегистрирован: 19.11.2015

 Не получается вписать в рамки моего скетча - работать вообще не хочет.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Может так, накидка условная

unsigned long duration, off, onRele = 0; // Добавляем переменную onRele
static int f_rele = 0;// Добавляем переменную флаг реле
if (uslovie1==1 && f_rele == 0)//Если сработало условие
{
  onRele=millis();//Засекаем время
  f_rele = 1;//Флаг ставим в 1 чтобы время засекалось 1 раз
  digitalWrite (relepin, HIGH);//включаем реле
}

if (f_rele==1 && millis()-onRele >=500)// проверяем прошло ли время 100-любое и если да то-
{
  f_rele = 0;//Флаг в 0 чтобы больше сюда не возвращаться
digitalWrite (relepin, LOW);//Реле выключаем
}

 

Evgenii
Evgenii аватар
Offline
Зарегистрирован: 30.07.2012

Почему при выполнении этого кода реле постоянно включено?