• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Identyfikacja numeru telefonu, arduino-sim800, alarm, odczyt softwareserial
#1
tagi
Arduino sim800, identyfikacja numeru przychodzącego, softwareserial odczyt danych

Witam
Chcę zrobić alarm używając Arduino. Sprawa banalna, czujniki, syrena parę prostych IFów... ale jak go wyłączyć, rozbroić? Fajnie by było użyć do tego telefonu, skoro każdy go ma ze sobą. I takich gotowych rozwiązani jest multum. tyle ze opierają swoje działanie na internecie albo smsach. Odpada. już przez sam fakt że odbezpieczenie alarmu wymaga kilku ruchów na ekranie. Nie każdy ma smartfona, nie każdy ma internet i wogóle pisanie smsa żeby wejść do lokalu - uważam za chybiony pomysł. Puszczenie "dzwonka" nie wystarczy? Tylko takiego rozwiązania nie znalazłem.

Założenia:
Alarm ma powiadamiać zdalnie o naruszeniu. W zasadzie wystarczy nawiązanie rozmowy, ale może być sms, z informacją który czujnik zadziałał. Rozbrajanie alarmu ma być realizowane za pomocą dowolnego telefonu. wstępnie był pomysł aby każda osoba dzwoniąca na numer alarmu go rozbrajała, ale co z telemarketerami? No to może dzwonek wejście do lokalu i w ciągu 30 sekund potwierdzenie rozbrojenia przyciskiem? Nie... Na bank da się to zrobić identyfikując numer. Musi być tak, aby alarm odbezpieczały tylko wybrane numery.

Hardware:
Arduino NANO. modem, moduł o nazwie SIM800. czujniki pir, albo mikrofalowe, wyświetlacz lcd, przekaźnik uruchamiający syrenę, buzer. Ze względu na różnice napięć, jedną z nóżek sim800 trzeba podłączać przez "dzielnik napięcia" zrobiony z rezystora 3k2 i 4k7 ohm. sim800 ma nieładny zwyczaj pobierania bardzo dużego prądu w momencie pierwszego logowania się do sieci, więc  trzeba mu przy samym zasilaniu zapiąć duuży kondensator. czytałem ze 1500mikro wystarczy, u mnie nie zawsze wystarczał. więc dałem 3300mikro. Arduino jest zasilane z 5V, sim800 z baterii, wiec nie zalecam przekraczania 4.2V. (mój jest zasilany z 18650)

Software:
(jeśli potrafisz to zrobić prościej - napisz proszę jak)
punktem wyjścia jest zestawienie komunikacji z PC po hardwarowym serialu przez kabel usb, a z sim800 po softwarowym serialu, po zdefiniowanych pinach. znaki przychodzące z (klawiatury PC) hard-seriala wysyłane są do (sim800) soft seriala. i na odwrót. znaki wysyłane z soft seriala(sim800) są wysyłane na hard-serial(ekran PC) Znaki. to ważne słowo. Nieda się więc szukać  w tym co widzimy na ekranie numeru telefonu, bo to zlepek pojedyńczych znaków. Czy trzeba analizować ciągle kolejne ciągi znaków? Czy nie spowoduje to "zamulenia" arduino? Ja to "obszedłem" tak: Mój numer telefonu to 508xxxxx. Więc wystarczy że w transmisji z seriala będę szukał "piątki" i 8 kolejnych znaków. trop okazał sie słuszny. jeśli program znajdzie "piątkę" to do ciągu o nazwie "numer_telefonu" dopisuje (matematycznie dodaje) każdy kolejny znak. tak dostałem swój numer, który mogłem porównać z wprowadzonym do programu. Można było dopisać w programie kilka numerów telefonu od porównywania. to nie problem. problem był taki, że wszystkie musiały się zaczynać od "piątki" Przed numerem telefonu jest "clip:" więc zacząłem "łapać wysyłane znaki od dwukropka i zapisałem do zmiennej "numer_telefonu". następnie odczytałem (porównałem) zmienną z pominięciem 3 pierwszych znaków. 
    Czy istnieje inna metoda? W zasadzie tak. Znalazłem program, naprawdę profesjonalny program zarządzający otwieraniem bramy. Jednak tam wykorzystano inny system identyfikacji, gdyż sam pogram na arduino miał być uniwersalny dla każdej bramy, więc nie mógł zawierać numerów telefonu.... czyli numery muszą być zapisane na karcie sim. ów program wymaga modyfikowanej biblioteki sim900h, którą ja jeszcze musiałem zmodyfikować aby soft-serial działał na tych a nie innych pinach. Czy to nie lepsze rozwiązanie? To zależy. ja raz ustalę jakie numery otwierają alarm, więc to mi nie robi różnicy. Mogę żonglowac kartami sim, co moze przełożyć sie na niższe koszty. no i chyba dośc istotna sprawa, ten program w okrojonej wersji zajmuje 29% pamięci i 49% pamięci zmiennych, mój (okrojony) 11 i 14%. Ale sam pomysł naprowadził mnie na inne rozwiązanie.
 
