Seite 1 von 1

Attiny sendet Alarm-SMS

Verfasst: Sa 19. Dez 2015, 19:02
von Heinrichs
In dem Artikel SMS verschicken mit dem SIM800L-Modul habe ich dargestellt, wie man mithilfe eines Terminals eine SMS über das SIM800L versenden kann. Nun möchte ich hier zeigen, wie eine SMS von unserem Attiny verschickt werden kann. Dies kann man z. B. ausnutzen, um sich eine Alarm-SMS zukommen zu lassen, wenn z. B. eine Bewegung registriert wird, vgl. auch meinen Beitrag zum PIR-Bewegungsmelder. Im Folgenden soll der der Alarm der Einfachheit halber durch Betätigen des Tasters Ta0 (an PortD.2) ausgelöst werden. Es dürfte keine Probleme bereiten, den Alarm durch andere Signale auszulösen.

Es ist nicht schwierig, den Attiny die benötigten AT-Commands (vgl. SMS verschicken mit dem SIM800L-Modul) per print-Befehl an das SIM800L-Modul schicken zu lassen. Hier gilt es lediglich zu beachten, dass das SIM800L-Modul am Ende des Befehls lediglich ein CR erwartet; der BASCOM-print-Befehl schließt aber mit einem CR und LF ab. Mit einem Semikolon können diese beiden Steuerzeichen aber unterdrückt werden; natürlich muss dann das einzelne CR "per Hand" gesendet werden. Der AT-Command sieht dann z. B. so aus:

print "AT"; chr(13);

Etwas schwieriger fällt die Aufgabe, die vom SIM800L gegebenen Antworten zu analysieren. Diese Analysen sind erforderlich, weil sie zeigen, wann und ob der SIM800L einen Befehl erfolgreich ausgeführt hat. Dazu soll der Attiny die Antwort nach einem signifikanten Suchwort untersuchen. Wir benutzen dafür die Prozedur warte_auf_suchwort (vgl. Programm-Code unten). Diese Prozedur wartet lediglich darauf, dass die Variable "gefunden" den Wert 1 erhält. Die eigentliche Suche findet in der Interrupt-Routine "Onrxd" statt. (Da die Antwort auch CR-Zeichen enthält, kann man nicht einfach mit dem input-Befehl arbeiten!). Um auch die jeweils zuletzt empfangenen Zeichen anzeigen lassen zu können, arbeiten wir mit einem 16 Zeichen langen Ringpuffer.

Vorbereitung der Antwort-Analyse, AT-Command und Analyse sehen z.B. so aus:

Suchwort = "OK"
Call Init_warte
Print "AT" ; Chr(13);
Call Warte_auf_suchwort


Die restlichen Einzelheiten kann man den Kommentaren im folgenden Programm-Code entnehmen:

Code: Alles auswählen

' Datei für Attiny-Platine von E. Eube, G. Heinrichs und U. Ihlefeldt
' Wenn Ta0 betätigt wird, schickt der Mikrocontroller über das SIM800L-Modul
' eine SMS ans Handy. Statt des Tasters kann auch ein anderer Sensor die SMS
' auslösen.
'
' SIM800L und Display anschließen
' Achtung: Externe Spannungsversorgung mit 4,0 V und min. 2,0 A!!!!!!!!!!!!!!!!!
'
' Wenn "connect?" im Display erscheint und nach einiger Zeit der Blinkrhythmus
' noch immer knapp 1 s (und nicht 3 s) ist, dann Platine ausschalten und alles
' neu starten.
'
' Die meisten Display-Texte dienen nur zur Ablaufkontrolle und können
' bei Bedarf entfernt werden.
'
'----------------------------------------------------------------------------

$regfile = "attiny2313.dat"                                 'Attiny2313
$crystal = 4000000                                          '4 MHz
$baud = 9600

'**********************************************************
'******************* Deklarationen ************************

Dim Answer As String * 16
Dim Answer_byte(17) As Byte At Answer Overlay               'Ringpuffer für Answer (wegen Speicherknappheit)
Dim Answer_index As Byte
Dim Suchwort As String * 4                                  'Suchwort max. 4 Zeichen
Dim Suchwort_byte(5) As Byte At Suchwort Overlay
Dim Suchwort_index As Byte
Dim Suchwort_laenge1 As Byte
Dim Suchende As Word
Dim E As Byte
Dim I As Byte
Dim J As Byte
Dim N As Byte
Dim Gefunden As Byte

Declare Sub Warte_auf_suchwort
Declare Sub Zeige_antwort                                   'zeigt den Ringpuffer an
Declare Sub Init_warte                                      'initialisiert die Parameter für Warte_auf_suchwort

'****************** Initialisierung ***********************

Ddrb = &B11111111                                           'Port B als Ausgangsport
Ddrd = &B01110000                                           'D4, D5, D6 als Ausgang; Rest als Eingang
Portd = &B10001111                                          'Eingänge auf high legen
Waitms 50                                                   'warte bis Kondensator bei Ta0 geladen

