Включение в определенной последовательности

kaar85
Offline
Зарегистрирован: 15.02.2017

Добрый вечер. Столкнулся с такой проблемой а решение найти не могу

Имеется ардуино, 4-х канальный релейный блок, два светодиода (красный и зеленый) и PIR-датчик от обычной охранной сигнализации ( в ждущем режиме работает как обычная замкнутая кнопка) 

Помогите с кодом. 

В чем задача - при первом срабатывании PIR должен загорется зеленый светодиод и гореть в течении 2-х секунд, при втором срабатывании PIR - зеленый светодиод в течении 2-х секудна затем с задержкой в 5 секунд первый канал релейного блока. При третьем срабатывании PIR - 2-ой канал релейного блока без задержки. При четвертом срабатывании PIR - красный светодиод в течении 1 секунды и с задержкой в 3 секунды 3 и 4 каналы релейного блока.

Простые скетчи наваять могу, а вот совместить это все во едино ...... ну никак =)

 

JasKo
Offline
Зарегистрирован: 21.11.2015

А что делать при пятом сработывании?

kaar85
Offline
Зарегистрирован: 15.02.2017

JasKo пишет:

А что делать при пятом сработывании?

ничего. чтобы запустить все сначало - нужно перегрузить устройство

JasKo
Offline
Зарегистрирован: 21.11.2015

Ну раз простые скетчи ваять можете покажите ваш скетч для PIR датчика.

PS: В этой ветке форума помогаут тем кто пишет сам. За других пишут в ветке "Ищу исполнителя".

kaar85
Offline
Зарегистрирован: 15.02.2017

 вданно случаи так как PIR датчик от обычнйо охранной сигнализации, то он представлен как обычная замкнутая кнопка

 
JasKo
Offline
Зарегистрирован: 21.11.2015

А теперь самое врем почитать http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

kaar85
Offline
Зарегистрирован: 15.02.2017
// задаем константы
const int buttonPin = 2;     // номер входа, подключенный к кнопке
const int ledPin =  8;      // номер выхода светодиода
const int Relay =  9;      // номер выхода реле 
// переменные
int buttonState = 0;         // переменная для хранения состояния кнопки
 
void setup() {
  // инициализируем пин, подключенный к светодиоду, как выход
  pinMode(ledPin, OUTPUT);  
   // инициализируем пин, подключенный к кнопке, как вход
  pinMode(buttonPin, INPUT);
    // инициализируем пин, подключенный к реле, как выход
  pinMode(Relay, OUTPUT);    
}
 
void loop(){
  // считываем значения с входа кнопки
  buttonState = digitalRead(buttonPin);
   // проверяем нажата ли кнопка
  // если нажата, то buttonState будет HIGH:
  if (buttonState == HIGH) {   
    // выключаем светодиод   
    digitalWrite(ledPin, LOW); 
     // выключаем реле  
    digitalWrite(Relay, LOW); 
  }
  else {
      // включаем светодиод
    digitalWrite(ledPin, HIGH); 
   // задержка 
    delay(5000);  
    // включаем реле
    digitalWrite(Relay, HIGH);
     //длительность включения реле
    delay(5000);  
  }
}

правильно вставил код

JasKo
Offline
Зарегистрирован: 21.11.2015

Теперь надо добавить подсчет срабатываний PIR.

Для этого надо добавить переменные int countButton и boolean lastButton

В первой будешь считать нажатия, во второй хранить последннее считанное значение кнопки и проверять его в строке 22.

присваивание LastButton = текущее состояние копки предлогаю добавить в 23 и 31 строке.

Задача ясна?

kaar85
Offline
Зарегистрирован: 15.02.2017

JasKo пишет:

Теперь надо добавить подсчет срабатываний PIR.

Для этого надо добавить переменные int countButton и boolean lastButton

В первой будешь считать нажатия, во второй хранить последннее считанное значение кнопки и проверять его в строке 22.

присваивание LastButton = текущее состояние копки предлогаю добавить в 23 и 31 строке.

Задача ясна?

задача ясна 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

kaar85 пишет:

Простые скетчи наваять могу, а вот совместить это все во едино ...... ну никак =)

