Skocz do zawartości

Rozbudowa systemu alarmowego z kursu Arduino


Pomocna odpowiedź

Napisano

No to ja dorzucę swoich kilka pytań. Może jakieś sugestie się Wam nasuną. Bazuję na programie rozbudowanym już o przerwanie (jak będę przy komputerze wrzucę listing).  Usiłuję rozwiązać problem:

1. Po uzbrojeniu alarmu i rozłączeniu kontaktronu mam 10s na rozbrojenie. OK. Po ponownym uzbrojeniu, przy próbie rozbrojenia od razu włącza się alarm. Wnioskuję że nie jest "resetowany" wskaźnik numeru wprowadzonego znaku. Jak to zmienić?

2. W sumie najlepszym chyba rozwiązaniem było by gdyby cała sekwencję pinu wprowadzić i dopiero całość akceptować jakimś klawiszem, a nie po kolei - obecna forma nie zostawia miejsca na korektę.  Z drugiej strony można by to rozwiązanie ograniczyć np. do 3 prób.

3. Rozbrojenie alarmu przez wywołanie przerwania jest ok, ale warto było by jeszcze dodać możliwość rozbrojenia gdy już alarm się aktywuje. Nie wiedzieć czemu gdy w tym przypadku próbuję wprowadzić coś z klawiatury aktywny jest tylko jeden klawisz "6" reszta nie generuje niczego w podglądzie Serial.println.

4. Czego powinienem użyć by rozbudować układ z ćwiczenia o ekran lcd? Patrząc na wcześniejsze ćwiczenia z LCD to zarówno klawiatura jak i LCD korzystają z tych samych pinów. Nie mówiąc już o tym że np. próbuję rozbudować układ o kolejne PIR i kontaktrony i tutaj już w ogóle brakuje pinów.

Na ten moment to wszystko chyba... ale kolejne pomysły na rozbudowę się pojawią.

16 godzin temu, MC2Systems napisał:

4. Czego powinienem użyć by rozbudować układ z ćwiczenia o ekran lcd? Patrząc na wcześniejsze ćwiczenia z LCD to zarówno klawiatura jak i LCD korzystają z tych samych pinów. Nie mówiąc już o tym że np. próbuję rozbudować układ o kolejne PIR i kontaktrony i tutaj już w ogóle brakuje pinów.

Jeśli chcesz do układu podłączyć więcej elementów to nie obejdzie się np. bez ekspanderów GPIO, które działają na I2C. Przykład wykorzystania tego układu znajdziesz tutaj: Kurs budowy robotów – #9 – ekspander I/O, serwo. Za pomocą takich układów możesz podłączyć wyświetlacz oraz dodatkowe elementy wykonawcze.

Jak wstawisz kod programu to łatwiej będzie pomóc, więc pozostałe pytania chwilowo zostawiam na później 😉

(edytowany)

W odniesieniu do wcześniejszej mojej wypowiedzi... doszedłem do wniosku że trochę zmodyfikuję rozwiązanie i... natrafiłem na problem.

Z uwagi na to że mówimy o "systemie alarmowym", wydaje mi się przydało by się trochę bezpieczniej podejść do tematu, no przynajmniej ja chciałbym 😉

Dnia 28.09.2019 o 20:25, MC2Systems napisał:

2. W sumie najlepszym chyba rozwiązaniem było by gdyby cała sekwencję pinu wprowadzić i dopiero całość akceptować jakimś klawiszem, a nie po kolei - obecna forma nie zostawia miejsca na korektę.  Z drugiej strony można by to rozwiązanie ograniczyć np. do 3 prób.

Założyłem 2 etapy:

1. zamiast wprowadzania znaku i od razu kontroli poprawności (co  jest prostsze ale wprowadzać może problematyczne sytuacje)  chcę wprowadzać sekwencji np. 4 znaków zakończonych  znakiem #. I dopiero dla tej sekwencji wykonywana jest kontrola poprawności. Takie rozwiązanie zwiększa ilość kombinacji. 

2. Wprowadzenie kontroli ilości prób. Powiedzmy 3 próby zanim alarm się uruchomi.

Zmontowałem podstawowy układ do wprowadzania danych z "klawiatury" i wyświetlania wyniku na monitorze portu szeregowego. Do tego kawałek kodu. Na początek by wiedzieć co się dzieje i jakie są pośrednie wyniki, ustawiłem warunki dla 3 znaków i kontrolę na porcie szeregowym dla każdego etapu. Oczywiście jak poprawnie zadziała to zbędne elementy się usunie.

#include <Keypad.h>
const byte ROWS = 4; // ile wierszy
const byte COLS = 4; //ile kolumn
byte rowPins[ROWS] = {5, 4, 3, 2};
byte colPins[COLS] = {6, 7, 8, 9};
// MAPOWANIE
char keys[ROWS][COLS] = { //mapowanie klawiatury
  {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'}
};
//inicjalizacja klawiatury
Keypad klawiatura = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
  Serial.begin(9600);
}