rozwiązanie problemu nr 2
Wszystkie numery telefonu które miały otwierać alarm, zapisałem na karcie sim, nadając im nazwy rozpoczynające się od ciągu trzech identycznych (żadko spotykanych) znaków i kolejnej cyfry. więc dajmy na to 
508xxxxxx   "+(-001" 
508yyyyyy   "+(-002" 
508zzzzzz   "+(-003". 
Następne program miał za zadanie znaleźć znak "=", jeśli to znalazł to czekać na"(" a następnie na "-". ciąg trzech konkretnych znaków (z całej tabeli ascii) uważam za wystarczający do odblokowania alarmu. trudno to nazwać identyfikacją numeru, ale działa. 

Problemy
Komunikacja po serialach nie jest idealna. dość często trafiały mi się jakieś błędy, najczęściej objawiające się rzędami odwróconych znaków zapytania, a czasami gubieniem wysyłanych znaków. z gubieniem znaków poradziłem sobie wstawiając delaye(10-50) a ze znakami zapytania... podnosząc prędkość transmisji do 57600. Nie pytajcie mnie dlaczego. Najczęściej spotyka sie na serialach w arduino 9600, czasem nawet 4800, a mnie rzędy pytajników zaczęły się kurczyć przy 37tyś cośtam a zniknęły na 57tyś. Niestety, czasami pierwszy dzwonek nie identyfikował się poprawnie. Aby uzyskać potwierdzenie identyfikowania zdecydowałem że "podniosę" słuchawkę w sim800, piknę coś dtmf-em i odłożę. 2 sekundy to 1 grosz - pomijalny koszt (wspomniana biblioteka sim900h potrzebuje 5 sekund (ciszy) na zainicjowanie piknięcia dtmfem. nie chodzi o grosiki ale wydłuża to czas zabawy z telefonem) Tu uwaga - po ATA ma NIE być spacji - długo się z tym męczyłem. 

Kod:
// napisał: ToMasz
// bierz co chcesz do swoich projektów
// Dziel się z innymi, ale wspomnij o autorze
#include <SoftwareSerial.h>         // do obslugi rx i tx z sim800
SoftwareSerial serialSIM800(3,4);   //ustawienia pinow Rxi Tx do komunikacji z sim800
#include <LiquidCrystal_I2C.h>      // do obslugi wyswietlacza LCD
LiquidCrystal_I2C lcd(0x3f, 2,1,0,4,5,6,7); // ustawienie adresu LCD I2C
int i=1;           //zmienna potrzebna do petli for
char znak=' ';     // pojedynczy znak wczytywany z seriala
String numer="";   // numer telefonu poskladany z pojedynczych znakow

