Автоматическое включение света и вентилятора

mrbin
Offline
Зарегистрирован: 01.02.2015

Ребята подскажите не опытному,хочу сделать в помещение  автоматическое включение света и вентилятора на ардуино,тоесть зашел человек датчик его увидел,включил свет и если человек находится там более 2х минут,включилась вытяжка на 10минут ,и при выходе человека из помещения свет гаснул а вытяжка работала заданое время,подскажите в какую сторону копать,как обнаружить и включить я знаю,а как сделать промежуток не знаю.

nikolaki
nikolaki аватар
Offline
Зарегистрирован: 14.02.2013

Смотри тута

mrbin
Offline
Зарегистрирован: 01.02.2015

Cпасибо! но ни чего полезного для себя не нашел

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015
unsigned long previousMillis = 0;
long interval = 600000; //интервал в миллисекундах (10 минут)

unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval)
{
  previousMillis = currentMillis;
  //тут делаем что надо через заданное время
  //включаем выключаем и прочее
}

 

mrbin
Offline
Зарегистрирован: 01.02.2015

Большое спасибо! буду разбиратся

 

mrbin
Offline
Зарегистрирован: 01.02.2015

Здравствуйте! Penni,подскажите пожалуйста как прописать что бы мигала два светодиода с разным промежутком времени

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Можно использовать вот это http://alxarduino.blogspot.ru/2013/09/ComfortablyBlinkWithoutDelay.html тогда код будет красивый и легкочитаемый.

Практически тоже самое кодом

#define BLINK_INTERVAL1 1000
#define BLINK_INTERVAL2 2000

unsigned long prevBlinkTime1 = 0;
unsigned long prevBlinkTime2 = 0;

unsigned long currentMillis = millis();
if(currentMillis - previousMillis > BLINK_INTERVAL1)
{
  prevBlinkTime1 = currentMillis;
  //тут мигаем одним светодиодом
}

currentMillis = millis();
if(currentMillis - previousMillis > BLINK_INTERVAL2)
{
  prevBlinkTime2 = currentMillis;
  //тут мигаем другим светодиодом
}

 

mrbin
Offline
Зарегистрирован: 01.02.2015

Ну спасибо вам большое!

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Извеняюсь, у меня там ошибка, в 8 и 15 строках соответственно вместо previousMillis надо писать prevBlinkTime1 и prevBlinkTime2

mrbin
Offline
Зарегистрирован: 01.02.2015

Bсе получилось благодарю за подсказку

mrbin
Offline
Зарегистрирован: 01.02.2015

Еще такой вопрос у меня к вам,не могу разобратся что бы при нажатии на кнопку начанал мигать,через if вылазиют ошибки,поскажите если не трудно

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

А при отпускании или повторном нажатии ничего не должно происходить? Просто нажали и начало мигать с определенным интервалом? Если так то можно считывать кнопку и как тоьлко её нажали взвести флаг и этот флаг проверять перед тем как мигать, как то так

boolean ButtonPress = false;

pinMode("pin name", INPUT);

if ((digitalRead("pin name")==HIGH)&&(!ButtonPress))
  ButtonPress=true;

Первая строка флаг для отслеживания кнопки, вторая это в сетап настройка пина для кнопки, условие вставляете в loop вначале.

В 11 или 18 строке 6ого поста не просто мигаем светодиодом, а сначало через if проверяем надо ли моргать или нет.

if(ButtonPress)
{
  // мигаем
}

Тогда через заданный интервал сначало будет проверяться флаг ButtonPress и если он true то мигаем, если false то не мигаем.

Ну это если я правильно понял

mrbin
Offline
Зарегистрирован: 01.02.2015

Нет ни чего ,отпустил потух,благодарю за помощь

mrbin
Offline
Зарегистрирован: 01.02.2015

Не понял ,какого поста?

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

6 (шесть) пост в этой теме

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Но если надо чтобы при отпускании переставал моргать, то надо немного по другому.

if (digitalRead("pin name")==HIGH)
  ButtonPress=true;
