Skocz do zawartości

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


Pomocna odpowiedź

Pisałem komentarz z zapytaniem, ale podczas jego pisania rozwiązałem problem, ale zamieszczam informację, gdyby ktoś miał taki problem jak ja 😛
Przez to, że wyjście PIR jest podłączone do PINu 1 na Arduino (TX), który odpowiada również za wysyłanie danych to, gdy gdzieś w kodzie zainicjalizujecie serial to będzie Wam zawsze program łapał na tym PINie stan wysoki, a co za tym idzie zawsze będzie uruchamiał alarm (stan 4).

U siebie miałem w setupie Serial.begin(9600) 😛

  • Lubię! 1

Tutaj mój kod z:

1. Efektem dźwiękowym przy kliknięciu przycisku
2. Efekt dźwiękowy podczas zazbrajania alarmu

#define BUZZER 11
#define KONTRAKTON 10
#define PIR 1

#include <Keypad.h> // Biblioteka klawiatury
#include <Adafruit_NeoPixel.h> // Biblioteka linijki LED

const byte ROWS = 4; // Ile wierszy
const byte COLS = 4; // Ile kolumn

int pinAlarmPosition = 1;
char pinNumber1 = '1';
char pinNumber2 = '2';
char pinNumber3 = '3';
char pinNumber4 = '4';

int passedTime = 0;

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

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

Keypad keyboard = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); // Inicjalizacja klawiatury
Adafruit_NeoPixel LED = Adafruit_NeoPixel(8, A0, NEO_GRB + NEO_KHZ800); // Konfiguracja linijki LED

volatile int alarmState = 1;

void setup() {

  pinMode(BUZZER, OUTPUT);
  pinMode(KONTRAKTON, INPUT_PULLUP);
  pinMode(PIR, INPUT_PULLUP);

  LED.begin(); // Inicjalizacja linijki
  LED.show();

}

