Skocz do zawartości

Kurs Arduino II - #5 - klawiatura, własny system alarmowy


Pomocna odpowiedź

Cześć. Zauważyłem, że buzzer jeżeli ma po sobie instrukcje delay to wydaje inny dźwięk niż gdy pracuje w czasie normalnego obiegu pętli. Dość dobrze to widać gdy zada mu się określony czas pracy i da delaya np. mniejszego o połowę. Wtedy przez połowę czasu brzmi normalnie a przez drugą połowę trochę bardziej trzeszczy. Czy to jest normalne? A może ja coś źle robię?

tone(Buzzer, 700, 4000);
delay(2000);

Problem nie powtarza się na krótszych programach niż ta centralka.

@Rogal tak, takie zachowanie może występować. W przypadku korzystania z funkcji tone/notone idealnie byłoby darować sobie korzystania z opóźnień (generowany za pomocą delay). Lepiej sprawdzą się opóźnienia bazujące na funkcji millis (więcej w dalszej części kursu). Możesz też wstawić cały program to sprawdzimy temat dokładniej. Załóż wtedy osobny temat i opisz swój problem 😉

  • Pomogłeś! 1
  • 1 miesiąc później...
#include <Arduino.h>
#include <Keypad.h> //biblioteka klawiatury
#include <Adafruit_NeoPixel.h> //biblioteka linijki LED

#define BUZZER 11
#define KONTRAKTRON 12
#define PIR 1

#define RESET 2   //DODATKOWE, zdefiniowanie klawisza resetu

void wylaczDiody();
void alarmSTOP();

bool zgasDiody = false;   //DODATKOWE, zdefiniowanie gaszenia diod po resecie

const byte ROWS = 4; //ile wierszy klawiatury
const byte COLS = 4; //ile kolumn w klawiaturze

byte rowPins[ROWS] = {6, 5, 4, 3};  //piny wierszy
byte colPins[COLS] = {7, 8, 9, 10};  //piny kolumn