void loop() {
  char klawisz = klawiatura.getKey();
  String kod;
  String k = String(klawisz); //string z klawiatury
  String a = "_"; //ciąg wyjściowy
  String a1;     //string pomocniczy
  if (klawisz != NO_KEY)
  {
    while (klawisz != '#' ) //klawisz zakończenia
    {
      switch (klawisz)
      {
        case 'A':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz A ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case 'B':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz B ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case 'C':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz C ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case 'D':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz D ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '1':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 1 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '2':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 2 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '3':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 3 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '4':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 4 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '5':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 5 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '6':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 6 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '7':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 7 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '8':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 8 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '9':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 9 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '0':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz 0 ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        case '*':
          {
            kod = kod_wyjsciowy(a, k);
            Serial.print("klawisz * ");
            Serial.print(" kod=");
            Serial.print(kod);
            a1 = kod;
            Serial.print(" a1=");
            Serial.println(a1);
            delay(10);
          }
          break;
        default:

          break;
      }
      a = a1;
      klawisz = klawiatura.getKey();
      k = String(klawisz);

    }
    // jeśli # to porównaj z szyfrem
  } // koniec NO_KEY

  Serial.println(kod);
  delay(10);
}


String kod_wyjsciowy(String stary, String nowy)
{
  String wyjscie;
  wyjscie = stary + nowy;
  return wyjscie;
}

Podstawowe pytanie na ten moment to jak zoptymalizować ilość pamięci którą program zajmuje. Obecnie niewiele program robi a już zabiera 22% pamięci programu i 25% pamięci dynamicznej. 


 

Edytowano przez MC2Systems
pierwotny problem udało się rozwiązać...
Dnia 29.09.2019 o 12:57, Treker napisał:

Jeśli chcesz do układu podłączyć więcej elementów to nie obejdzie się np. bez ekspanderów GPIO, które działają na I2C. Przykład wykorzystania tego układu znajdziesz tutaj: Kurs budowy robotów – #9 – ekspander I/O, serwo. Za pomocą takich układów możesz podłączyć wyświetlacz oraz dodatkowe elementy wykonawcze.

Jak wstawisz kod programu to łatwiej będzie pomóc, więc pozostałe pytania chwilowo zostawiam na później 😉

Dzięki za wskazówkę. Czyli zostaje albo Arduino Mega albo expandery... Póki co expander zastosuję.

  • Lubię! 1

@MC2Systems, mam pytanie do kodu, który wstawiłeś. Czemu ten switch...case ma służyć. Jest chyba niepotrzebny, dobrze widzę? W każdym przypadku robisz to samo, a zmienną char (klawisz) i tak możesz wyświetlić sobie przez Serial.print zamiast pisać w osobnych przypadkach: "klawisz A "/"klawisz B "...itd. Chociaż dziś już ledwo na oczy widzę to przepraszam, jeśli coś przeoczyłem 😄

  • Lubię! 2
12 godzin temu, MC2Systems napisał:

Dzięki za wskazówkę. Czyli zostaje albo Arduino Mega albo expandery... Póki co expander zastosuję.

@MC2Systems lepszym rozwiązaniem w większości przypadków będą ekspandera, ponieważ zawsze możesz łączyć ich kilka. Bardzo łatwo możesz dodać 8, 16, 24 "nowych" pinów itd.

11 godzin temu, Bhoy67 napisał:

@MC2Systems, mam pytanie do kodu, który wstawiłeś. Czemu ten switch...case ma służyć. Jest chyba niepotrzebny, dobrze widzę? W każdym przypadku robisz to samo, a zmienną char (klawisz) i tak możesz wyświetlić sobie przez Serial.print zamiast pisać w osobnych przypadkach: "klawisz A "/"klawisz B "...itd. Chociaż dziś już ledwo na oczy widzę to przepraszam, jeśli coś przeoczyłem 😄

Słuszna uwaga 😉 Późna pora też mi się udzieliła. To co zamieściłem to była ewolucja z użycia nieskutecznego innych pętli... w efekcie faktycznie switch jest niepotrzebny. 
Skrócenie kodu zaowocowało też zmniejszeniem zajętości pamięci... Same plusy 😉

Ok, to teraz już chyba poprawnie. Docelowo wysyłki na monitor portu szeregowego mają być zastąpione wyświetlaczem LCD, ale czekam na ekspander.
Przydało by się jeszcze by po każdym wciśnięciu klawisza został wysłany na LCD podgląd, a po sekundzie nadpisany  *.