else
  ButtonPress=false;

Тогда пока держим кнопку светодиод моргает с заданным интервалом, когда отпустили он перестал моргать.

mrbin
Offline
Зарегистрирован: 01.02.2015

Почему то он без нажатия кнопки начинает мигать

mrbin
Offline
Зарегистрирован: 01.02.2015

Разобрался))) еще вопрос можно,связанный со временем?

 

mrbin
Offline
Зарегистрирован: 01.02.2015

Подскажите пожалуйста еще один пример,кнопка включена,после включения кнопки диод загорается через 2секунды,после выключения кнопки диод гаснет не сразу а так же через две секунды

 

mrbin
Offline
Зарегистрирован: 01.02.2015

Подскажите пожалуйста еще один пример,кнопка включена,после включения кнопки диод загорается через 2секунды,после выключения кнопки диод гаснет не сразу а так же через две секунды

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

По коду так и есть. Можно сделать чтобы сразу погас. Можно вот это кусок

if (digitalRead("pin name")==HIGH)
  ButtonPress=true;
else
  ButtonPress=false;

заменить на такой

if (digitalRead("pin name")==HIGH)
  ButtonPress=true;
else
{
  ButtonPress=false;
  digitalWrite("led pin name", LOW);
}

Тогда как только отпустите кнопку светодиод сразу погаснет, не дожидаясь выполнения условия по времени.

mrbin
Offline
Зарегистрирован: 01.02.2015

Вы настоящий друг,Спасибо!

mrbin
Offline
Зарегистрирован: 01.02.2015
#define BLINK_INTERVAL1 5000
#define BLINK_INTERVAL2 3000
#define BLINK_INTERVAL3 10000
#define LED1  13
#define LED2  12
unsigned long prevBlinkTime1 = 0;// здесь храниться время последнего изменения состояния светодиода 
unsigned long prevBlinkTime2 = 0;// здесь храниться время последнего изменения состояния светодиода 
unsigned long prevBlinkTime3 = 0;// здесь будет храниться время последнего изменения состояния светодиода 
boolean DAT1Press = false;

int DAT1= A1;

void setup() 
{
  pinMode(DAT1, INPUT);
  // задаем режим выхода для порта, подключенного к светодиоду
  pinMode(LED1, OUTPUT);  // устанавливаем порт, как выход    
  pinMode(LED2, OUTPUT);  // устанавливаем порт, как выход 
}

void loop()
{
  
   if (digitalRead(DAT1)==HIGH)
    {
    DAT1Press=true;
    digitalWrite(LED2,HIGH  );
    }
    unsigned long currentMillis = millis(); 
    if(currentMillis - prevBlinkTime1  > BLINK_INTERVAL1)
    {
    prevBlinkTime1 = currentMillis;
    digitalWrite(LED2,LOW);  
    }
   
    if(currentMillis - prevBlinkTime2  > BLINK_INTERVAL2)
    {
    prevBlinkTime2 = currentMillis;
    digitalWrite(LED1,HIGH);  
    }
    if(currentMillis - prevBlinkTime3  > BLINK_INTERVAL3)
    {
    prevBlinkTime3 = currentMillis;
    digitalWrite(LED1,LOW);  
    }
}
   
  
   

 

Подскажите мне еще пожалуйста,вот код,то есть при нажатии на кнопку загорается первый светодиод на 12 порту ,при отпускании он через через 5 секунд гаснет,при длительном нажатии должен загорется 2й светодиод на 13 порту ,и при отпускании кнопки он должен светится 10 секунд и гаснуть,оно так делает,только причина в том если на кнопку не нажимать он все равно загорается и гаснет бесконечно,какое условие нужно поставить?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Что-то у Вас каша какая то получилась из кода. Всё что с 29 строчки и ниже будет выполняться на каждом цикле и без разницы нажата или отпущена кнопка. DAT1Press у Вас вообще не используется, один раз ей присваивается значение и все. Что значит длительное нажатие? Как Вы его отслеживать собрались, по времени? Длинное это 1 секунда или сколько? Сегодня уже спать пора, завтра поглядим.