void setup() {
Serial.begin(57600);             //start komunikacji przez USB
while(!Serial);                  // Potrzebne do komunikacji prze USB
serialSIM800.begin(57600);       // start komunikacji z sim800
// na 57600 najlepiej to dziala. na duzo nizszych prędkosciach
// czasami wyswietlaly sie znaki zapytania. na wyzszych - gubily znaki

pinMode(9, OUTPUT);     // tu jest podlaczona diodka z rezystorem 500ohm
digitalWrite(9, HIGH);  // migamy sobie diodka
delay(500);             // przy starcie
digitalWrite(9, LOW);   // w celu sprawdzeia czy dziala

lcd.begin(16,2);                  // initialize the lcd
lcd.setBacklightPin(3, POSITIVE); //na pinie 3 LCD (nie arduino) bedzie swiatlo
lcd.setBacklight(HIGH);           //zalaczamy swiatelko
lcd.setCursor(0,0);               // kursor na poczatek ekranu
lcd.clear();                      // czyscimy ewentualne smieci

Serial.println("Komunikacja software serial dziala");  //Taki tam testowy napis seeriala
serialSIM800.write("AT\r");                           //na wszelki wypadek budzimy modem do zycia
//serialSIM800.write("AT+CBC \r");                     //stan baterii procent naladowania, mili wolt
//serialSIM800.write("AT+COPS? \r");                   // u jakiego operoatora jeses?
//serialSIM800.write("AT+CSQ \r");                     // zasieg. umnie 30 to maks
}

void loop() {
 
 if(serialSIM800.available()){  //jesli sa jakies dane na porcie sim800
 znak=(serialSIM800.read());    // odczytaj jeden znak
 Serial.write(znak);            // wyslij hardware serialem = wyswietl go na ekranie pc
 }                              // koniec IFa odczytujacego dane Z sim800
delay(10);
if(znak==':'){             // jesli odczytales dwukropek, to chyba leci identyfikacja numeru
 Serial.println("znalazlem numer telefonu!!!!");
 //digitalWrite(9, HIGH);    /// z radosci zapal diodke (pomaga debugowac)

for (i=1; i<12; i++){         //skoro "leci" numer dzwoniacego
 znak=(serialSIM800.read()); // odczytaj dokladnie 12 kolejnych znakow
 delay(10);                   // tak na wszelki wypadek
 numer=numer+znak;           // i zapisz cale 12 znakow od dwukropka do Stringu "numer"
}                             // koniec petli for

Serial.println(numer.substring(2));     // pomin dwukropek, cudzyslow i wyswietl tylko numer
lcd.print(numer.substring(2));          // rowniez na ekranie lcd
if (numer.substring(2)=="508508508"){   // jesli numer dzwoniacy jest taki sam jak podany
digitalWrite(9, HIGH);                  //  zaswiec diodke
serialSIM800.write("ATA\r");            // odbierz rozmowe aby potwierdzic identyfikacje
delay(500);                             // zagraj melodyjke
serialSIM800.write("AT+VTS=1\r");       // dzwiekami DTMF
delay(1000);
serialSIM800.write("AT+VTS=9\r");
delay(1000);
serialSIM800.write("ATH\r");            //zakoncz rozmowe
}

                           // sprzatamy po sobie:
lcd.setCursor(0,0);         // kursor wraca na poczatek w oczekiwaniu na nowy numer tel
digitalWrite(9, LOW);       // gasimy diodke
numer="";                   // kasujemy numer
}                           // koniec IFa  identyfikujacego numer telefonu

 
 if(Serial.available()){               // jesli cos jest pisane na klawiaturze
   serialSIM800.write(Serial.read());  // to przeslij to do sim800
 }                                     //koniec ifa sprawdzajacego czy cos jest pisane na klawiaturze

 }     //koniec loop


Załączone pliki Miniatury
       
 
Odpowiedź
#2
Thumbs Up 
Hejka!!! Propsy za ten projekcik, elektronicznie wygląda bardzo prosto ale za to świetnie go opisałeś, program z fajnymi pomocnymi komentarzami, łatwo zrozumieć co i jak. Z tego co piszesz jeszcze nie jesteś ekspertem i niektórych rzeczy  nie wiesz. Biblioteka software serial działa z użyciem przerwań a co za tym idzie jeśli jeszcze coś w tym czasie korzysta z przerwań mogą pojawić się błędy. To jest własnie minus w arduino że choć łatwo jest zrobić coś działającego to jednak bez znajomości dokładnego działania bibliotek czasem pojawiają się błedy których przyczynę trudno znaleźć. Jak dla mnie świetnie sobie poradziłeś z delayami. A co do odwróconych znaków zapytania one wynikają z błedów ale innych. Otóż komunikacja w porcie szeregowym ma swoją prędkość baudrate której muszą trzymać się obie strony, nadajnik i odbiornik, ponieważ nie ma linii taktującej. Sprawdziłem w necie i moduł sim800 ma jakiś domyślne baudrate , znalazłem info że domyślnie wynosi ono 115200. Ty dałeś 57600 więc o prawie połowę mniejsze a błędy zniknęły czyli komunikacja działa naprawde świetnie. Pozdrawiam serdecznie i dzięki za fajny opis projektu!
 