#include <Keypad.h>
const byte ROWS = 4; // ile wierszy
const byte COLS = 4; //ile kolumn
byte rowPins[ROWS] = {5, 4, 3, 2};
byte colPins[COLS] = {6, 7, 8, 9};
// MAPOWANIE
char keys[ROWS][COLS] = { //mapowanie klawiatury
  {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'}
};
//inicjalizacja klawiatury
Keypad klawiatura = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
  Serial.begin(9600);
}

void loop() {
  char klawisz = klawiatura.getKey();
  String szyfr = "92740*AC";
  String kod;
  String k = String(klawisz); //string z klawiatury
  String a = ""; //ciąg wyjściowy
  String a1;     //string pomocniczy
  
  if (klawisz != NO_KEY)
  {
    for (int i = 1; i < 4; i++)
    {
      while (klawisz != '#' ) //klawisz zakończenia
      {
        kod = kod_wyjsciowy(a, k);
        a1 = kod;
        a = a1;
        klawisz = klawiatura.getKey();
        k = String(klawisz);
      }
      // jeśli # to porównaj z szyfrem

      if (a1 != szyfr)
      { int proby = 3 - i;
        Serial.print("Próba "); Serial.print(i); Serial.print("#3 "); Serial.print("błędne hasło "); Serial.println(a1);
        delay(1500);
        a = "";
        klawisz = klawiatura.getKey();
        k = String(klawisz);
      }
      else if (a1 == szyfr)
      {
        Serial.print ("super podałeś prawidłowe hasło "); Serial.println(a1);
        delay(1500);
      }
    }
    if (a1 != szyfr)
    {
      Serial.print("ALARM");
      delay(2000);
    }
  } // koniec NO_KEY
}


String kod_wyjsciowy(String stary, String nowy)
{
  String wyjscie;
  Serial.print("Klawisz"); Serial.println(nowy); // nie działa zgodnie z oczekiwaniem
  wyjscie = stary + nowy;
  return wyjscie;
}

Niestety wyświetlanie wprowadzonego znaku w pojedynczym wierszu pojedynczo  nie działa tak jak tego oczekiwałem. Cały czas przewija się sekwencja.
Tak że tutaj mile widziana sugestia jak to rozwiązać.

Napisz może dokładnie co chciałeś osiągnąć i dlaczego to co jest nie działa zgodnie z oczekiwaniem ( co to znaczy "przewija się sekwencja").

Tak przy okazji pomyśl o rezygnacji ze String na rzecz zmiennych typu char i tablic - pamięć w Arduino nie jest z gumy i za chwilę może jej zabraknąć! Poczytaj o niebezpieczeństwach używania malloc() i free() - klasa String jest zaimplementowana za pomocą tych funkcji.

  • Lubię! 1

@ethanak  No właśnie mam problem z przełożeniem tego co pojawia się np. na ekranie komputera gdy piszę program, a z tym co wyświetla port szeregowy.

Gdy piszę w np. php  print('coś tam'); otrzymuję pojedynczy wiersz na wyjściu z tym tekstem i tyle.

Gdy piszę w ArduinoC  Serial.print("Klawisz"); Serial.println(nowy);   w porcie szeregowym mam efekt przewijania się wielu wierszy Klawisz i sporadycznie gdy wduszę jakiś klawisz to wyświetli się jaki. I to nie jest to co chcę uzyskać.

Efekt który chcę uzyskać to coś podobne do tego co mam w php. Wyświetli się aktualny klawisz i nie ma tej całej sekwencji "Klawisz". 
Docelowy efekt ma być taki że gdy naciskam klawisz pojawia się  dźwięk o zdefiniowanych parametrach (wysokości i długość) i najpierw pojawia się dany znak, zamieniany po sekundzie na # lub *. Po prostu ma być podgląd tego co się nacisnęło bez zbyt długiego czasu na zobaczenie przez osoby postronne.
Docelowo z tej całej funckjonalności zrobić funkcję która będzie zwracać prawdę lub fałsz i na bazie tego system albo włącza alarm albo rozbraja się.

  • Lubię! 1

Dla większego porządku posty wydzieliłem z kursu, ponieważ nie dotyczą one ćwiczeń z kursu (jest to rozbudowa opisanych tam przykładów). Tutaj będzie łatwiej utrzymać porządek w dyskusji i nie będziemy mylić osób szukających informacji o programach z kursu. Źródło pytania: https://forbot.pl/forum/topic/9531-kurs-arduino-ii-5-klawiatura-wlasny-system-alarmowy/

 

(edytowany)

@MC2Systems życzę powodzenia bo przyglądam się z ciekawością. Też chcę zbudować namiastkę alarmu w kluczowych miejscach, z bateryjnym podtrzymaniem i modułem GSM, by być niezależnym od zasilania, internetu itp... Ino czasu brak:(

@Treker ostatnie posty @ethanak proponuję wkleić do Twojego poradnika dobrych manier na forum, jako wzorcowy, pozytywny przykład:) 

Edytowano przez SOYER
  • 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...