void loop() {

  char key = 0; // zmienna do przetrzymywania znakow z klawiatury
  int i = 0; // zmienna pomocnicza do pętli


  switch(alarmState) {
    case 1:
        // Listening
        LED.setPixelColor(0, LED.Color(0, 15, 0)); // Dioda nr 1 świeci na zielono
        LED.show();

        key = keyboard.getKey();
        if (key == 'A') {
          int buzzTones = 2000;
          for (i = 1; i < 8; i++){
            LED.setPixelColor(i, LED.Color(0, 0, 15)); // Dioda nr. 1 świeci na niebiesko
            LED.show();
            tone(BUZZER, buzzTones);
            delay(710);
            buzzTones = buzzTones + 100;
          } // Wykonanie tej pętli zajmie około 5 sekund

          for (i = 1; i < 8; i++){
            LED.setPixelColor(i, LED.Color(15, 0, 0)); // Dioda nr i świeci na czerwono
            LED.show();
            delay(710);
            buzzTones = buzzTones + 100;
            tone(BUZZER, buzzTones);
          }
          noTone(BUZZER);
          turnOffLED();
          alarmState = 2;
        }
    break;

    case 2:
      // Monitoring
      LED.setPixelColor(7, LED.Color(15, 0, 0)); // Dioda nr 8 świeci na czerowno
      LED.show();
      delay(50);
      LED.setPixelColor(7, LED.Color(0, 0, 0)); // Dioda nr 8 wyłączona
      LED.show();
      delay(50);

      if (digitalRead(PIR) == HIGH) {
        alarmState = 4; // Natychmiast uruchamiamy alarm
      } else if (digitalRead(KONTRAKTON) == HIGH){
        alarmState = 3; // Szansa na rozbrojenie
      }
    break;

    case 3:
      // Disarming
      key = keyboard.getKey();
      if(key){
        // Czy kolejna podana cyfra jest poprawna?
        if (pinAlarmPosition == 1 && key == pinNumber1) { // Jeśli sprawdzamy 1 pozycję PINu
          pinAlarmPosition++; // Cyfra poprawna, można sprawdzić kolejną
          pinSound();
        } else if (pinAlarmPosition == 2 && key == pinNumber2){
          pinAlarmPosition++;
          pinSound();
        } else if (pinAlarmPosition == 3 && key == pinNumber3) {
          pinAlarmPosition++;
          pinSound();
        } else if (pinAlarmPosition == 4 && key == pinNumber4){
          pinSound();
          alarmState = 1; // Wszystkie 4 cyfry są poprawne
          pinAlarmPosition = 1; // Resetujemy informacje o wpisywanym pinie
        } else{
          alarmState = 4; // Błąd w kodzie PIN - włącz alarm
          pinAlarmPosition = 1; // Resetujemy informacje o PINie
        }
       }

       delay(100);
       passedTime++;

       if (passedTime >= 50) {
        alarmState = 4;
       }
    break;

    case 4:
      // Alarm signal
      for (i = 0; i < 8; i++){
        LED.setPixelColor(i, LED.Color(255, 0, 0)); // Dioda nr i swieci na czerowno
      }
      LED.show();
      tone(BUZZER, 4300);
      delay(100);

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


void turnOffLED(){
  int i = 0;
  for (i = 0; i < 8; i++){
    LED.setPixelColor(i, LED.Color(0, 0, 0)); // Dioda nr 1 wyłaczona
  }
  LED.show();
}

void pinSound(){
  tone(BUZZER, 2000);
  delay(50);
  noTone(BUZZER);
}

 

  • Lubię! 2
  • 8 miesiące później...
(edytowany)

Zadania dodatkowe 
sygnał dźwiękowy podczas uzbrajania alarmu,
sygnał dźwiękowy podczas podawania pinu (wciśnięcie klawisza - "bip"),
osobny przycisk podłączony pod przerwanie, który resetuje alarm,
bardziej rozbudowane efekty dźwiękowe.

 

Ok o ile sobie poradzilem z efektami dzwiękowymi i wygląda to juz naprawdę fajnie to jakoś nie działa mi ten przycisk z przerwaniem. Nic nie reaguje. Czy ktos może spojrzeć na kod co jest nie tak? 

 attachInterrupt(digitalPinToInterrupt(RESET), restart, FALLING); tu zmirenialem i na falling i na rising. Przycisk podlaczony do arduino do pinu 12 a z drugiej strony do gnd.

 

Czy mozna odsylac poprzez przerwanie do case 1? jak to napisałem w 

void restart() {stanAlarmu = 1;}

??

#define BUZZER 11
#define KONTAKTRON 10
#define PIR 1
#define RESET 12
#include <Keypad.h> //biblioteka od klawiatury
#include <Adafruit_NeoPixel.h> //biblioteka od linijki LED

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

byte rowPins[ROWS] = {5, 4, 3, 2}; //piny wierszy
byte colPins[COLS] = {6, 7, 8, 9}; //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); //Konfiguracja pin 11 jako buzzera
  pinMode(KONTAKTRON, INPUT_PULLUP);
  pinMode(PIR, INPUT_PULLUP);
  pinMode(RESET, INPUT_PULLUP);
 attachInterrupt(digitalPinToInterrupt(RESET), restart, FALLING); // Przerwanie reagujące na zbocze rosnące
  linijka.begin(); //inicjalizacja linijki
  linijka.show(); 
}

void loop() {
  char klawisz = 0; //zmienna do przetrzymywania znakow z klawiatury
  int i = 0; //zmienna pomocnicza do pętli

  switch(stanAlarmu) { //Wykonywania akcji odpowiedniej dla danego stanu
    case 1:
      //Czuwanie
      linijka.setPixelColor(0, linijka.Color(0, 15, 0)); //Dioda nr 1 świeci na zielono
      linijka.show();
      
      klawisz = klawiatura.getKey();
      if (klawisz == 'A') { //Czy zubroic alarm?
        for (i = 1; i < 8; i++) {
          tone(BUZZER, 4300, 100); //Wygeneruj sygnał o częstotliwości 4300Hz na pinie 11 ktory trwa 100ms
          linijka.setPixelColor(i, linijka.Color(0, 0, 15)); //Dioda nr i świeci na niebiesko
          linijka.show();
          delay(710);
        } // wykonanie tej petli zajmie okolo 5 sekund
        
         for (i = 1; i < 8; i++) {
          tone(BUZZER, 2300, 100); //Wygeneruj sygnał o częstotliwości 2300Hz na pinie 11 ktory trwa 100ms
          linijka.setPixelColor(i, linijka.Color(15, 0, 0)); //Dioda nr i świeci na czerwono
          linijka.show();
          delay(710);
        } // wykonanie tej petli zajmie okolo 5 sekund     
         tone(BUZZER, 2000, 500); //Wygeneruj sygnał o częstotliwości 2000Hz na pinie 11 ktory trwa 500ms  
        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 wylaczona
      linijka.show();
      delay(50);

      if (digitalRead(PIR) == HIGH) {
        stanAlarmu = 4; //Natychmiast uruchamiamy alarm
      } else if (digitalRead(KONTAKTRON) == HIGH) {
        ileCzasuMinelo= 0; //Zerowanie zmiennej
        stanAlarmu = 3; //Szansa na rozbrojenie
      }
      
    break;
    
    case 3:
      //Rozbrajanie
      klawisz = klawiatura.getKey();
      if (klawisz) {

        // dzwiek przy kliknieciu
          tone(BUZZER, 4300, 100); //Wygeneruj sygnał o częstotliwości 4300Hz na pinie 11 ktory trwa 100ms
  
  delay(150);  
        //Czy kolejna podana cyfra jest poprawna?
        if (pinAlarmuPozycja == 1 && klawisz == pinCyfra1) { //Jesli sprawdzamy 1 pozycje PINu
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna
        } else if (pinAlarmuPozycja == 2 && klawisz == pinCyfra2) { //Jesli sprawdzamy 2 pozycje PINu
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna         
        } else if (pinAlarmuPozycja == 3 && klawisz == pinCyfra3) { //Jesli sprawdzamy 3 pozycje PINu
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna        
        } else if (pinAlarmuPozycja == 4 && klawisz == pinCyfra4) { //Jesli sprawdzamy 4 pozycje PINu
            stanAlarmu = 1; //Wszystkie 4 cyfry kodu sa poprawne
            pinAlarmuPozycja = 1; //Resetujemy informacje o wpisywanym pinie  

             // dzwiek poprawnej kombinacji
      for (int i = 0; i < 5; i++) {
        tone(BUZZER, 4300, 100); //Wygeneruj sygnał o częstotliwości 4300Hz na pinie 11 ktory trwa 100ms
        delay(100); // Wydłużamy opóźnienie, aby dźwięki były słyszalne
        noTone(BUZZER);
        delay(100); // Wydłużamy opóźnienie, aby dźwięki były słyszalne

        }} else {
           stanAlarmu = 4; //Blad w kodzie PIN - wlacz alarm
           pinAlarmuPozycja = 1; //Resetujemy informacje o wpisywanym pinie 
           tone(BUZZER, 1000, 500); // Dźwięk o niższej częstotliwości i dłuższym czasie trwania BLEDNY PIN
        }}
      

      delay(100);
      ileCzasuMinelo++;

      if (ileCzasuMinelo >= 50) {
        stanAlarmu = 4;
      }
    break;
    
    case 4:
      //Sygnalizacja alarmu
      for (i = 0; i < 8; i++) {  
        tone(BUZZER, 4500); //Wygeneruj sygnał o częstotliwości 4500Hz na pinie 11 ktory trwa 100ms
        linijka.setPixelColor(i, linijka.Color(255, 0, 0)); //Dioda nr i świeci na czerwono 
      }
      linijka.show();
      delay(100);
      noTone(BUZZER);
      
      for (i = 0; i < 8; i++) {  
        linijka.setPixelColor(i, linijka.Color(0, 0, 255)); //Dioda nr i świeci na niebiesko 
      }
      linijka.show();
      delay(100);
    break;
   } 
}

void wylaczDiody() {
  int i = 0;
  for (i = 0; i < 8; i++){
    linijka.setPixelColor(i, linijka.Color(0, 0, 0));   
  }
  linijka.show();
  }
void restart() {
stanAlarmu = 1;
}

 

 

Edytowano przez PanMajster
(edytowany)

@jand Oczywiście że masz rację nawet było o tym w kursie 🙂
Teraz wszystko działa. Zaktualizowany kod jak by ktoś szukał ściągawki

 

#define BUZZER 11
#define KONTAKTRON 10
#define PIR 1
#define RESET 2
#include <Keypad.h> //biblioteka od klawiatury
#include <Adafruit_NeoPixel.h> //biblioteka od linijki LED

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

byte rowPins[ROWS] = {5, 4, 3, 12}; //piny wierszy
byte colPins[COLS] = {6, 7, 8, 9}; //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 = '*';
char pinCyfra2 = '0';
char pinCyfra3 = '#';
char pinCyfra4 = 'D';

int ileCzasuMinelo = 0;

void setup() {
  pinMode(BUZZER, OUTPUT); //Konfiguracja pin 11 jako buzzera
  pinMode(KONTAKTRON, INPUT_PULLUP);
  pinMode(PIR, INPUT_PULLUP);
  pinMode(RESET, INPUT_PULLUP);
 attachInterrupt(digitalPinToInterrupt(RESET), restart, FALLING); // Przerwanie reagujące na zbocze rosnące
  linijka.begin(); //inicjalizacja linijki
  linijka.show(); 
}

void loop() {
  char klawisz = 0; //zmienna do przetrzymywania znakow z klawiatury
  int i = 0; //zmienna pomocnicza do pętli

  switch(stanAlarmu) { //Wykonywania akcji odpowiedniej dla danego stanu
    case 1:
      //Czuwanie + wygaszenie diod po resecie
      wylaczDiody();
      linijka.setPixelColor(0, linijka.Color(0, 15, 0)); //Dioda nr 1 świeci na zielono
      linijka.show();
      
      klawisz = klawiatura.getKey();
      if (klawisz == 'A') { //Czy uzbroic alarm?
        for (i = 1; i < 8; i++) {
          tone(BUZZER, 4300, 100); //Wygeneruj sygnał o częstotliwości 4300Hz na pinie 11 ktory trwa 100ms
          linijka.setPixelColor(i, linijka.Color(0, 0, 15)); //Dioda nr i świeci na niebiesko
          linijka.show();
          delay(710);
        } // wykonanie tej petli zajmie okolo 5 sekund
        
         for (i = 1; i < 8; i++) {
          tone(BUZZER, 2300, 100); //Wygeneruj sygnał o częstotliwości 2300Hz na pinie 11 ktory trwa 100ms
          linijka.setPixelColor(i, linijka.Color(15, 0, 0)); //Dioda nr i świeci na czerwono
          linijka.show();
          delay(710);
        } // wykonanie tej petli zajmie okolo 5 sekund     
         tone(BUZZER, 2000, 500); //Wygeneruj sygnał o częstotliwości 2000Hz na pinie 11 ktory trwa 500ms  
        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 wylaczona
      linijka.show();
      delay(50);

      if (digitalRead(PIR) == HIGH) {
        stanAlarmu = 4; //Natychmiast uruchamiamy alarm
      } else if (digitalRead(KONTAKTRON) == HIGH) {
        ileCzasuMinelo= 0; //Zerowanie zmiennej
        stanAlarmu = 3; //Szansa na rozbrojenie
      }
      
    break;
    
    case 3:
      //Rozbrajanie
      klawisz = klawiatura.getKey();
      if (klawisz) {

        // dzwiek przy kliknieciu
          tone(BUZZER, 4300, 100); //Wygeneruj sygnał o częstotliwości 4300Hz na pinie 11 ktory trwa 100ms
  
  delay(150);  
        //Czy kolejna podana cyfra jest poprawna?
        if (pinAlarmuPozycja == 1 && klawisz == pinCyfra1) { //Jesli sprawdzamy 1 pozycje PINu
        linijka.setPixelColor(0, linijka.Color(15, 15, 15)); //Dioda nr 1 świeci na zółto
        linijka.setPixelColor(pinAlarmuPozycja, linijka.Color(15, 15, 0)); //Dioda nr 1 świeci na zółto
          linijka.show();
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna
        } else if (pinAlarmuPozycja == 2 && klawisz == pinCyfra2) { //Jesli sprawdzamy 2 pozycje PINu
          linijka.setPixelColor(pinAlarmuPozycja, linijka.Color(25, 25, 0)); //Dioda nr 1 świeci na zółto 
          linijka.show();  
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna    
            
        } else if (pinAlarmuPozycja == 3 && klawisz == pinCyfra3) { //Jesli sprawdzamy 3 pozycje PINu
          linijka.setPixelColor(pinAlarmuPozycja, linijka.Color(35, 35, 0)); //Dioda nr 1 świeci na zółto
          linijka.show(); 
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna  
        } else if (pinAlarmuPozycja == 4 && klawisz == pinCyfra4) { //Jesli sprawdzamy 4 pozycje PINu
         for (int i = 0; i < 8; i++) {
        linijka.setPixelColor(i, linijka.Color(0, 25, 0)); //Dioda nr 1 świeci na Zielono
        linijka.show(); 
            stanAlarmu = 1; //Wszystkie 4 cyfry kodu sa poprawne
            pinAlarmuPozycja = 1; //Resetujemy informacje o wpisywanym pinie  
         }
             // dzwiek poprawnej kombinacji
      for (int i = 0; i < 5; i++) {
        linijka.setPixelColor(0, linijka.Color(0, 15, 0)); //Dioda nr 1 świeci na Zielono
        tone(BUZZER, 4300, 100); //Wygeneruj sygnał o częstotliwości 4300Hz na pinie 11 ktory trwa 100ms
        delay(100); // Wydłużamy opóźnienie, aby dźwięki były słyszalne
        noTone(BUZZER);
        delay(100); // Wydłużamy opóźnienie, aby dźwięki były słyszalne
      
      linijka.show();

        }} else {
           stanAlarmu = 4; //Blad w kodzie PIN - wlacz alarm
           pinAlarmuPozycja = 1; //Resetujemy informacje o wpisywanym pinie 
           tone(BUZZER, 1000, 500); // Dźwięk o niższej częstotliwości i dłuższym czasie trwania BLEDNY PIN
        }}
      

      delay(100);
      ileCzasuMinelo++;

      if (ileCzasuMinelo >= 50) {
        stanAlarmu = 4;
      }
    break;
    
    case 4:
      //Sygnalizacja alarmu
      for (i = 0; i < 8; i++) {  
        tone(BUZZER, 4500); //Wygeneruj sygnał o częstotliwości 4500Hz na pinie 11 ktory trwa 100ms
        linijka.setPixelColor(i, linijka.Color(255, 0, 0)); //Dioda nr i świeci na czerwono 
      }
      linijka.show();
      delay(100);
      noTone(BUZZER);
      
      for (i = 0; i < 8; i++) {  
        linijka.setPixelColor(i, linijka.Color(0, 0, 255)); //Dioda nr i świeci na niebiesko 
      }
      linijka.show();
      delay(100);
    break;
   } 
}

void wylaczDiody() {
  int i = 0;
  for (i = 0; i < 8; i++){
    linijka.setPixelColor(i, linijka.Color(0, 0, 0));   
  }
  linijka.show();
  }
void restart() {
stanAlarmu = 1;

}

 

Edytowano przez PanMajster
zmiana kodu rozbrojenia na *0#D
  • 3 miesiące później...

@waldemaw10 na czym dokładnie polega problem? Co to znaczy, że instalują Ci się inne biblioteki? Czy próbowałeś pobrać bibliotekę i zainstalować ją "ręcznie" z archiwum ZIP?

  • 8 miesiące później...

 

W załączniku znajduje się program oraz film przedstawiający efekt działania centralki alarmowej po modyfikacjach. 

centralkaAlarmowaRozbudowana.zip

Poniżej wstawiam kod programu:

#define BUZZER 11
#define KONTAKTRON 10
#define PIR 1
#define PRZYCISK_RESETU 2

#include <Keypad.h> //biblioteka od klawiatury
#include <Adafruit_NeoPixel.h> //biblioteka od linijki LED

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

byte rowPins[ROWS] = {5, 4, 3, 12}; //piny wierszy
byte colPins[COLS] = {6, 7, 8, 9}; //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(KONTAKTRON, INPUT_PULLUP);
  pinMode(PIR, INPUT_PULLUP);
  pinMode(PRZYCISK_RESETU, INPUT_PULLUP);

  linijka.begin(); //inicjalizacja linijki
  linijka.show(); 
  attachInterrupt(digitalPinToInterrupt(2), reset, FALLING);
}

void loop() {
  char klawisz = 0; //zmienna do przetrzymywania znakow z klawiatury
  int i = 0; //zmienna pomocnicza do pętli

  switch(stanAlarmu) { //Wykonywania akcji odpowiedniej dla danego stanu
    case 1:
      //Reset
      wylaczDiody();
      wyciszAlarm();
      stanAlarmu = 2;
      break;
    
    case 2:
      //Czuwanie


      linijka.setPixelColor(0, linijka.Color(0, 15, 0)); //Dioda nr 1 świeci na zielono
      linijka.show();
      
      klawisz = klawiatura.getKey();
      if (klawisz == 'A') { //Czy uzbroic 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, 300);
          delay(355);
          tone(BUZZER, 2000);
          delay(355);
        } // wykonanie tej petli zajmie okolo 5 sekund
        
         for (i = 1; i < 8; i++) {
          linijka.setPixelColor(i, linijka.Color(15, 0, 0)); //Dioda nr i świeci na czerwono
          linijka.show();
          tone(BUZZER, 300);
          delay(355);
          tone(BUZZER, 2000);
          delay(355);
        } // wykonanie tej petli zajmie okolo 5 sekund     
        noTone(BUZZER);
        wylaczDiody();
        stanAlarmu = 3;
      }
        
    break;
    
    case 3:
      //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 wylaczona
      linijka.show();
      delay(50);

      if (digitalRead(PIR) == HIGH) {
        stanAlarmu = 5; //Natychmiast uruchamiamy alarm
      } else if (digitalRead(KONTAKTRON) == HIGH) {
        ileCzasuMinelo= 0; //Zerowanie zmiennej
        stanAlarmu = 4; //Szansa na rozbrojenie
      }
      
    break;
    
    case 4:
      //Rozbrajanie
      klawisz = klawiatura.getKey();
      if (klawisz) {
        tone(BUZZER, 697);
        delay(100);
        noTone(BUZZER);


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

      delay(100);
      ileCzasuMinelo++;

      if (ileCzasuMinelo >= 50) {
        stanAlarmu = 5;
      }
    break;
    
    case 5:
      //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 nr 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 1 wylaczona    
  }

  linijka.show();
}

void wyciszAlarm() {
  noTone(BUZZER);
}

void reset(){
  stanAlarmu = 1;
}
  

Jeśli chodzi o zmiany w kodzie to:

  • Dodałem dodatkowy stan który resetuje diody i buzzer. 
    case 1:
      //Reset
      wylaczDiody();
      wyciszAlarm();
      stanAlarmu = 2;
      break;
  • Dodałem efekt dźwiękowy w trakcie uzbrajania alarmu.
if (klawisz == 'A') { //Czy uzbroic 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, 300);
          delay(355);
          tone(BUZZER, 2000);
          delay(355);
        } // wykonanie tej petli zajmie okolo 5 sekund
        
         for (i = 1; i < 8; i++) {
          linijka.setPixelColor(i, linijka.Color(15, 0, 0)); //Dioda nr i świeci na czerwono
          linijka.show();
          tone(BUZZER, 300);
          delay(355);
          tone(BUZZER, 2000);
          delay(355);
        } // wykonanie tej petli zajmie okolo 5 sekund     
        noTone(BUZZER);
        wylaczDiody();
        stanAlarmu = 3;
  • Dodałem jednolity efekt dźwiękowy w trakcie wciskania przycisków
case 4:
      //Rozbrajanie
      klawisz = klawiatura.getKey();
      if (klawisz) {
        tone(BUZZER, 697);
        delay(100);
        noTone(BUZZER);
  • Dodałem przerwanie które po wciśnięciu przycisku przechodzi do stanu resetu.
attachInterrupt(digitalPinToInterrupt(2), reset, FALLING);

 

void reset(){
  stanAlarmu = 1;
}

Ogólnie bardzo fajny projekt który podsumowuje wiedzę z wcześniejszych artykułów + jest praktyczny.

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

Mój program z uwzględnieniem zadań dodatkowych. Specjalnie dodałem piąty stan alarmu, żeby maksymalnie zminimalizować samą funkcję przerwania. W samym piątym stanie wstawiłem też funkcje wyłączania diod i buzzera, żeby uniknąć nakładania dźwięków i samych efektów świetlnych diod po resecie.

PIR specjalnie przeniosłem na pin 12, bo staram się unikać wykorzystywania pinów 0(RX) i 1 (TX). Zauważyłem, że gdy w momencie wysyłania programu do Arduino mam stan niski na pinie 0(RX), to program nie chce się wgrywać. Miałem tak przy poprzednim kursie z kontaktronem, więc już dla zasady, jeżeli nie muszę, to nie wykorzystuję tych pinów :).

Program działa dobrze w mojej ocenie, Alarm się wyłącza, po wciśnięciu dedykowanego przycisku resetu, dodałem sygnały dźwiękowe. Mam jedynie problem z tym (i nie potrafię dojść dlaczego tak się dzieje), że przerwanie nie działa w momencie, gdy alarm się uzbraja, czyli po wciśnięciu przycisku "A", gdy pojawia się ok 10 sekundowa animacja na diodach. W tym momencie tych 10 sekund, przerwanie nie robi nic, a chciałem móc je przerwać, żeby też wróciło do stanu świecenia się jednej zielonej diody i oczekiwania na uzbrojenie.

#define BUZZER A5
#define KONTAKTRON 11
#define PIR 12
#define reset 2
#include <Keypad.h> //biblioteka od klawiatury
#include <Adafruit_NeoPixel.h> //biblioteka od linijki LED
const byte ROWS = 4; // ile wierszy
const byte COLS = 4; //ile kolumn
byte rowPins[ROWS] = {6, 5, 4, 3}; //piny wierszy
byte colPins[COLS] = {7, 8, 9, 10}; //piny kolumn
char keys[ROWS][COLS] = { //mapowanie klawiatury
  {'A','B','C','D'},
  {'3','6','9','#'},
  {'2','5','8','0'},
  {'1','4','7','*'}
};
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(KONTAKTRON, INPUT_PULLUP);
  pinMode(PIR, INPUT_PULLUP);
  pinMode(reset, INPUT_PULLUP);
  linijka.begin(); //inicjalizacja linijki
  linijka.show(); 
  attachInterrupt(digitalPinToInterrupt(reset), resetujStan, FALLING);
}
void loop() {
  char klawisz = 0; //zmienna do przetrzymywania znakow z klawiatury
  int i = 0; //zmienna pomocnicza do pętli
  switch(stanAlarmu) { //Wykonywania akcji odpowiedniej dla danego stanu
    
    case 1:
      //Czuwanie
      linijka.setPixelColor(0, linijka.Color(0, 15, 0)); //Dioda nr 1 świeci na zielono
      linijka.show();
           
      klawisz = klawiatura.getKey();
      if (klawisz == 'A') { //Czy zubroic alarm?
        tone(BUZZER, 1000, 100);

        for (i = 1; i < 8; i++) {
          linijka.setPixelColor(i, linijka.Color(0, 0, 15)); //Dioda nr i świeci na niebiesko
          linijka.show();
          tone(BUZZER, 1000, 100);
          delay(710);
        } // wykonanie tej petli zajmie okolo 5 sekund
        
         for (i = 1; i < 8; i++) {
          linijka.setPixelColor(i, linijka.Color(15, 0, 0)); //Dioda nr i świeci na czerwono
          linijka.show();
          tone(BUZZER, 2000, 100);
          delay(710);
        } // wykonanie tej petli zajmie okolo 5 sekund     
          
        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 wylaczona
      linijka.show();
      delay(50);
      if (digitalRead(PIR) == HIGH) {
        stanAlarmu = 4; //Natychmiast uruchamiamy alarm
      } else if (digitalRead(KONTAKTRON) == HIGH) {
        ileCzasuMinelo= 0; //Zerowanie zmiennej
        stanAlarmu = 3; //Szansa na rozbrojenie
      }
      
    break;
    
    case 3:
      //Rozbrajanie
      klawisz = klawiatura.getKey();
      if (klawisz) {
        tone(BUZZER, 2000, 100);
        //Czy kolejna podana cyfra jest poprawna?
        if (pinAlarmuPozycja == 1 && klawisz == pinCyfra1) { //Jesli sprawdzamy 1 pozycje PINu
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna
        } else if (pinAlarmuPozycja == 2 && klawisz == pinCyfra2) { //Jesli sprawdzamy 2 pozycje PINu
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna         
        } else if (pinAlarmuPozycja == 3 && klawisz == pinCyfra3) { //Jesli sprawdzamy 3 pozycje PINu
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna        
        } else if (pinAlarmuPozycja == 4 && klawisz == pinCyfra4) { //Jesli sprawdzamy 4 pozycje PINu
            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(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 nr i świeci na niebiesko 
      }
      linijka.show();
      tone(BUZZER, 3500);
      delay(100);
    break;

    case 5:
      noTone(BUZZER);
      wylaczDiody();
      stanAlarmu = 1; 
    break;
   }
  
}
void wylaczDiody() {
  int i = 0;
  for (i = 0; i < 8; i++){
    linijka.setPixelColor(i, linijka.Color(0, 0, 0)); //Dioda nr 1 wylaczona    
  }
  linijka.show();
}

void resetujStan() {
  stanAlarmu = 5;  
}

 

  • Lubię! 1

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...