Przerwania, z opóźnieniem jak ogarnąć

alankedzior
Posts: 114
Joined: Mon Jun 18, 2018 5:38 pm

Post

Problem polega na zbudowaniu alarmu, posiadam prosty krótki program bez obsługi supli oddzielne arduino mega , który działa na zasadzie:

Gdy alarm nie jest uzbrojony załączać będzie mi klika STREF oświetlenia z różnych czujników PIR, program testuje narazie na jednym czujniku i jednym wyjściu na Strefę Oświetleniową, gdy ogarnę owy problem rozbuduję go o kolejne czujniki i strefy. Alarm uzbrajam dotychczas w ramach testu przyciskiem, po uzbrojeniu alarm przechodzi po zadanym czasie w STAN UZBROJONY i czeka na wykrycie intruza, wszystko działa gdy Intruz zostaje wykryty alarm załącza się natychmiastowo, lecz ja potrzebuję opóźnić jeszcze jedną strefę o jakiś czas chodzi mi o możliwość późniejszczego wyłączenia alarmu za pomocą RFID i nie chcę, żeby automatycznie załączało mi alarm tylko dało mi chwilę na dołożenie breloka do czytnika. Czas na opuszczenie budynku działa.

Code: Select all

 

#define PRZYCISK 21
#define SWIATLO 29
#define ALARM 34
#define PIR 22
#define LED 13
#define CZAS_WYJSCIA 15000


boolean uzbrojony = false;
unsigned long przycisk_czas, uzbrojenie_czas;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(SWIATLO, OUTPUT);
  digitalWrite(SWIATLO, LOW);
  pinMode(ALARM, OUTPUT);
  digitalWrite(ALARM, LOW);
  pinMode(PIR, INPUT);
  pinMode(PRZYCISK, INPUT_PULLUP);


}
void zmiana()
{
  digitalWrite(ALARM, LOW);
  uzbrojenie_czas = millis() + CZAS_WYJSCIA;
  przycisk_czas = millis() +50;
  uzbrojony = !uzbrojony;
  detachInterrupt(digitalPinToInterrupt(PRZYCISK));
}

void loop() {
  digitalWrite(LED, uzbrojony);

  if (przycisk_czas < millis())
    attachInterrupt(digitalPinToInterrupt(PRZYCISK), zmiana, FALLING);

  if (digitalRead(PIR))
  
  {
    if (uzbrojony && uzbrojenie_czas < millis())
      digitalWrite(ALARM, HIGH);
    digitalWrite(SWIATLO, HIGH);
  }
  else
    digitalWrite(SWIATLO, LOW);


    
}


Jak opóźnić zadziałanie syreny po wykryciu ruchu, gdy używam przerwań
User avatar
pzygmunt
Posts: 20302
Joined: Tue Jan 19, 2016 9:26 am
Location: Paczków
Been thanked: 59 times

Post

Dodaj sobie dodatkową zmienną czasową w której określasz moment zadziałania. W lopie sprawdzasz:

Code: Select all

if ( zmienna != 0 && zmienna <= millis() ) {
  zmienna = 0;
  // ..... zrób coś
}
następnie w innym miejscu jak wystąpi jakieś zdarzenie to tylko ustawiasz

Code: Select all

zmienna = millis() + opoznienie;
SUPLA.... Nareszcie w domu.
alankedzior
Posts: 114
Joined: Mon Jun 18, 2018 5:38 pm

Post

Nie ogarniam, nie wiem czy nie zacząć tego jakoś od nowa.
alankedzior
Posts: 114
Joined: Mon Jun 18, 2018 5:38 pm

Post

Jest ktoś mi to w stanie napisać bo mecze się już tydzień, użyłem timera ale blokuje mi wyłączenie alarmu nie wiem jak to zrobić, używałem też zmiennej która sprawdzała czy czas po delay
100 jest 50 razy większy np. Czyli 5 sekund ale też nic, może być całkiem inny kod, chodzi o Alarm który uzbrajam i rozbrajam przycisku, czujnik pir i przekaznik na syrene pottzenuj czas na wyjście z budynku i czas na wejście i rozbrojenie alarmu
User avatar
pzygmunt
Posts: 20302
Joined: Tue Jan 19, 2016 9:26 am
Location: Paczków
Been thanked: 59 times

