Skocz do zawartości

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


Komentator

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.

Link do komentarza
Share on other sites

@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
Link do komentarza
Share on other sites

#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
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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
Link do komentarza
Share on other sites

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();?

Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.