Skocz do zawartości

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


Komentator

Pomocna odpowiedź

@planszowki Wróć do pierwszego poziomu kursu Arduino i tam masz opis jak podłączyć przycisk. Podłącz sobie do masy, a w programie daj pullup i zrobione. Przerwanie możesz dać - o tym było w części 4 tego kursu, ale nie jest to konieczne. W dalszych częściach kursu poziom 2 masz o pozornej wielozadaniowości. Tu też podrzucam Ci 2 wpisy gdzie opisałem jak używać przycisk z Arduino (jeden z wpisów dotyczy STM32 ale kod jest analogiczny):

oraz ten:

 

  • Lubię! 1
Link do komentarza
Share on other sites

Mam problem z wykonaniem tej części kursu...

Pierwszym z nich jest klawiatura, a raczej biblioteka do niej...

Pobrałem ją jak zawsze z apki (Arduino IDE) w zarządzaniu bibliotekami...

Zacząłem pisać program korzystając z komend zawartych w tym temacie kursu i zdziwko.... 

Pierwszy komunikat to błąd związany z biblioteką, a reszta to błędy w kodzie, nieistniejące komendy (np. .getKey)...

Nie wiedziałem o co chodzi, pierwszy raz coś takiego mi się przytrafiło.

Usunąłem bibliotekę i pobrałem jeszcze raz, to samo...

Wszedłem w sekcję komentarzy (może ktoś także miał taki problem i został on już rozwiązany).

Spróbowałem skorzystać z cudzysłowiu, tak jak ktoś polecił... i nic.

Dalej nie działa.

 

Później skorzystałem z przykładów, a tam zupełnie inne komendy, kod itp (no może nie zupełnie inny, ale mocno różni się od tego z kursu).

Spróbowałem napisać program właśnie na podstawie tego z przykładów, ale no coś nie wyszło.

@Treker pomógłbyś?

Jako początkujący za nic nie mogę sobie z tym problemem poradzić.

Działa mi tylko zbrojenie, a rozbrajanie już nie.

Sprawdziłem sobie na jakiej zasadzie działają te funkcje z przykładu. 

Rozbrajanie nie działa poprawnie, ponieważ (moim zdaniem) funkcja (char)e.bit.EVENT wysyła dwukrotnie wciśnięty przycisk/znak...

Próbował coś pozmieniać i teraz w terminalu widzę kwadraty.

Oczywiście sprawdzałem kod związany z rozbrajaniem, co wysyła funkcja, że nie mogę rozbrajać tylko od razu włącza mi alarm.

Na początku zauważyłem coś dziwnego, a mianowicie po przerwaniu kontaktronu wysyłało mi (do rozbrajania) liczbę 65, próbowałem to jakoś nieudolnie rozwiązać i się udało (częściowo).

Później próbowałem z dalszą częścią rozbrajania, ale mi nie wychodziło i teraz to wogóle jest klops...

 

Kopiowałem twój kod i nie działał z powodu biblioteki...

Spróbowałem zainstalować starszą wersję i to też nie pomogło....

 

Liczę na szybką pomoc 😄

 

KOD, który ukleiłem:

Sprawdzałem co wysyła podczas rozbrajania oraz czy zmienne char działają (w akcie desperacji)

#include <Adafruit_Keypad.h> //Dołączenie biblioteki od klawiatury
#include <Adafruit_NeoPixel.h> //Dołączenie biblioteki od paska LED

//Podłączone urządzenia:
#define kontaktron 10  
#define pir 12
#define buzzer 11

//Określenie liczby kolumn i wierszy
const byte ROWS = 4;
const byte COLS = 4; 

//Zdefiniowanie przycisków:
char keys[ROWS][COLS]{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'},
};

//Piny podłączenia:
byte rowPins[ROWS] = {2, 3, 4, 5}; 
byte colPins[COLS] = {9, 8, 7, 6};

//Inicjacja klawiatury:
Adafruit_Keypad klawiatura = Adafruit_Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