Post

Wrzuć kod to zerknę gdzie popełniasz błąd.
SUPLA.... Nareszcie w domu.
alankedzior
Posts: 114
Joined: Mon Jun 18, 2018 5:38 pm

Post

Code: Select all

 

#include <Timers.h>     // biblioteka timers
#define PRZYCISK 21 // przycisk 
#define SWIATLO 28  // sekcja 1 oswietlenia   
#define ALARM 34    // syrena alarmowa
#define PIR 24      // czujnik ruchu 1
#define LED 13      // kontrola uzbrojenia alarmu
#define CZAS_WYJSCIA 5000      //  czas na opuszczenie budynku 

Timer czaswejscia;             //  czas na zwłokę po wykryciu ruchu

bool isTimeEnd = czaswejscia.available();     // available zwraca wartość true jeśli upłynął już czas, lub false jeśli nie upłynął.


boolean uzbrojony = false;                         // zmienna uzbrojenia alarmu
unsigned long przycisk_czas, uzbrojenie_czas;      // definicja czasu przycisku oraz opóźenie (czas wyjścia)

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(SWIATLO, OUTPUT);
  digitalWrite(SWIATLO, HIGH);
  pinMode(ALARM, OUTPUT);
  digitalWrite(ALARM, HIGH);
  pinMode(PIR, INPUT);
  pinMode(PRZYCISK, INPUT_PULLUP);
}

void zmiana()
{
  digitalWrite(ALARM, HIGH);
  uzbrojenie_czas = millis() + CZAS_WYJSCIA;     // opoznienie czas wyjścia
  przycisk_czas = millis() + 55;                 // definiowanie przycisku  
  uzbrojony = !uzbrojony;                        // kontrola alarmu
  detachInterrupt(digitalPinToInterrupt(PRZYCISK));            // przerwanie (ON/OFF alarm)
}

void loop() {
  digitalWrite(LED, uzbrojony);                       // jezeli alarm uzbrojony zapal diode

  if (przycisk_czas < millis())                                                       // przycisk zmienia stan alarmu (ON/OFF)
    attachInterrupt(digitalPinToInterrupt(PRZYCISK), zmiana, FALLING);

  if (digitalRead(PIR))
  digitalWrite(SWIATLO, HIGH);                    // zapalanie światła
  else
  digitalWrite(SWIATLO, LOW);
  
  {
    if (digitalRead(PIR) == HIGH && uzbrojony && uzbrojenie_czas < millis())     // jezeli alarm jest uzbrojony, czujnik wyrkył ruch, daj opoznienie na czas wyjscia w tym czasie nie załączam alarmu
    
 czaswejscia.time(SECS(6));        // gdy minał czas wyjscia, a ruch zostal wykryty licz 6 seknud na rozbrojenie alarmu

if (czaswejscia.available())     //  jezeli 6 sekund mineło
    {
    digitalWrite(ALARM, LOW);   // URUCHUM ALARM
   }
  
  else                         //  jeezeli nie 

digitalWrite(ALARM, HIGH);     // nie uruchamiaj alarmu

czaswejscia.restart();           // czekaj na ruch i ilicz od nowa
  }}

User avatar
pzygmunt
Posts: 20302
Joined: Tue Jan 19, 2016 9:26 am
Location: Paczków
Been thanked: 59 times

Post

Jak chcesz używać tego z Suplą to nie używaj timerów.
Nie chciało mi się tego poprawiać.
Poniżej moja przeróbka pisana na "kolanie".
Nie sprawdzałem czy działa.
Musisz się zastanowić co w przypadku gdy Arduino się restartnie. Twój koncept rozbraja alarm.
Zrobiłem analogicznie jak masz.
Masz tam też możliwość anulowania uzbrajania jeżeli naciśniesz ponownie przycisk zanim alarm się uzbroi.

[EDIT] poprawka

Code: Select all

#define PIN_BUTTON 21
#define PIN_LIGHT 28  
#define PIN_ALARM 34  
#define PIN_PIR 24    
#define PIN_LED 13            
#define ARM_DELAY 5000      