mrbin
Offline
Зарегистрирован: 01.02.2015

Вообщем должно работать так,нажимаю и держу кнопку,загорелся первый светодиод,спустя пять секунд загорелся второй светодиод,отпускаю кнопку,первый гаснет спустя две секунды,второй спутя десять секунд

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Вот теперь понятно, обед будет гляну

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

На обеде времени не появилось лишнего. Дома на макетке накидал кнопку и светодиоды и получился такой код. На оптимальность не претендую, но описанные действия выполняет.

#define ButtonPin 2 // пин куда подключаем кнопку
#define LED1Pin 12  // пин с первым светодиодом
#define LED2Pin 13  // пин со вторым светодиодом

#define LED1StopDelay 2000 // задержка выключения первого светодиода

#define LED2StartDelay 5000 // задержка включения второго светодиода
#define LED2StopDelay 10000 // задержка выключения второго светодиода

unsigned long ButtonPressTime = 0; // время нажатия кнопки
unsigned long ButtonReleaseTime = 0; // время отпускания кнопки

byte ButtonFlag = 0; //флаг для типа избавления от дребезка и выполнения кода один раз

void setup()
{
  pinMode(ButtonPin, INPUT);
  pinMode(LED1Pin, OUTPUT);
  pinMode(LED2Pin, OUTPUT);
  digitalWrite(LED1Pin, LOW);
  digitalWrite(LED2Pin, LOW);
}

void loop()
{
  // если нажали кнопку и до этого она была не нажата
  if(digitalRead(ButtonPin)==HIGH&&ButtonFlag==0)
  {
    ButtonFlag = 1;
    ButtonReleaseTime = 0;
    // запоминаем время начатия
    ButtonPressTime = millis();
    // включаем первый светодиод
    digitalWrite(LED1Pin, HIGH);    
  }
  // если кнопку отпустили
  if(digitalRead(ButtonPin)==LOW&&ButtonFlag==1)
  {
    ButtonFlag = 2;
    ButtonPressTime = 0;
    // запоминаем время отпускания
    ButtonReleaseTime = millis();    
  }
  // если кнопка нажата
  if(ButtonFlag==1)
  {
    // ждём заданное время и зажигаем второй светодиод
    if(millis() - ButtonPressTime > LED2StartDelay)
      digitalWrite(LED2Pin, HIGH);
  }
  // если отпустили кнопку
  if(ButtonFlag==2)
  {
    // ждем заданное время и гасим первый светодиод
    if(millis() - ButtonReleaseTime > LED1StopDelay)
    {
      digitalWrite(LED1Pin, LOW);
      // если второй светодиод еще не успел загореться то флаг в начальное значение сбрасываем
      if(digitalRead(LED2Pin)==LOW)
      {
        ButtonReleaseTime=0;
        ButtonFlag=0;
      }
    }
    // ждем заданное время и гасим второй светодиод и сбрасываем флаги
    // типа начальное состояние готовы к новому циклы работы
    if(millis() - ButtonReleaseTime > LED2StopDelay)
    {
      digitalWrite(LED2Pin, LOW);
      ButtonReleaseTime=0;
      ButtonFlag=0;
    }
  }
}

 

mrbin
Offline
Зарегистрирован: 01.02.2015

Спасибо! терпеливый вы человек,другой бы давно послал,буду изучать,еще раз спасибо за помощь.

mrbin
Offline
Зарегистрирован: 01.02.2015

Penni здравствуйте! опять я с вопросом,подскажите как сгенерировать  36кгц на ардуино?

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Честно никогда не занимался подобным, но думаю вот тут найдете все что надо http://cxem.net/arduino/arduino62.php

Demos
Offline
Зарегистрирован: 21.02.2015