//Inicjacja paska LED:
Adafruit_NeoPixel linijka = Adafruit_NeoPixel(8, A0, NEO_GRB + NEO_KHZ800);

volatile int stanAlarmu = 1;

int i = 0; //Zmienna pomocnicza
int pinAlarmuPozycja = 1;
char pinCyfra1 = '1';
char pinCyfra2 = '2';
char pinCyfra3 = '3';
char pinCyfra4 = '4';
int klawisz = 0;

void setup() {
  Serial.begin(9600);
  pinMode(buzzer, OUTPUT);
  pinMode(kontaktron, INPUT_PULLUP);
  pinMode(pir, INPUT);

 linijka.begin();
 linijka.show();
 klawiatura.begin();
}

void loop() {
 
 switch(stanAlarmu){
  case 1:
   //czuwanie
   linijka.setPixelColor(0, linijka.Color(0, 15, 0));
   linijka.show();

   klawiatura.tick();
   while(klawiatura.available()){
    keypadEvent e = klawiatura.read();
    if((char) e.bit.KEY == 'A'){
      for(i = 1; i < 8; i++){
        linijka.setPixelColor(i, linijka.Color(0, 0, 15)); //Dioda nr i świeci na niebiesko
        linijka.show();
        delay(710);
      } //wykonanie tej linijki zajmie ok 5s
      for(i = 1; i < 8; i++){
        linijka.setPixelColor(i, linijka.Color(15, 0, 0)); //Dioda nr i świeci na czerwono
        linijka.show();
        delay(710);
      } //Wykonanie tej linijki zajmie ok 5s
      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
      }
      if (digitalRead(kontaktron) == HIGH ) {
        stanAlarmu = 3; //Szansa na rozbrojenie
      }
       break;

    case 3:
     //rozbrajanie
   
    klawiatura.tick();
    if(klawiatura.available() > 0){
   
    klawisz = klawiatura.getKey();
    Serial.println((char)e.bit.EVENT);
    if(pinAlarmuPozycja == 1 && (char)e.bit.EVENT == '1') { //Jesli sprawdzamy 1 pozycje PINu
          pinAlarmuPozycja++;//Cyfra poprawna, mozna sprawdzic na kolejna
        }else if (pinAlarmuPozycja == 2 && (char)e.bit.EVENT == '2') { //Jesli sprawdzamy 2 pozycje PINu
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna         
        }else if(pinAlarmuPozycja == 3 && (char)e.bit.EVENT == '3') { //Jesli sprawdzamy 3 pozycje PINu
          pinAlarmuPozycja++; //Cyfra poprawna, mozna sprawdzic na kolejna        
        }else if(pinAlarmuPozycja == 4 && (char)e.bit.EVENT == '4') { //Jesli sprawdzamy 3 pozycje PINu
          stanAlarmu = 1; //Wszystkie 4 cyfry kodu sa poprawne      
          pinAlarmuPozycja = 1; //Resetujemy informacje o wpisywanym pinie   
        } //Jesli sprawdzamy 4 pozycje PINu
       
             }
   
   break;

     case 4:
      //Sygnalizacja alarmu

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

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




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

 

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

Problem rozwiazany!!!!

Jesli komus nie dziala, a pobral biblioteke to polecam zobaczyc jaka....

Wystarczy poszukac ta zrobiona przez Mark'a Stanley'a 😄 

Smiesznie troche 😄 😄 😄 😄 

  • Lubię! 1
Link do komentarza
Share on other sites

Cześć

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

#define pir 1
#define reset 2
#define kontaktron 11
#define buzzer 12

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

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

int ileCzasuMinelo = 0; //odliczanie czasu na wpisanie pinu

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); //inicjacja klawiatury
Adafruit_NeoPixel linijka = Adafruit_NeoPixel(8, A0, NEO_GRB + NEO_KHZ800); //konfiguracja linijki led

volatile int stanAlarmu = 1;

void setup()
{

  pinMode(buzzer, OUTPUT);
  pinMode(kontaktron, INPUT_PULLUP);
  pinMode(pir, INPUT_PULLUP);
  pinMode(reset, INPUT_PULLUP);

  linijka.begin(); //inicjacja linijki led
  linijka.show(); 

  attachInterrupt(digitalPinToInterrupt(reset), resetowanie, LOW); //przerwanie do resetu
}

void loop()
{
  char klawisz = 0;
  int i = 0; //zmienna do petli

  switch (stanAlarmu) //maszyna stanow wykonujaca akcje odpowiednia dla danego stanu
  {
    case 1: //czuwanie
    
      noTone(buzzer);
      linijka.clear();
      
      linijka.setPixelColor(0, linijka.Color(0, 15, 0)); //dioda 1 swieci na zielono
      linijka.show();

      klawisz = klawiatura.getKey();
      if (klawisz == 'A') //czy uzbroic alarm? (gdy odebrany znak to A)
      {
        for (i = 1; i < 8; i++) //efekt swietlny
        {
          linijka.setPixelColor(i, linijka.Color(0, 0, 15)); //dioda nr i swieci na niebiesko
          linijka.show();
          tone(buzzer, 3500 + 50 * i);
          delay(710);
        }

        noTone(buzzer);

        for (i = 1; i < 8; i++) //kolejny efekt
        {
          linijka.setPixelColor(i, linijka.Color(15, 0, 0));
          linijka.show();
          tone(buzzer, 3900 + 50 * i);
          delay(710);
        }
        
        wylaczDiody();
        noTone(buzzer);

        tone(buzzer, 3500);  //efekt dzwiekowy
        delay(100);
        tone(buzzer, 3800);
        delay(100);
        tone(buzzer, 4000);
        delay(100);
        tone(buzzer, 4200);
        delay(100);
        tone(buzzer, 4500);
        delay(100);
        noTone(buzzer);

        stanAlarmu = 2;
      }

      break;

    case 2: //monitorowanie
    
      linijka.setPixelColor(7, linijka.Color(15, 0, 0)); //dioda8 na czerwono
      linijka.show();
      delay(50);
      
      linijka.setPixelColor(7, linijka.Color(0, 0, 0)); //dioda 8 wylaczona
      linijka.show();
      delay(50);

      //monitorujemy dwa parametry

      if (digitalRead(pir) == HIGH) //jesli wykryto ruch
      {
        stanAlarmu = 4; //Natychmiast uruchamiamy alarm
      }
      else if (digitalRead(kontaktron) == HIGH) //jesli kontaktron rozerwany
      {
        ileCzasuMinelo = 0; //zerowanie zmiennej do odliczania czasu
        for (i = 0; i < 8; i++) //efekt swietlny
        {
          linijka.setPixelColor(i, linijka.Color(35, 15, 0));
        }
        linijka.show();
        stanAlarmu = 3; //Szansa na rozbrojenie
      }

      break;

    case 3: //rozbrajanie

      klawisz = klawiatura.getKey(); //pobieramy znak

      if (klawisz) //jesli mamy znak
      {
        tone(buzzer, 3500); //dzwiek "bip"
        delay(40);
        noTone(buzzer);

        if (pinAlarmuPozycja == 1 && klawisz == pinCyfra1) //cyfra 1 - jesli klawisz wpisany zgadza sie z tym co ustalilismy
        {
          pinAlarmuPozycja++; //cyfra poprawna - przechodzimy do kolejnej
        }
        
         else if (pinAlarmuPozycja == 2 && klawisz == pinCyfra2) //sprawdzenie 2 pozycji
         {
           pinAlarmuPozycja++; //cyfra poprawna - przechodzimy do kolejnej
         }
         
          else if (pinAlarmuPozycja == 3 && klawisz == pinCyfra3) //sprawdzenie 3 pozycji
          {
            pinAlarmuPozycja++; //cyfra poprawna - przechodzimy do kolejnej
          }
          
           else if (pinAlarmuPozycja == 4 && klawisz == pinCyfra4) //sprawdzenie 4 pozycji
           {
             stanAlarmu = 1; //kod poprawny, przechodzimy do czuwania
             pinAlarmuPozycja = 1; //resetujemy mechanizm
             wylaczDiody();
           }
           
            else
            {
              stanAlarmu = 4; //blad w pinie - wlaczamy alarm
              pinAlarmuPozycja = 1; //resetujemy mechanizm
              wylaczDiody();
            }

      }

      //odmierzanie czasu wyznaczonego na wpisanie pinu
      delay(100);
      ileCzasuMinelo++;
      if (ileCzasuMinelo >= 50) //jesli uplynal okreslony czas na wpisanie pinu
      {
        stanAlarmu = 4; //uruchom alarm
      }

      break;

    case 4: //sygnalizacja alarmu

      for (i = 0; i < 8; i++)
      {
        linijka.setPixelColor(i, linijka.Color(255, 0, 0)); //dioda i swieci na czerwono
      }
      linijka.show();
      tone(buzzer, 4300);
      delay(100); //mozliwe sa delaye ze wzgledu ze case 4 jest ostatnia mozliwoscia

      for (i = 0; i < 8; i++)
      {
        linijka.setPixelColor(i, linijka.Color(0, 0, 255)); //dioda i swieci 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)); //wylaczenie diod
  }
  linijka.show();
}

void resetowanie()
{
  stanAlarmu = 1;
}

oryginalny kod + przerwanie i nowe efekty dźwiękowe.

Kolejna świetna część kursu!

Pozdrawiam

Edytowano przez emiemi8
  • Lubię! 1
Link do komentarza
Share on other sites

Czy mógłby ktoś wyjaśnić ten fragment kodu? Nie przypominam sobie, żeby to było w poprzednich ćwiczeniach

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

O oznacza zapis rowPins[ROWS], dlaczego przypisując nową zmienną odwołujemy się do innej?

Link do komentarza
Share on other sites

 

Do swojego systemu alarmowego dodałem dodatkowo efekty dźwiękowe odliczania przy uzbrajaniu oraz dźwiękowy komunikat o uzbrojeniu.  Można było pokusić się o zbudowaniu systemu na dwóch buzzerach - cichym do komunikatów i głośnym na MOSFETcie do alarmu.

#define buzzer 11
#define kontakt 10
#define PIR 1
#define ResetButton 2

#include <Keypad.h>
#include <Adafruit_NeoPixel.h>

const byte ROWS = 4;
const byte COLS = 4;

byte rowPins[ROWS] = {5, 4, 3, 0};
byte colPins[COLS] = {6, 7, 8, 9};

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, A0, NEO_GRB + NEO_KHZ800);

volatile int stanAlarmu = 1;

int pinAlarmuPozycja = 1;
char pinCyfra1 = '4';
char pinCyfra2 = '1';
char pinCyfra3 = '0';
char pinCyfra4 = '1';


int ileCzasu = 0;

void setup() {
  pinMode(buzzer, OUTPUT);
  pinMode(kontakt, INPUT_PULLUP);
  pinMode(PIR, INPUT_PULLUP);
  pinMode(ResetButton, INPUT_PULLUP);

  linijka.begin();
  linijka.show();
  attachInterrupt(digitalPinToInterrupt(ResetButton), stanAlarmu = 1, LOW);
}

void loop() {
  char klawisz = 0;
  int i = 0;

  switch(stanAlarmu) {
    case 1: //czuwanie
      linijka.setPixelColor(0, linijka.Color(0, 15, 0));
      linijka.show();

      klawisz = klawiatura.getKey();

      if (klawisz == 'A') {
        tone(buzzer, 2500);
        delay(100);
        noTone(buzzer);
        for (i = 1; i < 8; i++) {
          linijka.setPixelColor(i, linijka.Color(0, 0, 15));
          linijka.show();
          tone(buzzer, 2000 + i * 100);
          delay(50);
          noTone(buzzer);
          delay(640);
        }
        for (i = 1; i < 8; i++) {
          linijka.setPixelColor(i, linijka.Color(15, 0, 0));
          linijka.show();
          tone(buzzer, 2000 + i * 100);
          delay(50);
          noTone(buzzer);
          delay(640);        
        }
      tone(buzzer, 2500);
      delay(100);
      tone(buzzer, 3000);
      delay(100);
      tone(buzzer, 3500);
      delay(100);
      noTone(buzzer);
      wylaczDiody();
      stanAlarmu = 2;  
      }  
    break;

    case 2: //monitorowanie
      linijka.setPixelColor(7, linijka.Color(15, 0, 0));
      linijka.show();
      delay(50);
      linijka.setPixelColor(7, linijka.Color(0, 0, 0));
      linijka.show();
      delay(50);

      if (digitalRead(PIR) == HIGH) {
        stanAlarmu = 4;
      }
      else if (digitalRead(kontakt) == HIGH) {
        ileCzasu = 0;
        stanAlarmu = 3;
      } 

    break;

    case 3: //rozbrajanie
      klawisz = klawiatura.getKey();
      if(klawisz) {
        tone(buzzer, 4000);
        delay(100);
        noTone(buzzer);
        if (pinAlarmuPozycja == 1 && klawisz == pinCyfra1) {
          pinAlarmuPozycja++;
        } else if (pinAlarmuPozycja == 2 && klawisz == pinCyfra2) {
          pinAlarmuPozycja++;
        } else if (pinAlarmuPozycja == 3 && klawisz == pinCyfra3) {
          pinAlarmuPozycja++;
        } else if (pinAlarmuPozycja == 4 && klawisz == pinCyfra4) {
          stanAlarmu = 1;
          pinAlarmuPozycja = 1;
        } else {
          stanAlarmu = 4;
          pinAlarmuPozycja = 1;
        }
      }

      delay(100);
      ileCzasu++;

      if (ileCzasu >= 50) {
        stanAlarmu = 4;
      }
    break;

    case 4: //alarm

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

      for(i = 0; i < 8; i++) {
        linijka.setPixelColor(i, linijka.Color(0, 0, 255));
      }
      linijka.show();
      tone(buzzer, 3500);
      delay(50);
      tone(buzzer, 2500);
      delay(50);
    break;
  }

}

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

 

Edytowano przez Sito89
  • Lubię! 2
Link do komentarza
Share on other sites

9 godzin temu, Sito89 napisał:
void wylaczDiody() {
  int i = 0;
  for (i = 0; i < 8; i++) {
    linijka.setPixelColor(i, linijka.Color(0, 0, 0));
  }
  linijka.show();
}

Jestem przed pierwszą kawą, więc odniosę się tylko do tego 😉
Jak dobrze widzę konstrukcję, to linijka gaśnie cała, a nie po kolei? Jak tak, to czyszczenie nie lepsze? 😄


 

void wylaczDiody() {
  linijka.clear();
  linijka.show();
}

 

Link do komentarza
Share on other sites

Dnia 1.02.2024 o 09:13, Danyeru napisał:

Jestem przed pierwszą kawą, więc odniosę się tylko do tego 😉
Jak dobrze widzę konstrukcję, to linijka gaśnie cała, a nie po kolei? Jak tak, to czyszczenie nie lepsze? 😄


 

void wylaczDiody() {
  linijka.clear();
  linijka.show();
}

 

Jasne, że lepiej. Dzięki 😄 

Taki zapis, jak miałem był oryginalnie w kodzie z tej lekcji, więc go przeklepałem nie zastanawiając się na tym. Pewnie pisząc, już myślałem o czymś ważniejszym 😉 Jeszcze raz dzięki za podpowiedź!

Link do komentarza
Share on other sites

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

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.