Вот же удивительно. Что бы научить человека читать и писать на русском хватает полгода, даже если этому человеку всего 6-7 лет. Но почему, то все равно идут уроки русского языка и литературы вплодь до последнего года обучения. Вот когда вы найдете, зачем вы тратите время сидя на этих уроках, то я думаю вы поймете, что да же простые скетчи вы не умеете писать.

kaar85
Offline
Зарегистрирован: 15.02.2017

qwone пишет:

kaar85 пишет:

Простые скетчи наваять могу, а вот совместить это все во едино ...... ну никак =)

Вот же удивительно. Что бы научить человека читать и писать на русском хватает полгода, даже если этому человеку всего 6-7 лет. Но почему, то все равно идут уроки русского языка и литературы вплодь до последнего года обучения. Вот когда вы найдете, зачем вы тратите время сидя на этих уроках, то я думаю вы поймете, что да же простые скетчи вы не умеете писать.

Все с чего то начинали. Не думаю что вы сели за Пк и уже через час писали програмные коды на несколько тысяч строк. 

JasKo
Offline
Зарегистрирован: 21.11.2015

kaar85 пишет:

....

Все с чего то начинали. Не думаю что вы сели за Пк и уже через час писали програмные коды на несколько тысяч строк. 

Вы абсолютно правы.

И вы во всем разберетесь и все получится.

kaar85
Offline
Зарегистрирован: 15.02.2017
// задаем константы
const int buttonPin = 2;     // номер входа, подключенный к кнопке
const int ledPin =  8;      // номер выхода светодиода
const int Relay1 =  9;      // номер выхода #1 реле 
const int Relay2 =  10;      // номер выхода #2 реле 
const int Relay3 =  11;      // номер выхода #3 реле 
const int Relay4 =  12;      // номер выхода #4 реле 
// переменные
int buttonState = 0;         // переменная для хранения состояния кнопки
int countButton = 1;      // начальное значение нажатия кнопки
boolean lastButton = true;   // начальное значение 
 
void setup() {
  // инициализируем пин, подключенный к светодиоду, как выход
  pinMode(ledPin, OUTPUT);  
   // инициализируем пин, подключенный к кнопке, как вход
  pinMode(buttonPin, INPUT);
    // инициализируем пин, подключенный к реле, как выход
  pinMode(Relay1, OUTPUT);    
  // инициализируем пин, подключенный к реле, как выход
  pinMode(Relay2, OUTPUT); 
  // инициализируем пин, подключенный к реле, как выход
  pinMode(Relay3, OUTPUT); 
  // инициализируем пин, подключенный к реле, как выход
  pinMode(Relay4, OUTPUT); 
}
 
void loop(){
  // считываем значения с входа кнопки
  buttonState = digitalRead(buttonPin);
   // проверяем нажата ли кнопка
  // если нажата, то buttonState будет HIGH:
  if (buttonState == HIGH)  { 
  boolean lastbutton = false;
  countButton = lastButton; //текущее значение срабатывания
      // выключаем светодиод 
    digitalWrite(ledPin, LOW); 
     // выключаем реле  
    digitalWrite(Relay, LOW); 
  }
  else {
      // включаем светодиод
    digitalWrite(ledPin, HIGH); 
    countButton +=1; // увеличилось значение на 1
   // задержка перед включением реле
    delay(5000);  
    // включаем реле
    digitalWrite(Relay, HIGH);
     //длительность включения реле
    delay(5000);  
  }
}

Предчувствую что бред написал, но все же

А для чего вводить boolean? почему нельзя с каждым циклом увеличивать значение countButton и в зависимости от него выполнять нужный алгоритм?

Logik
Offline
Зарегистрирован: 05.08.2014

///Все с чего то начинали.

Так тогда уже начинайте с правильного подхода. https://habrahabr.ru/post/160105/ читать до примера, понять почему флаги-плохо, думать где и какие состояния у Вас, рисовать диаграмму аналогичную приведеной.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

 Вот еще delay(5000);   это не пауза в 5 секунд. А 5 секунд Ардуина ничего не видит, ничего не слышит, и главное ничего не делает. Если Ардуина предназначена только 1 светодиодом, то может прокатить. Но только чуточку больше уже все. Началась полная жопа, потому что 

delay(5000);   это не пауза в 5 секунд. А 5 секунд Ардуина ничего не видит, ничего не слышит, и главное ничего не делает. 

 

