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

(edytowany)

 

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

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.