Penni, Здравствуйте! У меня в чем то похожая проблемма. Нужно включить двухканальное реле. Сначала 1 канал на 5 секунд потом оба канала на 5 секунд одновременно, потом опять только первый канал и опять оба. Включать нужно через определенный период который выбирается кнопками в меню, период устанавливается, в этом проблемм нет, проблемка в том что не могу включать второй раз одновременно - идет разброс время включения + время ожидания.

Хотел привязать скетч, найденым на этом форуме http://arduino.ru/forum/programmirovanie/kak-vklyuchit-na-nekotoroe-vremya  но как я сказал выше идет разброс, через несколько включений совпадает что включаются одновременно, а потом опять не вместе. Помогите пожалуйста или подскажите как сделать что б время ожидания совпадало.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Т.е. включается первый канал на 5ть секунд, выключается. Ждём заданный промежуток времени и включаем оба канала на 5ть секунд и так по кругу?

Demos
Offline
Зарегистрирован: 21.02.2015

Да, именно так

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Можно вот так сделать. Там уже код вставите как надо, у меня просто в лупе крутится, поэтому когда весь цикл проходит и оба канала отключаются, тут же включается первый и пошло всё снова.

#define channel1pin 12
#define channel2pin 13
#define work_interval 5000 // время работы канала
#define idle_interval 10000 // время между включениями каналов

unsigned long prevMillis = 0;
byte state = 0;

void setup()
{
  pinMode(channel1pin, OUTPUT);
  pinMode(channel2pin, OUTPUT);
}

void loop()
{
  if(!state)
    digitalWrite(channel1pin, HIGH);
  unsigned long currentMillis = millis();
  if((currentMillis - prevMillis > work_interval) && (state==0 || state==2))
  {
    prevMillis = currentMillis;
    switch(state)
    {
      case 0:        
        digitalWrite(channel1pin, LOW);
        state = 1;
        break;
      case 2:
        digitalWrite(channel1pin, LOW);
        digitalWrite(channel2pin, LOW);
        state = 0;
        break;
    }
  }
  currentMillis = millis();
  if(currentMillis - prevMillis > idle_interval && state==1)
  {
    prevMillis = currentMillis;
    digitalWrite(channel1pin, HIGH);
    digitalWrite(channel2pin, HIGH);
    state = 2;
  }
}

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Если надо чтобы после отключения двух каналов опять выдерживалась пауза заданная то можно ввести state = 3 в 37 строке добавить || state==3 в условии сделать switch(state) по case 1 выполнять те строки что есть (с 39 по 42) а по case 3 делать просто state=0;

Demos
Offline
Зарегистрирован: 21.02.2015

С первым примером включается 1 канал на 5 сек через 5 сек  включается 2 канал и оба включены 10 сек, потом оба выключаются на 5 сек

после добавления корректировок получился такой код:

#define channel1pin 12
#define channel2pin 13
#define work_interval 5000 // время работы канала
#define idle_interval 10000 // время между включениями каналов

unsigned long prevMillis = 0;
byte state = 0;

void setup()
{
  pinMode(channel1pin, OUTPUT);
  pinMode(channel2pin, OUTPUT);
  
}

void loop()
{
  if(!state)
    digitalWrite(channel1pin, LOW);
  unsigned long currentMillis = millis();
  if((currentMillis - prevMillis > work_interval) && (state==0 || state==2))
  {
    prevMillis = currentMillis;
    switch(state)
    {
      case 0:        
        digitalWrite(channel1pin, HIGH);
        state = 1;
        break;
     case 1:   
    prevMillis = currentMillis;
    digitalWrite(channel1pin, LOW);
    digitalWrite(channel2pin, LOW);
    state = 2;
      case 2:
        digitalWrite(channel1pin, HIGH);
        digitalWrite(channel2pin, HIGH);
        state = 0;
        break;
     case 3:
     state = 0;
     break;
    }
  }
  currentMillis = millis();
  if(currentMillis - prevMillis > idle_interval && state==1 || state==3)
  {
    prevMillis = currentMillis;
    digitalWrite(channel1pin, LOW);
    digitalWrite(channel2pin, LOW);
    state = 2;
  }
}