Logik
Offline
Зарегистрирован: 05.08.2014

///Если Ардуина предназначена только 1 светодиодом, то может прокатить. Но только чуточку больше уже все. 

Угу. Потому лучше к этому не привыкать изначально. Потом всеравно перучиватся прийдется.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Иногда мне кажется, что Дуина это кидалово. Поманить их красивыми пустыми возможностями и завести их в тупик. Это как научить новичков писать свое имя и предложить им подписать отказ от своего имущества.

kaar85
Offline
Зарегистрирован: 15.02.2017

Logik пишет:

///Если Ардуина предназначена только 1 светодиодом, то может прокатить. Но только чуточку больше уже все. 

Угу. Потому лучше к этому не привыкать изначально. Потом всеравно перучиватся прийдется.

Ну так вся информация в сети построена на "delay". Я уже заметил что в течении этих 5 секунд ничего не происходит. тогда как по другому задать задержку между моментом когда диод горит и срабатыванием реле?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

kaar85 пишет:

Ну так вся информация в сети построена на "delay". Я уже заметил что в течении этих 5 секунд ничего не происходит. тогда как по другому задать задержку между моментом когда диод горит и срабатыванием реле?

Ну не вся . Обычно новички millis() упор не замечают.

/* millis_1btn_1TimeRelay.ino
  //#1 реле
  реле 1  -> 12(relay1_pin) 1 включено / 0 выключено
  //#2 кнопка
  кнопка  -> 10 (btn1_pin) 0  нажата / 1 нет
  Принцип кода: реле работает только 3 секунды после нажатия
*/
//#1 реле
const int relay1_pin = 12;// нога реле
bool relay1;// состояние реле
const uint32_t TimeOFF = 3 * 1000; // время отключения
//#2 кнопка
const int btn1_pin = 10;
bool btn1, btn1_old; //нажатие кнопки
bool bounce_btn1 = 0; // антидребезговый флаг
void setup() {
  //#1 реле
  pinMode(relay1_pin, OUTPUT); // подключить реле
  digitalWrite(relay1_pin, relay1 = 0); // и выключить
  //#2 кнопка
  pinMode(btn1_pin, INPUT_PULLUP);
  btn1 = digitalRead(btn1_pin);
}
void loop() {
  //#1 реле
  static uint32_t past_1 = 0 ;
  if (relay1 && millis() - past_1 >= TimeOFF ) // если реле вкл и подошло время выключить
    digitalWrite(relay1_pin, relay1 = 0); // то его выключить

  //#2 кнопка использует дебонс
  static uint32_t past_2 = 0 ;
  if (! bounce_btn1 && btn1 != digitalRead(btn1_pin)) { // если прошел фронт изм на выводн
    bounce_btn1 = 1;                                 // выставить флаг
    past_2 = millis();                          // сделать временую отметку
  }
  else if ( bounce_btn1 && millis() - past_2 >= 5 ) { // если прошло антидребезговое время 5 ms
    bounce_btn1 = 0;      // то снять флаг
    btn1_old = btn1;
    btn1 = digitalRead(btn1_pin) ; // прочитать реальное значение на выводе
    if (btn1_old && ! btn1 && ! relay1) {      // если обнаружилось что это было нажатие и реле не вкл
      past_1 = millis(); // выставить отметку
      digitalWrite(relay1_pin, relay1 = 1); // и включить реле
    }
  }
}

 

Logik
Offline
Зарегистрирован: 05.08.2014

kaar85 пишет:

Ну так вся информация в сети построена на "delay".

Делей забыть, сеть сменить ;) delay - сильно лоховский подход о чем qwone по философски намекнул выше. Да, если чел совсем нулевый - ну чего делать?! Пусть хоть с delay пишет. Но если Вы сами уже замечаете проблему - так таки пора забыть делей. Вон, в соседней теме туда посылают - http://alxarduino.blogspot.ru/2013/09/BlinkAndPrintWithoutDelay.html

kaar85
Offline
Зарегистрирован: 15.02.2017
int ButPin = 7; // Подключаем кнопку к выходу 7
int Relay_1 = 8; // Подключаем 1 канал
int Relay_2 = 9; // Подключаем 2 канал
int Relay_3 = 10; // Подключаем 3 канал
int Relay_4 = 11; // Подключаем 4 канал
int LedPin = 12; // Подключаем диод
int flag = 0; // флаг состояния
int regim = 0; // Переключалка