char keys[ROWS][COLS] = { //mapowanie klawiatury
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

Keypad klawiatura = Keypad (makeKeymap(keys), rowPins, colPins, ROWS, COLS); // inicjalizacja klawiatury
Adafruit_NeoPixel linijka = Adafruit_NeoPixel(8, A0, NEO_GRB + NEO_KHZ800); //konfiguracja linijki LED

volatile int stanAlarmu = 1;
int pinAlarmuPozycja = 1;
char pinCyfra1 = '1';
char pinCyfra2 = '2';
char pinCyfra3 = '3';
char pinCyfra4 = '4';

int ileCzasuMinelo = 0;

void setup() {
  pinMode(BUZZER, OUTPUT);
  pinMode(KONTRAKTRON, INPUT_PULLUP);
  pinMode(PIR, INPUT_PULLUP);
  pinMode(RESET, INPUT_PULLUP);

  linijka.begin(); //inicjalizacja linijki
  linijka.show();

  attachInterrupt(digitalPinToInterrupt(RESET), alarmSTOP, FALLING);  // DODATKOWE, przerwanie reagujące na zbocze opadające
}

void loop() {
  
  char klawisz = 0; //zmienna do przetrzymywania znaków z klawiatury
  int i = 0;  //zmienna pomocnicza do pętli
  
  switch (stanAlarmu)  {//Wykonywanie akcji odpowiedniej dla danego stanu
  case 1:
    // Czuwanie
    if(zgasDiody == true){
        delay(500);
        for (i = 0; i < 8; i++){
        linijka.setPixelColor(i, linijka.Color(0,0,0));
         }
        linijka.show();
        noTone(BUZZER);
        zgasDiody = false;
        }

      linijka.setPixelColor(0, linijka.Color(0, 15, 0)); //Dioda nr 1 świeci na zielono
      linijka.show();

      klawisz = klawiatura.getKey();
      if (klawisz == 'A'){  //Czy uzbroić alarm?
        for(i = 1; i < 8; i++){
          linijka.setPixelColor(i, linijka.Color(0, 0, 15));  //Dioda nr i świeci na niebiesko
          linijka.show();
          tone(BUZZER,2500);  //DODATKOWE, dźwięk podczas uzbrajania
          delay(100);         //DODATKOWE, dźwięk podczas uzbrajania
          noTone(BUZZER);     //DODATKOWE, dźwięk podczas uzbrajania
          delay(210);
        } // wykonanie tej pętli zajmuje około 5 sekund -> nie prawda już teraz

        for(i = 1; i < 8; i++){
          linijka.setPixelColor(i, linijka.Color(15, 0, 0));  //Dioda i świeci na czerwono
          linijka.show();
          tone(BUZZER,2500);  //DODATKOWE, dźwięk podczas uzbrajania
          delay(100);         //DODATKOWE, dźwięk podczas uzbrajania
          noTone(BUZZER);     //DODATKOWE, dźwięk podczas uzbrajania
          delay(210);
        } // wykonanie tej pętli zajmuje około 5 sekund -> nie prawda już teraz

        wylaczDiody();
        stanAlarmu = 2;
      }
  break;
    
  case 2:
    //Monitorowanie
    linijka.setPixelColor(7, linijka.Color(15, 0, 0)); //Dioda nr 8 świeci na czerwono
    linijka.show();
    delay(50);
    linijka.setPixelColor(7, linijka.Color(0, 0, 0));  //Dioda nr 8 wyłączona
    linijka.show();
    delay(50);

    if(digitalRead(PIR) == HIGH){
        stanAlarmu = 4; //Natychmiast uruchamiany alarm
    }else if(digitalRead(KONTRAKTRON) == HIGH){
        ileCzasuMinelo = 0; //Zerowanie zmiennej
        stanAlarmu = 3; //Szansa na rozbrojenie
        pinAlarmuPozycja = 1;   //WAŻNA sprawa, żeby działało za każdym razem
      }
  break;
  
  case 3:
    //Rozbrajanie
    klawisz = klawiatura.getKey();
    if(klawisz){
      //Czy kolejna podana cyfra jest poprawna?
      if(pinAlarmuPozycja == 1 && klawisz == pinCyfra1){  //Jesli sprawdzamy 1 pozycje PINu
        tone(BUZZER, 6000);   //DODATKOWE, dźwięk podczas rozbrajania
        delay(100);           //DODATKOWE, dźwięk podczas rozbrajania
        noTone(BUZZER);       //DODATKOWE, dźwięk podczas rozbrajania
        pinAlarmuPozycja++; //Cyfra poprawna, można sprawdzić kolejną
      } else if (pinAlarmuPozycja == 2 && klawisz == pinCyfra2) { //Jeśli sprawdzamy 2 pozycje PINu
        tone(BUZZER, 6000);     //DODATKOWE, dźwięk podczas rozbrajania
        delay(100);             //DODATKOWE, dźwięk podczas rozbrajania
        noTone(BUZZER);         //DODATKOWE, dźwięk podczas rozbrajania
        pinAlarmuPozycja++; //Cyfra poprawna, można sprawdzić kolejną
      } else if (pinAlarmuPozycja == 3 && klawisz == pinCyfra3){ //Jeśli sprawdzamy 3 pozycje PINu
        tone(BUZZER, 6000);       //DODATKOWE, dźwięk podczas rozbrajania
        delay(100);               //DODATKOWE, dźwięk podczas rozbrajania
        noTone(BUZZER);           //DODATKOWE, dźwięk podczas rozbrajania
        pinAlarmuPozycja++; //Cyfra poprawna, można sprawdzić kolejną
      } else if (pinAlarmuPozycja == 4 && klawisz == pinCyfra4){  //Jeśli sprawdzamy 4 pozycję PINu
        tone(BUZZER, 6000);         //DODATKOWE, dźwięk podczas rozbrajania
        delay(100);                 //DODATKOWE, dźwięk podczas rozbrajania
        stanAlarmu = 1; //Wszystkie 4 cyfry kodu są poprawne
        tone(BUZZER, 5500);         //DODATKOWE, dźwięk podczas rozbrajania
        delay(100);                 //DODATKOWE, dźwięk podczas rozbrajania
        tone(BUZZER, 7000);         //DODATKOWE, dźwięk podczas rozbrajania
        delay(100);                 //DODATKOWE, dźwięk podczas rozbrajania
        noTone(BUZZER);             //DODATKOWE, dźwięk podczas rozbrajania
      } else {
        stanAlarmu = 4; //Błąd w kodzie PIN - włącz alarm
      }
    }

    delay(100);
    ileCzasuMinelo++;

    if(ileCzasuMinelo >= 50){
      stanAlarmu = 4;
    }
  break;
    
  case 4:
    //Sygnalizacja alarmu
    for(i = 0; i < 8; i++){
      linijka.setPixelColor(i, linijka.Color(255, 0, 0)); //Dioda nr i świeci na czerwono
    }
    linijka.show();
    tone(BUZZER, 4300);
    delay(100);

    for(i = 0; i < 8; i++){
      linijka.setPixelColor(i, linijka.Color(0, 0, 255)); //Dioda i świeci na niebiesko
    }
    linijka.show();
    tone(BUZZER, 3500);
    delay(100);
  break;
  }
}

void wylaczDiody(){
  int i = 0;
  for (i = 0; i < 8; i++){
    linijka.setPixelColor(i, linijka.Color(0, 0, 0)); //Dioda nr i wyłączona
  }
  linijka.show();
}

void alarmSTOP(){                                           //DODATKOWE, sekwencja resetowania alarmu zaimplementowana na przerwaniu
  int i = 0;
  for (i = 0; i < 8; i++){
  linijka.setPixelColor(i, linijka.Color(100, 100, 0));
  }
  linijka.show();
  zgasDiody = true;
  noTone(BUZZER);
  stanAlarmu = 1;
}

Przedstawiam moje rozwiązanie dla zadań dodatkowych, działa prawidłowo i za każdym razem. Największy problem miałem z rozbrajaniem po drugim uruchomieniu alarmu, ale się udało załatwić jedną linią kodu. Pozdrawiam.

  • Lubię! 1
  • 2 miesiące później...

Taka uwaga z innego forum, ale chyba warta poprawienia - zmienna pinAlarmuPozycja nie jest resetowana do początkowej wartości, więc po wpisaniu poprawnego hasła, przy kolejnych próbach wystarczy wpisać tylko koniec pinu. Wypadałoby to poprawić i dodać pinAlarmuPozycja=1 w odpowiednich miejscach, żeby nikt nie pisał o błędach w kursach Forbot-a 😉

  • Lubię! 1

@Elvis dzięki za sygnał! Zaktualizowałem dodając linijki w odpowiednim miejscu, później sprawdzę dla pewności układ w praktyce 😉

  • 3 tygodnie później...

W przypadku gdy mamy stanAlarmu=4 (czyli alarmowanie) pętla loop cały czas wybiera case:4...

Czy ktoś mógłby wyjaśnić w jaki sposób zatem dochodzi do przechwycenia naciśnięcia klawisza skoro w kodzie case:4 nie ma nigdzie klawiatura.getKey();?

@altano witam na forum 🙂 Zgodnie ze schematem blokowym działania tego układu, w tej sytuacji nie przechwytujemy już klawiatury. Alarm po włączeniu cały czas jest już włączony 🙂

  • 1 miesiąc później...

Cześć, 

W ramach tej części kursu zaimplementowałem sobie mały alarm w szafce w biurku. Do układu wmontowany jest też czujnik PIR, jest też wpisany dla niego kod, lecz w tym przypadku nie jest on wykorzystywany. Taka specyfika szafki, że zanim wykryje ruch, wykryje otwarcie. Ale w kodzie sobie to zostawiłem bo chciałem, żeby układ był bardziej uniwersalny. 

tutaj kod:

#define BUZZER 11
#define KONTAKTRON 10
#define PIR 1
#define listwaLED A0

#include <Keypad.h> //biblioteka klawiatury
#include <Adafruit_NeoPixel.h> //bibioteka dla listwy led

const byte ROWS = 4; //ile mamy wierszy
const byte COLS = 4; //ile mamy kolumn

byte rowPins[ROWS] = { 5, 4, 3, 2 }; //piny wierszy
byte colPins[COLS] = { 6, 7, 8, 9 }; // piny kolumn

int pinAlarmuPozycja = 1; //zmienne dla wpisywania pinu
char pinCyfra1 = '1';
char pinCyfra2 = '2';
char pinCyfra3 = '3';
char pinCyfra4 = '4';

int ileCzasuMinelo = 0; //zmienna pomocnicza do odliczania czasu

char keys[ROWS][COLS] = { //mapowanie klawiatury
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'}
};

Keypad klawiatura = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); //inicjalizacja klawiatury
Adafruit_NeoPixel listwa = Adafruit_NeoPixel(8, listwaLED, NEO_GRB + NEO_KHZ800); //konfiguracja listwy LED