Включаются оба канала, через 5 сек второй выключается, через 5 сек выключается первый, потом 10 секунд выключены оба и заново.

Может я не так что то исправил?

Demos
Offline
Зарегистрирован: 21.02.2015

что-то вообще не то пока.

Вот написал с использованием delay - работает как надо, но смысла нет потому что там еще куча всего должно работать) может поможет

#define channel1pin 15
#define channel2pin 16
#define work_interval 1000 // время работы канала
#define idle_interval 5000 // время между включениями каналов

unsigned long prevMillis = 0;
byte state = 0;

void setup()
{
  pinMode(channel1pin, OUTPUT);
  pinMode(channel2pin, OUTPUT);
  digitalWrite(channel1pin, HIGH);
  digitalWrite(channel2pin, HIGH);  
}

void loop()
{
  digitalWrite(channel1pin, LOW);
  delay(work_interval);  
  digitalWrite(channel1pin, HIGH);
  digitalWrite(channel2pin, HIGH);
  delay(idle_interval);
  digitalWrite(channel1pin, LOW);
  digitalWrite(channel2pin, LOW);
  delay(work_interval);
  digitalWrite(channel1pin, HIGH);
  digitalWrite(channel2pin, HIGH);
  delay(idle_interval);
}

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну вот у меня лежит мега 2560 к ней светодиод вместо реле подключен и + встроенный светодиод, тот код что я кидал работает, загорается первый на 5ть секунд, гаснет на 10, загораются оба светодиода, горят пять секунд гаснут и так по кругу. Сечас еще раз скетч загружу гляну может вечером вчера мне казалось иначе..

UPD залил еще раз проверил всё работает как описано, могу видео заснять :)

Demos
Offline
Зарегистрирован: 21.02.2015

Странно, а я уже седеть начинаю)

Вот не менял пины скопировал как есть - теперь зажигается 1 канал, выключается и сразу же включается встроенный диод, горит 5 сек и выключается, оба не горят потом опять по циклу

у меня про мини если это имеет какое то значение

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну даже не знаю... у меня нет про мини чтобы попробовать не думаю что есть какая-то разница. Ну что там может быть millis чтоли по другому работает... Всё как обычно просто, надо только догадаться :)

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Единственное у вас реле включаются когда LOW а выключаются когда HIGH у меня со светодиодами соответственно наоборот. Т.е. в том коде что я давал надо HIGH на LOW поменять и LOW на HIGH, ну я думаю поменяли же. В общем надо как обычно отвлечься от проблемы и она сама решиться в голове :)

Demos
Offline
Зарегистрирован: 21.02.2015

/

mrbin
Offline
Зарегистрирован: 01.02.2015

Penni привет! у меня опять вопрос ,нет ли у вас примера бегущий строки на олед дисплеи?

 

mrbin
Offline
Зарегистрирован: 01.02.2015
void testscrolltext(void) {
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(10,0);
  display.clearDisplay();
  display.println("scroll");
  display.display();
 
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);    
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
}

вот такой пример есть но не так работает как хотелось

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Не, у меня нет, никогда с олед дело не имел, но думаю кто-то обязательно покажет. А как не так работает может этот пример можно поправить?

mrbin
Offline
Зарегистрирован: 01.02.2015

он работает так,при включении слово стоит вверху,потом начинает двигатся вправо ,влево,и после этого идет с низу вверх,также двигаясь в право и влево

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

А Вам надо чтобы только в одной строке туда сюда двигалось? По диагонали это 17 и 19 строки делают, уберите их и слово будет только в одной строке двигаться.

mrbin
Offline
Зарегистрирован: 01.02.2015

чтобы  слово прошло с право влево и конец

 

 

mrbin
Offline
Зарегистрирован: 01.02.2015

для чего нужны вот эти значения  (0x00, 0x07);

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

У меня нет библиотеки этой, но на гидхабе в описании написано, что это стартовая и конечная позиция. А какое разрешение у экрана?

mrbin
Offline
Зарегистрирован: 01.02.2015

128x64