void setup()
{
pinMode(Relay_1, OUTPUT); 
pinMode(Relay_2, OUTPUT);
pinMode(Relay_3, OUTPUT);
pinMode(Relay_4, OUTPUT);
pinMode(ButPin, INPUT);
pinMode(LedPin, OUTPUT);

}

void loop()
{
if(digitalRead(ButPin) == LOW && flag == 0)
  { 
regim ++;
flag = 1;

if(regim > 3) // Если номер режима превышает требуемого
{ 
regim = 0; // то отсчет начинается с нуля
{
 if(digitalRead(7)==HIGH)//если кнопка нажата ...
 {
 digitalWrite(12,LOW);//выключаем светодиод
 }
 else//если не нажата...
 {
 digitalWrite(12,HIGH);//включаем
 }
 }
}
}

if(digitalRead(ButPin) == HIGH && flag == 1)
{
flag = 0;
}

// ======= Вполняем задачу при выборе режима =======
// РЕЖИМ 0: OFF
if(regim == 0)
{
digitalWrite(Relay_1, HIGH);
digitalWrite(Relay_2, HIGH);
digitalWrite(Relay_3, HIGH);
digitalWrite(Relay_4, HIGH);
digitalWrite(LedPin, LOW);
}

// РЕЖИМ 1: 1 канал
if(regim == 1)
{
digitalWrite(LedPin, HIGH);
delay (2000);
digitalWrite(Relay_1, LOW);
digitalWrite(Relay_2, HIGH);
digitalWrite(Relay_3, HIGH);
digitalWrite(Relay_4, HIGH);
}

// РЕЖИМ 2: 2 канал
if(regim == 2)
{
digitalWrite(LedPin, HIGH);
delay (2000);  
digitalWrite(Relay_1, LOW);
digitalWrite(Relay_2, LOW);
digitalWrite(Relay_3, HIGH);
digitalWrite(Relay_4, HIGH);
}

// РЕЖИМ 3: 3 и 4 каналы
if(regim == 3)
{
digitalWrite(LedPin, HIGH);
delay (2000);  
digitalWrite(Relay_1, LOW);
digitalWrite(Relay_2, LOW);
digitalWrite(Relay_3, LOW);
digitalWrite(Relay_4, LOW);
}
}

от Delay все равно не смог отказаться =) с Режимами работы реле согласно задачи разобрался, но возникла другая ошибка - диод горит только после первого срабатывания кнопки. во всех остальных случаях - нет. где искать ошибку?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

kaar85, Ваша ошибка в выборе набора состояний. Их у Вас гораздо больше пяти:

1. Первое срабатывание датчика.

2. Первые две секунды после второго срабатывания датчика.

3. Последующие секунды после второго срабатывания датчика.

4. Первые две секунды после третьего срабатывания датчика.

5. Последующие секунды после третьего срабатывания датчика.

6. Первые две секунды после четвертого срабатывания датчика.

7. Последующие секунды после четвертого срабатывания датчика.

При этом переходы 2-3, 4-5 и 6-7 происходят не по датчику, а по времени. А если датчик сработал ранее 2 секунд, состояния перепрыгивают через одно.

 

 

kaar85
Offline
Зарегистрирован: 15.02.2017

andriano пишет:

kaar85, Ваша ошибка в выборе набора состояний. Их у Вас гораздо больше пяти:

1. Первое срабатывание датчика.

2. Первые две секунды после второго срабатывания датчика.

3. Последующие секунды после второго срабатывания датчика.

4. Первые две секунды после третьего срабатывания датчика.

5. Последующие секунды после третьего срабатывания датчика.

6. Первые две секунды после четвертого срабатывания датчика.

7. Последующие секунды после четвертого срабатывания датчика.

При этом переходы 2-3, 4-5 и 6-7 происходят не по датчику, а по времени. А если датчик сработал ранее 2 секунд, состояния перепрыгивают через одно.

В принципе понял о чем речь, но не понимаю как исправить. Дайте направление или подскажите как

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

1. Увеличить количесво режимов.

2. Предусмотреть переход из режима в режим не только по кнопке, но и по времени.