'########################################################################## '###### ###### '###### Handyschranken - System ###### '###### (C)Joachim Fossie Bär Reiter 2009 ###### '###### ###### '###### Last Change: 13.01.09 ###### '########################################################################## ' SMS Kommandos ' ADD nummer Nummer in Liste hinzufügen ' DEL nummer Nummer aus Liste löschen ' BLK nummer Nummer nur blocken ' FRE nummer Nummer freigeben ' MST nummer Nummer als Mastenummer eintragen ' NRM nummer Nummer als Mastenummer austragen 'EEPROM-Aufbau ' Byte 0 frei ' Byte 1-4 Pin des Handys ' Byte 5 0 damit der Pin als String eingelesen werden kann ' Byte 6 Anzahl der gespeicherten Nummer ' Jetzt jeder Eintrag 21 Bytes lang ' Byte 0 Flagbyte ' Bit 0 = 0 => Frei ' 1 => Gesperrt ' Bit 1 = 0 => Normaleintrag ' 1 => Löschflag ' Bit 7 = 0 => normale Nummer ' 1 => Masternummer ' Byte 1-21 Telefonnummern nullterminiert $regfile = "m32def.dat" $hwstack = 64 $swstack = 64 $framesize = 64 ' Benötigte Variablen und Konstanten Const Use_lcd = 1 'Const Quarz = 16000000 Const Quarz = 8000000 $crystal = Quarz $baud = 19200 Baud = 19200 Const Ticks = Int(65535000 / Quarz) ' ms pro Timerüberlauf ' Zeiten in ZehntelSekunden Const Zehntelsekundenwert = Int(100 / Ticks) Const Rel_ontime = 5 ' 0,5 Sekunden Einzeit für Relais Const Maxlocktime = 100 ' 10 Sekunden warten bis erneut reagiert wird Const Norm_timeout = 30 ' 3 Sekunden auf Antwort von Modem warten Const Long_timeout = 100 ' 10 Sekunden nach PIN zum Anmelden Const Sms_norm_timeout = 30 ' 3 Sekunden auf Antwort von Modem warten Const Sms_long_timeout = 100 ' 10 Sekunden nach PIN zum Anmelden Const Sms_checkwaittime = 600 ' 1 Minute bis SMS-Check Const Maxdisplaytime = 100 ' 10 Sekunden Anzeige auf LCD Const Max_errorcount = 5 ' Nach 5 Fehlern gibts nen Neustart Const Eeprom_pinpos = 1 Const Eeprom_maxnumberpos = 6 Const Eeprom_entrypos = 7 #if Use_lcd = 1 ' LCD-Definition $lib "lcd4busy.lib" 'define the used constants 'I used portA for testing Const _lcdport = Porta Const _lcdddr = Ddra Const _lcdin = Pina Const _lcd_e = 3 Const _lcd_rw = 2 Const _lcd_rs = 1 Config Lcd = 20 * 4 #endif Licht Alias Portb.0 ' BG-Licht von LCD Config Licht = Output Set Licht 'Sendekontakt Alias Portb.1 ' Relais für Sendekontakt Sendekontakt Alias Portd.5 ' Relais für Sendekontakt Config Sendekontakt = Output ' und als Ausgänge parametrieren Set Sendekontakt 'Handy_on Alias Portb.2 ' Kontakt für Handy Handy_on Alias Portd.6 ' Kontakt für Handy Config Handy_on = Output ' und als Ausgänge parametrieren Reset Handy_on 'Handy_power Alias Portb.3 ' Spannungsversorgung für Handy 'Config Handy_power = Output ' und als Ausgänge parametrieren 'Set Handy_power Led Alias Portb.3 ' ne LED für alles mögliche Config Led = Output Set Led ' ######################################################################### ' ###### SMS Variablen ###### ' ######################################################################### Dim Sms_rec_char As Byte ' Empfangenes Byte via serielle Dim Sms_rec_string As String * 141 ' Empfangsstring von Modem Dim Sms_rec_array(141) As Byte At Sms_rec_string Overlay ' und damit man es auch als Arra ansprechen kann Dim Sms_rec_stringlen As Integer ' Länge des Empfangsstring von Modem Dim Sms_text As String * 160 ' SMS hat max 160 Zeichen Dim Sms_text_array(160) As Byte At Sms_text Overlay ' und damit man es auch als Arra ansprechen kann Dim Sms_text_len As Integer ' Länge des Empfangsstring von Modem Dim Sms_statusbyte As Integer ' Statusbyte für alles mögliche Sms_rec_flag Alias Sms_statusbyte.0 ' ob was empfangen wurde Sms_rec_lock Alias Sms_statusbyte.1 'oder ob Empfang gesperrt ist Sms_waitfor_line Alias Sms_statusbyte.2 ' warte auf Text mit oder ohne LF Sms_pdudec_flag Alias Sms_statusbyte.3 ' beim Dekodieren benutzt Sms_nibble Alias Sms_statusbyte.4 ' gibt bei SMS-Empfang das Nibble an Sms_check Alias Sms_statusbyte.5 ' Zeit zum SMS-Check Sms_recflag Alias Sms_statusbyte.6 ' SMS empfangen und ausgewertet Sms_prgstep_flag Alias Sms_statusbyte.7 ' und ob ein Programmwechsel erfolgen soll Dim Sms_pdulen As Byte ' Daten aus PDU-Stream Dim Sms_pdutyp As Byte Dim Sms_pid As Byte Dim Sms_dcs As Byte Dim Sms_date As String * 14 ' Datum im Format "YYMMDDHHMMSSZZ" Dim Sms_date_array(14) As Byte At Sms_date Overlay ' Ddatum als Array Dim Sms_msglen As Byte ' Länge der dekodierten SMS Dim Sms_indexnr As Byte ' Speicherplätze der SMS im Handy Dim Sms_nummer As String * 16 Dim Sms_waitfor_ende As Byte ' wird für Waitfor benutzt Sms_waitfor_ok Alias Sms_waitfor_ende.0 Sms_waitfor_timeout Alias Sms_waitfor_ende.1 Dim Sms_temp As Byte ' Halt eine Tempvariable Dim Sms_temp1 As Integer ' Integertemp Dim Sms_count As Byte ' Zähler für Schleife Dim Sms_count1 As Integer ' Zähler für Schleife Dim Sms_count2 As Integer ' Zähler für Schleife Dim Sms_afrom As Byte ' von PDU-Dekoder benötigt Dim Sms_ato As Byte ' von PDU-Dekoder benötigt Dim Sms_zeichen As Word ' Auch für was anderes zu benutzen Dim Sms_timeout As Integer ' Wartezeit für Waitfor Dim Sms_locktime As Integer ' Sperrzeit wenn RING Dim Sms_prgstep As Byte ' Programmschritt bei Init und SMS-Empfang Dim Sms_errorcounter As Byte ' Fehlerzähler bei Init Dim Sms_anzread As Byte ' zu lesende Zeichen aus PDU-Stream Dim Sms_wait_string As String * 10 ' für Waitfor der Text auf den gewartet wird Dim Sms_checktime As Integer ' ######################################################################### ' ###### Sonstige Variablen ###### ' ######################################################################### Dim Zehntelsekunden_counter As Integer Dim Rec_string As String * 160 ' was normal über die serielle kommt Dim Prgstep As Byte Dim Relaistime As Integer Dim Locktime As Integer Dim Blinker As Byte Dim Rec_char As Byte Dim Temp As Byte Dim Temp1 As Byte Dim Count As Integer Dim Count1 As Integer Dim Maxnumber As Byte Dim Num_string As String * 16 At Sms_nummer Overlay ' Doppelbelegung Dim Tempstring As String * 16 At Sms_nummer Overlay ' Doppelbelegung Dim Tstring As String * 10 Dim Num_flag As Byte Dim Displaytime As Integer ' Anzege auf Display Dim Errorcounter As Byte Dim Statusbyte As Integer ' Statusbyte für alles mögliche Rec_flag Alias Statusbyte.0 ' ob was empfangen wurde Display_flag Alias Statusbyte.1 ' einmalige Anzeige Setrelais Alias Statusbyte.2 ' Ausgang setzen Master_flag Alias Statusbyte.3 ' Masterflag Found_flag Alias Statusbyte.4 Life_flag Alias Statusbyte.14 ' kann später weg, iss für LCD Life_toggle Alias Statusbyte.15 ' kann später weg, iss für LCD Config Serialin = Buffered , Size = 200 ' 200Byte Puffer für Serielle ' Timer initialisieren Config Timer1 = Timer , Prescale = 1 ' und starten Enable Timer1 On Timer1 Timerint ' Ints aktivieren Enable Interrupts ' Timer und seriell ' ######################################################################### ' ######################################################################### ' ######################################################################### Init: #if Use_lcd = 1 Cursor Off Set Licht Cls Lcd "SCHRANKENHANDY V0.2" Locate 2 , 1 Lcd "(C) Fossie 2009" For Count = 1 To 6 Toggle Licht Waitms 500 ' fürs Display warten Next Count #endif Gosub Init_handy ' Init OK, weiter gehts Sms_checktime = 300 ' schon nach 3Sek. mal sehen ob was im Handy ist #if Use_lcd = 1 Cls #endif ' ######################################################################### ' ######################################################################### ' ######################################################################### Main: Do If Display_flag = 1 Then ' wenn Zeit abgelaufen, dann Display löschen If Displaytime = 0 Then Locate 3 , 1 Lcd Spc(20) Locate 4 , 1 Lcd Spc(20) Reset Display_flag End If End If If Locktime = 0 Then ' Wenn Empfang nicht gesperrt ist, dann mal sehen #if Use_lcd = 1 Reset Life_toggle If Blinker > 10 Then Set Life_toggle ' jede Sekunde einmal If Life_toggle <> Life_flag Then Locate 1 , 1 If Life_toggle = 1 Then Lcd "WAIT FOR RING " Else Lcd "RING NOT DETECTED " End If Life_flag = Life_toggle End If #endif If Ischarwaiting() = 1 Then ' Wenn Zeichen im Puffer ist Rec_char = Waitkey() ' einlesen Select Case Rec_char ' was machen wir mit dem Zeichen Case 13 ' ignorieren Case 10 ' mal sehen If Rec_string <> "" Then Set Rec_flag ' wenn was da ist, dann weiter Case Else Rec_string = Rec_string + Chr(rec_char) ' ansonsten dabeimachen End Select End If Else ' solange der Empfang gesperrt ist #if Use_lcd = 1 Tempstring = Str(locktime) Locate 1 , 1 Lcd "Locked: " ; Format(tempstring , " 0.0") ; " Sek " #endif Gosub Flushbuf ' Zeichen ignorieren End If ' ###################################################################### ' ### normale Daten via serielle, sollte RING sein ' ###################################################################### If Rec_flag = 1 Then ' wenn was da ist Reset Rec_flag ' erst mal Empfang quitten If Left(rec_string , 7) = "+CLIP: " Then ' Wenns ein Anruf isf Locktime = Maxlocktime ' Empfang sperren Gosub Flushbuf ' und Puffer löschen Rec_string = Mid(rec_string , 8) ' dann das CLIP raus Temp = Instr(rec_string , ",") ' Komma suchen Decr Temp Rec_string = Left(rec_string , Temp) ' und die Nummer rausfiltern #if Use_lcd = 1 Locate 3 , 1 Temp = 17 - Len(rec_string) Lcd "Nr:" ; Rec_string ; Spc(temp) #endif Readeeprom Maxnumber , Eeprom_maxnumberpos ' Anzahl der gespeicherten Nummer Found_flag = 0 For Count = 1 To Maxnumber ' nun gehn wir sie mal durch Temp1 = Count - 1 Temp1 = Temp1 * 21 Temp1 = Temp1 + Eeprom_entrypos Readeeprom Num_flag , Temp1 ' lese aus EEPROM Incr Temp1 Readeeprom Num_string , Temp1 ' lese aus EEPROM If Num_flag.0 = 0 Then ' wenn Nummer freigeschaltet ist If Num_string = Rec_string Then ' und Nummer gleich Set Found_flag ' dann Flag Exit For ' und beenden die Suche End If End If Next Count Set Display_flag Displaytime = Maxdisplaytime If Found_flag = 1 Then #if Use_lcd = 1 Locate 4 , 1 Tempstring = Str(count) Lcd "Found at " ; Format(tempstring , " ") ; ", open " #endif Relaistime = Rel_ontime Else #if Use_lcd = 1 Locate 4 , 1 Lcd "No Entry found " #endif End If Wait 1 Reset Sms_waitfor_line Gosub Flushbuf Sms_timeout = Sms_norm_timeout Sms_wait_string = "OK" Print "AT+CHUP" Gosub Waitfor_sms End If Rec_string = "" End If ' ###################################################################### ' ###### SMS-Empfang checken ' ###################################################################### If Sms_checktime = 0 Then ' wenn Zeit zum Checken For Sms_indexnr = 1 To 10 ' Gehn wir die einzelnen Plätze durch #if Use_lcd = 1 Locate 2 , 1 Tempstring = Str(sms_indexnr) Lcd "Check SMS no " ; Format(tempstring , " ") ; " " #endif Set Sms_waitfor_line ' Auf Return + Text warten Sms_timeout = Sms_norm_timeout ' 3 Sekunden Wartezeit Sms_wait_string = "+CMGR:" ' Antwortstring Gosub Flushbuf ' Buffer löschen Print "AT+CMGR=" ; Sms_indexnr ' und Abfrage starten Gosub Waitfor_sms ' und auf Antwort warten If Sms_waitfor_ok = 1 Then ' wenn Empfang ok Errorcounter = 0 ' Fehlerzähler löschen Sms_rec_string = Mid(sms_rec_string , 11) ' dann mal sehen Sms_pdulen = Val(sms_rec_string) * 2 ' wieviel Zeichen zu lesen sind If Sms_pdulen > 0 Then ' wenn was zu lesen ist Gosub Get_sms ' auslesen und verarbeiten If Sms_recflag = 1 Then ' wenns gültige Daten sind #if Use_lcd = 1 Locate 3 , 1 Temp = 20 - Len(sms_nummer) Lcd "SMS:" ; Sms_nummer ; Spc(temp) Locate 4 , 1 Lcd Left(sms_text , 20) #endif Reset Master_flag Readeeprom Maxnumber , Eeprom_maxnumberpos ' Anzahl der gespeicherten Nummer For Count = 1 To Maxnumber ' nun gehn wir sie mal durch Temp1 = Count - 1 Temp1 = Temp1 * 21 Temp1 = Temp1 + Eeprom_entrypos Readeeprom Num_flag , Temp1 ' lese aus EEPROM Incr Temp1 Readeeprom Num_string , Temp1 ' lese aus EEPROM If Num_flag.7 = 1 Then ' wenn Masternummer If Num_string = Sms_nummer Then ' und Nummer gleich Set Master_flag Exit For End If End If Next Count If Master_flag = 1 Then ' wenns was vom Chef ist Temp = Instr(sms_text , " ") ' dann mal Space suchen Decr Temp Rec_string = Left(sms_text , Temp) ' den Befehl auslesen Temp = Temp + 2 Sms_rec_string = Mid(sms_text , Temp) ' und die Nummer Found_flag = 0 For Count = 1 To Len(sms_rec_string) Tstring = Mid(sms_rec_string , Count , 1) Temp = Asc(tstring) Select Case Temp Case 48 To 57 ' Zahl ok Case 43 ' Pluszeichen ok Case Else ' falsches Zeichen, abbrechen Exit For End Select Next Count Decr Count If Count > 12 And Count < 20 Then Sms_rec_string = Left(sms_rec_string , Count) Select Case Rec_string ' dann mal sehen was wir machen Case "ADD" For Count = 1 To Maxnumber ' nun gehn wir sie mal durch Temp1 = Count - 1 Temp1 = Temp1 * 21 Temp1 = Temp1 + Eeprom_entrypos Readeeprom Num_flag , Temp1 ' lese aus EEPROM If Num_flag.1 = 1 Then Exit For End If Next Count Temp1 = Count - 1 Temp1 = Temp1 * 21 Temp1 = Temp1 + Eeprom_entrypos Temp = 0 Writeeeprom Temp , Temp1 Incr Temp1 Writeeeprom Sms_rec_string , Temp1 If Count > Maxnumber Then Incr Maxnumber Writeeeprom Maxnumber , Eeprom_maxnumberpos ' Anzahl der gespeicherten Nummer End If #if Use_lcd = 1 Wait 1 Locate 3 , 1 Tempstring = Str(count) Lcd "ADD Number at pos " ; Format(tempstring , " ") Locate 4 , 1 Lcd Spc(20) #endif Case "DEL" For Count = 1 To Maxnumber ' nun gehn wir sie mal durch Temp1 = Count - 1 Temp1 = Temp1 * 21 Temp1 = Temp1 + Eeprom_entrypos Readeeprom Num_flag , Temp1 ' lese aus EEPROM Incr Temp1 Readeeprom Num_string , Temp1 ' lese aus EEPROM If Num_string = Sms_rec_string Then Decr Temp1 Set Num_flag.1 Writeeeprom Num_flag , Temp1 Exit For End If Next Count #if Use_lcd = 1 Wait 1 Locate 3 , 1 If Count > Maxnumber Then Lcd "No Entry found " Else Tempstring = Str(count) Lcd "DEL Number at pos " ; Format(tempstring , " ") End If Locate 4 , 1 Lcd Spc(20) #endif Case "BLK" For Count = 1 To Maxnumber ' nun gehn wir sie mal durch Temp1 = Count - 1 Temp1 = Temp1 * 21 Temp1 = Temp1 + Eeprom_entrypos Readeeprom Num_flag , Temp1 ' lese aus EEPROM Incr Temp1 Readeeprom Num_string , Temp1 ' lese aus EEPROM If Num_string = Sms_rec_string Then Decr Temp1 Set Num_flag.0 Writeeeprom Num_flag , Temp1 Exit For End If Next Count #if Use_lcd = 1 Wait 1 Locate 3 , 1 If Count > Maxnumber Then Lcd "No Entry found " Else Tempstring = Str(count) Lcd "BLK Number at pos " ; Format(tempstring , " ") End If Locate 4 , 1 Lcd Spc(20) #endif Case "FRE" For Count = 1 To Maxnumber ' nun gehn wir sie mal durch Temp1 = Count - 1 Temp1 = Temp1 * 21 Temp1 = Temp1 + Eeprom_entrypos Readeeprom Num_flag , Temp1 ' lese aus EEPROM Incr Temp1 Readeeprom Num_string , Temp1 ' lese aus EEPROM If Num_string = Sms_rec_string Then Decr Temp1 Reset Num_flag.0 Writeeeprom Num_flag , Temp1 Exit For End If Next Count #if Use_lcd = 1 Wait 1 Locate 3 , 1 If Count > Maxnumber Then Lcd "No Entry found " Else Tempstring = Str(count) Lcd "FRE Number at pos " ; Format(tempstring , " ") End If Locate 4 , 1 Lcd Spc(20) #endif Case "MST" For Count = 1 To Maxnumber ' nun gehn wir sie mal durch Temp1 = Count - 1 Temp1 = Temp1 * 21 Temp1 = Temp1 + Eeprom_entrypos Readeeprom Num_flag , Temp1 ' lese aus EEPROM Incr Temp1 Readeeprom Num_string , Temp1 ' lese aus EEPROM If Num_string = Sms_rec_string Then Decr Temp1 Set Num_flag.7 Writeeeprom Num_flag , Temp1 Exit For End If Next Count #if Use_lcd = 1 Wait 1 Locate 3 , 1 If Count > Maxnumber Then Lcd "No Entry found " Else Tempstring = Str(count) Lcd "MST Number at pos " ; Format(tempstring , " ") End If Locate 4 , 1 Lcd Spc(20) #endif Case "NRM" For Count = 1 To Maxnumber ' nun gehn wir sie mal durch Temp1 = Count - 1 Temp1 = Temp1 * 21 Temp1 = Temp1 + Eeprom_entrypos Readeeprom Num_flag , Temp1 ' lese aus EEPROM Incr Temp1 Readeeprom Num_string , Temp1 ' lese aus EEPROM If Num_string = Sms_rec_string Then Decr Temp1 Reset Num_flag.7 Writeeeprom Num_flag , Temp1 Exit For End If Next Count #if Use_lcd = 1 Wait 1 Locate 3 , 1 If Count > Maxnumber Then Lcd "No Entry found " Else Tempstring = Str(count) Lcd "NRM Number at pos " ; Format(tempstring , " ") End If Locate 4 , 1 Lcd Spc(20) #endif Case Else #if Use_lcd = 1 Wait 1 Locate 3 , 1 Lcd "Unknown Command " Locate 4 , 1 Lcd Spc(20) #endif End Select Else #if Use_lcd = 1 Wait 1 Locate 3 , 1 Lcd "Incorrect Number " Locate 4 , 1 Lcd "SMS ignored " #endif End If Set Display_flag Displaytime = Maxdisplaytime End If End If Gosub Flushbuf ' und Puffer löschen Reset Sms_waitfor_line ' Zeilenweises Lesen AUS Sms_wait_string = "OK" ' Antwortstring setzen Print "AT+CMGD=" ; Sms_indexnr ' und SMS löschen Gosub Waitfor_sms Gosub Flushbuf ' und Puffer löschen Sms_wait_string = "OK" ' Antwortstring setzen Print "AT+CMGD=" ; Sms_indexnr ' und SMS löschen Gosub Waitfor_sms End If Gosub Flushbuf ' und Puffer löschen Else If Sms_waitfor_timeout = 1 Then Incr Errorcounter If Errorcounter = Max_errorcount Then Goto Init End If End If Next Sms_indexnr ' und weiter mit der nächsten Sms_checktime = Sms_checkwaittime ' und von vorne warten Else #if Use_lcd = 1 Locate 2 , 1 Tempstring = Str(sms_checktime) Lcd "Check sms in " ; Format(tempstring , " 0.0") ; "Sek" #endif End If Loop End ' Programm '########################################################################## '###### SUB-ROUTINEN ####### '########################################################################## '########################################################################## Timerint: '### Millisekundentimer für Muster ### If Zehntelsekunden_counter > 0 Then Decr Zehntelsekunden_counter Else ' eine Sekunde vorbei If Sms_checktime > 0 Then Decr Sms_checktime If Sms_timeout > 0 Then Decr Sms_timeout ' wartezeit bei SMS-Waitfor ' If Timeout > 0 Then Decr Timeout ' ###################################################################### ' ### Relais überprüfen ' ###################################################################### If Relaistime > 0 Then Decr Relaistime Reset Sendekontakt ' Kontakt schliessen Else ' Wenn Zeit abgelaufen Set Sendekontakt ' Kontakt öffnen End If If Displaytime > 0 Then Decr Displaytime If Locktime > 0 Then Decr Locktime If Blinker > 0 Then Decr Blinker Else Blinker = 20 Zehntelsekunden_counter = Zehntelsekundenwert ' Zähler neu setzen End If Return '######################################################################### '###### Subroutinen für SMS-Empfang und Dekodierung $include "smsinc.bas" $eeprom Data 0 , "1234" Data 3 Data &B10000000 , "+491511234567", 0 , 0 , 0 , 0 , 0 , 0 Data &B10000000 , "+491512345678" , 0 , 0 , 0 , 0 , 0 , 0 Data &B00000000 , "+491513456789" , 0 , 0 , 0 , 0 , 0 , 0