Odpowiedź
#3
Zdecydowanie jestem amatorem. Moją naukę programowania zakończyła mama, gdy odebrała mi zx spectrum za słabe oceny Smile. Ale tak przy okazji. Próbuje ten sam program uruchomić z wykorzystaniem zamiast (sim800) telefonu se t610. Działa... gdy polecenia są wysyłane z (TYLKO) programu. (z prędkością od 1200 do 57600, z delayami od 2 do 500) Jednak gdy wysyła polecenie z klawiatury PC, to se T610 przyjmuje, zastanawia się parę sekund - odpowiada error. Zawsze. z dzielnikiem napięcia (niepotrzebny) bez dzielnika, z różnymi prędkościami. terminal -> telefon =error. program -> telefon - zawsze sukces ( i to nawet lepiej niż sim800, bo nigdy (narazie 78 połączeń) nie wystąpił ani jeden błąd.) Ciekawe jaka to subtelna różnica, pomiędzy poleceniem wydanym z wnętrza programu, a wpisanym z klawiatury powoduje błędy? Męczę stare telefony, bo one jednak jakby nie patrzeć, stabilne są. Na niektórych nawet "białą listę" da się zrobić. Jeszcze jedno o software serial. jak już będzie na 100% działający program, czy mógłbym go "wgrać" do arduino przez hardware serial, ale z taką modyfikacją ze po odłączeniu kabla usb, hardware serial będzie "gadał" z modemem? Boję się sprawdzać, bo nie mam pewności, czy potem da się takie arduino ponownie przeprogramować
 
Odpowiedź
#4
Też jestem amatorem. W arduino ide masz przykładowe programy. Sprawdź je. Zobacz, sa tez takie które korzystają z komunikacji przez hardware serial. I korzystając z nich da się później przeprogramowac arduino. Problemy może tylko powodować korzystanie z hardware serial w arduino leonardo i innych z prockiem atmega 32u4 bo tam procek ma sprzętowa obsługę usb, ale tam też był sposób na obejście tego. Nie napisze jaki bo nie pamiętam teraz. Ale z arduino uno czy nano takich problemów nie ma.
 
Odpowiedź
#5
EPILOG

Witam. 
Tworzę alarm, z powiadomieniem gsm, z "rozbrajaniem" telefonem. Tak jak opisałem w pierwszym poście. Ale alarm, musi być niezawodny. najlepiej aby miał swoje zasilanie. 5v to za mało, bo syrena będzie za słaba. Tak więc 12V. w sam raz na 3 ogniwa 18650. Układ ładujący do ogniw - jedna płytka - nie ma problemu. Z 12V potrzebuję zrobić 5V, ale chyba lepiej step-down, niz 7805. to też kolejna płytka. załączanie syreny, to nie diodka, wiec potrzebny będzie przekaźnik. no i czujniki. tanie są, więc im więcej tym lepiej. ale jeśli mają działać, to też musza mieć zasilanie z akumulatora, więc trzeba im zrobić jakies podłączenia, piny. 10 czujników to... 30 pinów. a na koniec modem. Wykorzystałem go w innym projekcie gdzie jego małe wymiary były kluczowe, więc w alarmie będzie działał telefon erisccon t610. Działa dokładnie tak jak modem, a jest mniej kapryśny jeśli chodzi o zasilanie. 
Całość przestała być malutka, więc musiałem to poprzykręcać do kawałka plastiku, ale i tak jest 4 razy mniejsza niż stary alarm. Jednak gdy kolega zobaczył co stworzyłem, popatrzył, porkęcił głową i stwierdził, że jak mnie złapią z tym na mieście, to dostanę 10 lat odsiadki.


Załączone pliki Miniatury
   
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości