Elektroda.pl
Elektroda.pl
X
Servizza
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Identyfikacja numeru telefonu, arduino-sim800, alarm, odczyt softwareserial

Tomasz_72 24 Lut 2018 20:54 732 0
  • #1 24 Lut 2018 20:54
    Tomasz_72
    Poziom 10  

    ***To jest gotowy działający układ. Można z niego korzystać we własnych projektach. Jeśli admin ma ochotę - może go przenieść. ***

    Arduino z sim800. Identyfikacja numeru telefonu osoby dzwoniącej. odczyt danych z softwareserial

    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. Arduino to potężny system, więc będzie również obsługiwał licznik wejść, powiadomienie o wejściu w godzinach pracy firmy a może jeszcze coś więcej. Dane mają być przedstawiane na wyświetlaczu, więc wskazana jest oszczędność pinów i w miarę możliwości jak najmniejsze zapotrzebowanie na pamięć.

    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 program 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ę żonglować 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.

    załączniki:
    program do arduino w którym każda linijka ma komentarz
    schemat połączenia arduino z sim800. minimalny
    fotka zmontowanego układu

    Code:

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

    0 0
  • Servizza