Config Lcd = 16 * 2                                         'LCD konfigurieren
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.6
Cursor Off

On Urxc Onrxd
Enable Urxc
Enable Interrupts

'**********************************************************
'******************** Hauptprogramm ***********************

Cls
Lcd "warte..."
Wait 5                                                      'Jetzt sollte die LED am SIM800L blinken (jede 900 ms)
Cls
Lcd "Init..."
Wait 1

'Initialisieren, Synchronisieren
Suchwort = "OK"
Call Init_warte
Print "AT" ; Chr(13);                                       'nur CR , kein LF
Call Warte_auf_suchwort
Wait 1

Cls
Lcd "SIM800L"
Lowerline
Lcd "found"
Wait 2

'PIN eingeben und verbinden
Suchwort = "SMS"
Call Init_warte
Print "AT+CPIN=" ; Chr(34) ; "xxxx" ; Chr(34) ; Chr(13);   'xxxx = eigene PIN
Call Warte_auf_suchwort

Call Zeige_antwort                                          'zu Testzwecken, kann zuammen mit dem folgenden Befehl entfernt werden
Do : Loop Until Pind.2 = 0                                  'warten bis Ta0 gedrückt

Cls
Lcd "connect?"                                              's. Kommentar am Anfang des Codes
Wait 5                                                      'jetzt sollte die LED jede 3000 ms blinken

'SMS-Mode einstellen
Suchwort = "OK"
Call Init_warte
Print "AT+CMGF=1" ; Chr(13);
Call Warte_auf_suchwort
Cls
Lcd "SMS-Mode"
Wait 1

'Parameter setzen
Suchwort = "OK"
Call Init_warte
Print "AT+CSMP=17,167,0,0" ; Chr(13);
Call Warte_auf_suchwort
Cls
Lcd "ParamSet"
Wait 1

'Warten auf Alarmknopf; hier kann auch auf andere Ereignisse gewartet werden
Cls
Lcd " Ta0 ->"
Lowerline
Lcd "ALARM..."
Do : Loop Until Pind.2 = 0

'Telefonnumer angeben und ...
Suchwort = ">"
Call Init_warte
Print "AT+CMGS=" ; Chr(34) ; "01774738820" ; Chr(34) ; Chr(13);
Call Warte_auf_suchwort

'... Botschaft senden
Suchwort = "OK"
Call Init_warte
Print "ALARM: Ta0 ist betätigt worden" ; Chr(26) ; Chr(13) ;       'SMS -text mit Ctrl-Z abschließen
Call Warte_auf_suchwort

Cls
Lcd "ALARM"
Lowerline
Lcd "...done"
End


'**********************************************************
'******************* Unterprogramme ***********************

Sub Init_warte
  Gefunden = 0
  Suchwort_index = 1
  Answer_index = 0
  For I = 1 To 17
    Answer_byte(i) = 0
  Next I
  Suchwort_laenge1 = Len(suchwort)
  Suchwort_laenge1 = Suchwort_laenge1 + 1
End Sub

Sub Warte_auf_suchwort
  Do
  Loop Until Gefunden = 1                                   'hier ggf. auch Timeout implementieren
End Sub

Sub Zeige_antwort                                           'zu Testzwecken; zeigt den aktuellen Inhalt des Ringpuffers an
  Cls
  For I = 1 To 16
    J = I + 15
    If J > 16 Then J = J - 16
    N = Answer_byte(j)
    Lcd Chr(n)
    If I = 8 Then Lowerline
  Next I
End Sub


'**********************************************************
'******************Interruptroutinen***********************

Onrxd:                                                      'über RxD empfangene Zeichen im Ringpuffer ablegen und mit Suchwort vergleichen
  E = Udr
  If E > 13 Then                                            'CR und NL nicht berücksichtigen
  Incr Answer_index
  Answer_byte(answer_index) = E
  If Answer_index = 16 Then Answer_index = 0                'An den Anfang des Ringregisters
  If E = Suchwort_byte(suchwort_index) Then
    Incr Suchwort_index
    If Suchwort_index = Suchwort_laenge1 Then
      Gefunden = 1
    End If
  Else
    Suchwort_index = 1
    If E = Suchwort_byte(suchwort_index) Then
      Incr Suchwort_index
    End If
  End If
 End If
Return

'**********************************************************
Das Programm kontrolliert nur nach, ob die Antworten des SIM800L jeweils ein Weiterarbeiten zulassen; dies wird auch durch kurze Meldungen auf einem LCD dokumentiert (Wer das Programm entschlacken möchte, kann diese Meldungen auf dem LCD beseitigen.). Das Programm erkennt keine Fehlermeldungen; um auch solche zu berücksichtigen, bietet es sich an, bei der Prozedur warte_auf_suchwort ein Timeout zu implementieren.

Auch wird - nach der Anmeldung im Handy-Netz - nicht mehr weiter kontrolliert, ob die Verbindung weiterhin besteht.