unsigned long arm_disarm_counter = 0;
bool waiting_for_arm = false;

unsigned long btn_next_check = 0;
char btn_pressed = false;

bool isArmed() {
  return digitalRead(PIN_LED) == HIGH;
}

void armTheAlarm(bool arm) {
  digitalWrite(PIN_LED, arm ? HIGH : LOW);
}

bool isBtnPressed() {
  return digitalRead(PIN_BUTTON) == LOW;
}

bool motionDetected() {
   return digitalRead(PIN_PIR) == HIGH;
}

void setup() {
  pinMode(PIN_LED, OUTPUT);
  pinMode(PIN_LIGHT, OUTPUT);
  digitalWrite(PIN_LIGHT, HIGH);
  pinMode(PIN_ALARM, OUTPUT);
  digitalWrite(PIN_ALARM, HIGH);
  pinMode(PIN_PIR, INPUT);
  pinMode(PIN_BUTTON, INPUT_PULLUP);

  btn_pressed = isBtnPressed();
}

void loop() {

  unsigned long now = millis();
  
  digitalWrite(PIN_LED, isArmed() ? HIGH : LOW); 
  digitalWrite(PIN_LIGHT, motionDetected() ? HIGH : LOW);
  digitalWrite(PIN_ALARM, motionDetected() && isArmed() ? LOW : HIGH);
  
  if (now > btn_next_check 
      && btn_pressed != isBtnPressed()) {

      btn_pressed = isBtnPressed();
      btn_next_check = now + 50;
      
      if (btn_pressed) {
            waiting_for_arm = !waiting_for_arm && !isArmed();
            arm_disarm_counter = now + ( waiting_for_arm ? ARM_DELAY : 0 );  
      }
  }

  if (arm_disarm_counter != 0 
      && arm_disarm_counter <=now ) {
        
    arm_disarm_counter = 0;
    armTheAlarm(waiting_for_arm);
    waiting_for_arm = false;
  }

}
SUPLA.... Nareszcie w domu.
alankedzior
Posts: 114
Joined: Mon Jun 18, 2018 5:38 pm

Post

Jeszcze nie sprawdzałem, ale jesteś wielki. Nie będe tego używać razem z supla na alarm i rzeczy nie związane z supla poświęce inne arduino. Wydaje mi się że tak będzie lepiej. Na pytanie odnośnie restartu arduino myślę dodać moduł GSM który wyślę SMS jeśli arduino się rozbroi
alankedzior
Posts: 114
Joined: Mon Jun 18, 2018 5:38 pm

Post

Ogólnie to jeszcze coś jest nie tak, albo źle sie zrozumieliśmy. Kontrolka LED ma mnie ifnormować czy uzbroiłem ALARM. Samo wykrycie ruchu powoduje zapalanie lamp. Wciśniecie przycisku powoduje uzbrajanie i rozbrajanie alarmu.
Jeżeli wcisnę przycisk automatycznie zapala się dioda informując mnie o tym, że alarm jest uzbrojony od czasu zapalenia diody ma odliczyć czas wyjścia i przejść w czas czuwania, jeżelii w czasie czuwania wykryje ruch czeka określony czas i jeźeli nie zdąże rozbroić włącza alarm aż do momentu gdy nie rozbroję (Podtrzymanie), pozostałe czujniki mogą załączać alarm odrazu. Obecnie nie działa kontrola odrazu po uzbrojeniu, podtrzymanie syreny oraz czas na rozbrojenie alarmu.

w sumie dla mnie najgorsze ogarnac własnie jak mam czekać w czuwaniu na rozbrojenie alarmu, to co ty napisałeś to dla mnie czarna magia, gdzie się tego nauczyłeś :) podziwiam takich ludzi jak Ty.
User avatar
pzygmunt
Posts: 20302
Joined: Tue Jan 19, 2016 9:26 am
Location: Paczków
Been thanked: 59 times

Post

Jutro Ci to poprawię. Dzisiaj już jestem poza kompem.
SUPLA.... Nareszcie w domu.

Return to “Pomoc”