volatile int stanAlarmu = 1; //zmiennna mówiąca o aktualnym stanie alarmu

void setup()
{
    pinMode(BUZZER, OUTPUT); //konfiguracja pinów
    pinMode(KONTAKTRON, INPUT_PULLUP);
    pinMode(PIR, INPUT_PULLUP);

    listwa.begin();
    listwa.show();

}

void loop()
{

    char klawisz = 0; //zmienna do przetrzymania znakow z klawiatury
    int i = 0; //zmienna pocnicza dla pętli

    switch (stanAlarmu)
    { //wykonywanie akcji odpowiedniej dla stanu alarmu
        case 1:
            //czuwanie
            listwa.clear();
            listwa.setPixelColor(0, listwa.Color(0, 15, 0)); //dioda numer 1 świeci na zielono
            listwa.show();

            klawisz = klawiatura.getKey();
            if (klawisz == 'A')
            { //czy uzbroić alarm?
                for (i = 1; i < 8; i++)
                {
                    listwa.setPixelColor(i, listwa.Color(0, 0, 15)); //dioda i świeci na niebiesko
                    listwa.show();
                    BuzzerPikniecie();
                    delay(710);
                }

                for (i = 1; i < 8; i++)
                {
                    listwa.setPixelColor(i, listwa.Color(15, 0, 0)); //dioda i świeci na czerwono
                    listwa.show();
                    BuzzerPikniecie();
                    delay(710);
                }

                BuzzerPikniecie();
                BuzzerPikniecie();

                wylaczDiody(); //wylaczenie wszystkich diod
                stanAlarmu = 2; //zmiana stanu alarmu
            }

            break;

        case 2:
            //monitorowanie

            listwa.setPixelColor(7, listwa.Color(15, 0, 0)); //dioda numer 8 miga na czerwono
            listwa.show();
            delay(50);
            listwa.setPixelColor(7, listwa.Color(0, 0, 0));
            listwa.show();
            delay(50);


            if (digitalRead(PIR) == HIGH)
            {
                stanAlarmu = 4; //natymiastowe wlaczenie alarmu
            }
            else if (digitalRead(KONTAKTRON) == HIGH)
            { //szansa na rozbrojenie
                ileCzasuMinelo = 0; //zerownie zmiennej
                stanAlarmu = 3;
            }


            break;

        case 3:
            //Rozbrajanie
            klawisz = klawiatura.getKey();
            if (klawisz)
            {
                //Czy kolejna podana cyfra jest poprawna?
                if (pinAlarmuPozycja == 1 && klawisz == pinCyfra1)
                { //Jesli sprawdzamy 1 pozycje PINu
                    pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna
                    BuzzerPikniecie();

                }
                else if (pinAlarmuPozycja == 2 && klawisz == pinCyfra2)
                { //Jesli sprawdzamy 2 pozycje PINu
                    pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna  
                    BuzzerPikniecie();
                }
                else if (pinAlarmuPozycja == 3 && klawisz == pinCyfra3)
                { //Jesli sprawdzamy 3 pozycje PINu
                    pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna 
                    BuzzerPikniecie();
                }
                else if (pinAlarmuPozycja == 4 && klawisz == pinCyfra4)
                { //Jesli sprawdzamy 4 pozycje PINu
                    BuzzerPikniecie();
                    BuzzerPikniecie();
                    BuzzerPikniecie();
                    stanAlarmu = 1; //Wszystkie 4 cyfry kodu sa poprawne
                    pinAlarmuPozycja = 1; //Resetujemy informacje o wpisywanym pinie  
                    
                }
                else
                {
                    stanAlarmu = 4; //Blad w kodzie PIN - wlacz alarm
                    pinAlarmuPozycja = 1; //Resetujemy informacje o wpisywanym pinie 
                }
            }

            delay(50);
            ileCzasuMinelo++; //odliczanie czasu na wpisanie kodu 

            if (ileCzasuMinelo <= 15)
            {
                for (i = 0; i < 2; i++)
                {
                    listwa.setPixelColor(i, listwa.Color(0, 20, 0));
                }
                listwa.show();
            }
            else if (ileCzasuMinelo > 15 && ileCzasuMinelo <= 30)
            {
                for (i = 2; i < 4; i++)
                {
                    listwa.setPixelColor(i, listwa.Color(20, 20, 0));
                }
                listwa.show();
            }
            else if (ileCzasuMinelo > 30 && ileCzasuMinelo <= 45)
            {
                for (i = 4; i < 6; i++)
                {
                    listwa.setPixelColor(i, listwa.Color(20, 20, 0));
                }
                listwa.show();

            }
            else if (ileCzasuMinelo > 45 && ileCzasuMinelo <= 60)
            {
                for (i = 6; i < 8; i++)
                {
                    listwa.setPixelColor(i, listwa.Color(20, 0, 0));
                }
                listwa.show();
            }
            else
            {
                stanAlarmu = 4;
            }

            break;

        case 4:
            //sygnalizacja alarmu
            for (i = 0; i < 8; i++)
            {
                listwa.setPixelColor(i, listwa.Color(255, 0, 0));
            }
            listwa.show();
            delay(100);

            for (i = 0; i < 8; i++)
            {
                listwa.setPixelColor(i, listwa.Color(0, 0, 255));
            }
            listwa.show();
            BuzzerAlarm();
            delay(100);

            klawisz = klawiatura.getKey();
            if (klawisz == 'D')
            {
                noTone(BUZZER);
                stanAlarmu = 1;
            }

            break;



    }

}

void wylaczDiody()
{ //funkcja służąca do wyłączenia diod
    int i = 0;
    for (i = 0; i < 8; i++)
    {
        listwa.setPixelColor(i, listwa.Color(0, 0, 0));
    }
    listwa.show();
}

void BuzzerPikniecie()
{
    tone(BUZZER, 600);
    delay(50);
    noTone(BUZZER);
}

void BuzzerAlarm()
{
    tone(BUZZER, 2000);
    delay(30);
    tone(BUZZER, 1500);
}

I krótki film:

 

  • Lubię! 2
  • 3 tygodnie później...

Odrobiłem pracę domową i proszę o sprawdzenie 😄 

Poniżej wstawiam kod:

#include <Arduino.h>
#include <Keypad.h>
#include <Adafruit_NeoPixel.h>
#define BUZZER 11
#define KONTRAKTRON 10
#define PIR 12
#define RESET 2
const byte ROWS = 4; // ile wierszy
const byte COLS = 4; //ile kolumn
 
byte rowPins[ROWS] = {5, 4, 3, A5}; //piny wierszy
byte colPins[COLS] = {6, 7, 8, 9}; //piny kolumn

char keys[ROWS][COLS]={
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

Keypad klawiatura = Keypad(makeKeymap(keys),rowPins,colPins,ROWS,COLS);
Adafruit_NeoPixel linijka = Adafruit_NeoPixel(8, 13, NEO_GRB + NEO_KHZ800); 

volatile int stanAlarmu = 1;
int pinAlarmuPozycja = 1;
char pinCyfra1 = '1';
char pinCyfra2 = '2';
char pinCyfra3 = '3';
char pinCyfra4 = '4';
int ileCzasuMinelo=0;
char kolor;

void reset(){
  noTone(BUZZER);
  stanAlarmu=1;
  Serial.println("Przerwanie!");
}

void setup() {
  Serial.begin(9600);
  pinMode(BUZZER,OUTPUT);
  pinMode(KONTRAKTRON,INPUT);
  pinMode(PIR,INPUT);
  pinMode(RESET,INPUT);
  linijka.begin();
  linijka.show();
  attachInterrupt(digitalPinToInterrupt(2), reset, FALLING);
}

void wyczysc()
{
  for(int i = 0; i<8; i++){
    linijka.setPixelColor(i,linijka.Color(0,0,0));
  }
  linijka.show();
}
void zaswiec (char kol){
  if(kol=='R'){
    for (int i = 0; i < 8; i++)
        {
          linijka.setPixelColor(i,linijka.Color(255,0,0));
          linijka.show();
        }
  }
  else if( kol=='G')
  {
    for (int i = 0; i < 8; i++)
        {
          linijka.setPixelColor(i,linijka.Color(0,255,0));
          linijka.show();
        }
  }
  else{
    for (int i = 0; i < 8; i++)
        {
          linijka.setPixelColor(i,linijka.Color(0,0,255));
          linijka.show();
        }
  }
}
void sekwencjaUzbrajania(){
  for(int i=1;i<8;i++){
          linijka.setPixelColor(i,linijka.Color(0,255,0));
          linijka.show();
          delay(710);
        }
       
        for (int i = 0; i < 8; i++)
        {
          linijka.setPixelColor(7-i,linijka.Color(255,0,0));
          linijka.show();
          delay(630);
        }
        for(int i=0;i<3;i++){
            kolor = 'R';
            wyczysc();
            delay(250);
            zaswiec(kolor);
            delay(250);
        }
        wyczysc();
}
void loop() {
  char klawisz;
  switch (stanAlarmu)
  {
  case 1:
  wyczysc();
  linijka.setPixelColor(0,linijka.Color(0,255,0));
  linijka.show();
  klawisz  = klawiatura.getKey();
    if(klawisz=='A'){
      tone(BUZZER, 3500, 100);
      stanAlarmu=2;
      sekwencjaUzbrajania(); // czas trwania 12 sekund
    }
      
    break;
  case 2:
  // Stan uzbrojenia
      linijka.setPixelColor(7, linijka.Color(255, 0, 0)); 
      linijka.show();
      delay(50);
      linijka.setPixelColor(7, linijka.Color(0, 0, 0)); 
      linijka.show();
      delay(50);

      if(digitalRead(PIR)==HIGH){
        stanAlarmu=4;
        Serial.println("Wykryto ruch! ALARM!");
      }else if(digitalRead(KONTRAKTRON)==HIGH){
        ileCzasuMinelo=0;
        stanAlarmu=3;
        Serial.println("Przechodzimy do wpisania kodu PIN");
      }
    break;
  case 3:
  // Stan rozbrojenia przez podanie PIN
    klawisz = klawiatura.getKey();
    if(klawisz){
        if(klawisz==pinCyfra1 && pinAlarmuPozycja==1){
          pinAlarmuPozycja++;
          tone(BUZZER, 3500, 100);}
        else if(klawisz==pinCyfra2 && pinAlarmuPozycja==2){
          pinAlarmuPozycja++;
          tone(BUZZER, 3500, 100);}
        else if(klawisz==pinCyfra3 && pinAlarmuPozycja==3){
        pinAlarmuPozycja++;
        tone(BUZZER, 3500, 100);}
        else if(klawisz==pinCyfra4 && pinAlarmuPozycja==4){
          stanAlarmu=1;
          pinAlarmuPozycja=1;
          tone(BUZZER, 3500, 100);}
        else
        {
          tone(BUZZER, 3500, 100);
          stanAlarmu=4;
          pinAlarmuPozycja=1;
          Serial.println("Bledny PIN! ALARM!!!");
        }
     }
        delay(100);
        ileCzasuMinelo++;
        if(ileCzasuMinelo>50)
          stanAlarmu=4;
    break;
  case 4:
  //Stan Alarmu
    zaswiec('R');
    tone(BUZZER,4300);
    delay(100);
    zaswiec('B');
    digitalWrite(BUZZER,3500);
    delay(100);
    break;
  }
}

Natknąłem się na jeden błąd ukazany na filmiku niżej. Mianowicie przerwanie nie przerywa sekwencji uzbrajania, dopiero po jej zakończeniu ustawiana jest zielona dioda.

Link filmiku na dysku:

https://drive.google.com/open?id=12TSF_ErON7ONpIL_IvJlBEMFMaR4SYub

Dzisiaj wróciłem do tego problemu. Wystarczy dodać warunek w pętlach (w funkcji sekwencjaUzbrajania) for sprawdzający czy stanAlarmu jest nadal równy 2, dzięki temu w momencie gdy przerwanie zmieni stan alarmu maksymalnie po jednym delay'u przechodzimy do ustawionego w przerwaniu stanu. 

  • Lubię! 1

@Merfinius fajnie że problem, że tak ujmę "sam się rozwiązał" 🙂 napotykanie takich trudności na pewno pozwala lepiej zrozumieć temat. Powodzenia w rozwiązywaniu kolejnych problemów.

  • Lubię! 1
  • 2 tygodnie później...
(edytowany)

Witam. Chciałbym stworzyć taką centralkę, tylko nieco prostszą na zwykłych switcach. Wszysrtko jest okej ale nie wiem jak zrobić, aby w case 3 nie przechodziło od razu do stanu alarmu tylko był jakis czas na wpisanie pinu. Bardzo proszę o porady.

 

#define zazbrajanie 0
#define cyfra1 1
#define cyfra2 2
#define cyfra3 3
#define cyfra4 4
volatile int stanAlarmu = 1;
int pozycja = 1;


void setup() {
  pinMode(0, INPUT_PULLUP); //zazbrajanie alarmu
  pinMode(1, INPUT_PULLUP); // klawiatura
  pinMode(2, INPUT_PULLUP); // klawiatura
  pinMode(3, INPUT_PULLUP);  // klawiatura
  pinMode(4, INPUT_PULLUP);  // klawiatura
  pinMode(12, INPUT_PULLUP); //imitacja PIR
  pinMode(10, INPUT_PULLUP); //imitacja Kontraktonu
  pinMode(A2, OUTPUT); // diody sygnalizacyjne
  pinMode(A4, OUTPUT); // diody sygnalizacyjne
  pinMode(A3, OUTPUT); // diody sygnalizacyjne
}

void loop() {

  switch(stanAlarmu){
    case 1:  //stan czuwania
    if(digitalRead(zazbrajanie) == LOW) {   // jesli nacisniemy, uklad zaczyna pracowac
      for(int i = 0; i < 5; i++) {
  digitalWrite(A2, HIGH);
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  delay(500);
  digitalWrite(A2, LOW);
  digitalWrite(A4, LOW);
  digitalWrite(A3, LOW);
  delay(500);
      }
      stanAlarmu = 2;  //po mignięciach przechodzimy w stan czuwania
    }
    break;

    case 2:  
  digitalWrite(A2, HIGH);  //sygnalizcja stanu czuwania
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  if(digitalRead(12) == LOW) {   //czy PIR wykryl ruch?
    stanAlarmu = 4;   // jesli tak, włącz alarm
  } else if(digitalRead(10) == LOW) { //czy kontrakton otwarty?
    stanAlarmu = 3;  // jesli tak, daj możliwosc wpisania PIN
  }
  break;

  case 3:  // wpisywanie PIN
  if(digitalRead(cyfra1) == LOW && pozycja == 1) {
    pozycja++;
  } else if(digitalRead(cyfra2) == LOW && pozycja == 2) {
  pozycja++;
  } else if(digitalRead(cyfra3) == LOW && pozycja == 3) 
  pozycja++;
   else if(digitalRead(cyfra4) == LOW && pozycja == 4) {
 stanAlarmu = 1;
 pozycja = 1;
} else {
  stanAlarmu = 4;
  pozycja = 1;
}
break;
case 4:  // alarm
for(int i = 0; i < 8; i++) {
  digitalWrite(A2, LOW);
  digitalWrite(A4, HIGH);
  digitalWrite(A3, HIGH);
  delay(500);
  digitalWrite(A2, HIGH);
  digitalWrite(A4, LOW);
  digitalWrite(A3, LOW);
  delay(500);
}
break;
  }
}

 

Edytowano przez Gieneq
Zachęcam do używania bloku kodu

Ze stanu 3 masz możliwość przejść do stanu 1 lub 4.

Przejść do stanu 1 możesz tylko gdy podasz kolejne pozycje czyli gdy pozycja i stan przycisku będą w odpowiedniej kolejności. Gdy podbijesz w ten sposób zmienną pozycja do 4 to się odblokuje. Z kolei każda pomyłka wywoła blok "else" i masz stan alarmu 4.

Więc o którym stanie alarmu piszesz? Bo do stanu alarmu 1 jest czas nieograniczony. A stan 4 wpada przy pomyłce.

Jeżeli chciałbyś w jakiś sposób mieć drugą szansę to wystarczy że będziesz zliczał nieudane próby i jak np przekroczysz 3 to dopiero wtedy wejdzie w stan 4. Każda nieudana próba ma zwiększać licznik nieudanych prób i resetować stan zliczania - czyli stanAlarmu = 1, pozycja w 1

5 godzin temu, Gieneq napisał:

Ze stanu 3 masz możliwość przejść do stanu 1 lub 4.

Przejść do stanu 1 możesz tylko gdy podasz kolejne pozycje czyli gdy pozycja i stan przycisku będą w odpowiedniej kolejności. Gdy podbijesz w ten sposób zmienną pozycja do 4 to się odblokuje. Z kolei każda pomyłka wywoła blok "else" i masz stan alarmu 4.

Więc o którym stanie alarmu piszesz? Bo do stanu alarmu 1 jest czas nieograniczony. A stan 4 wpada przy pomyłce.

Jeżeli chciałbyś w jakiś sposób mieć drugą szansę to wystarczy że będziesz zliczał nieudane próby i jak np przekroczysz 3 to dopiero wtedy wejdzie w stan 4. Każda nieudana próba ma zwiększać licznik nieudanych prób i resetować stan zliczania - czyli stanAlarmu = 1, pozycja w 1

tak tak, ale problem jest w tym, że u mnie od razu przechodzi w stan 4, Proszę spojrzeć na case 3 wydaje mi się że tu mam jakiś błąd

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...