Armins AVR-Buch - GSM_Modul_TC35

⇑GSM_Modul_TC35


(armin77, 02.01.2013, 17:48:28)

Oft willl man in seinen Projekten oder Basteleien, etwas mit dem
Handy schalten. Das GSM Modul TC35 von Siemens ist ideal dafür.
Es wird über einen Max232 an den ATMEGA 8 angeschlossen.

Bild gsm.jpg

Habe die beiden MAX232 mit Pfeilen markiert.
RX und TX müssen gekreuzt vom AVR zum GSM-Modul angeschlossen werden.

Bild gsm2.gif

Vor Beginn des eigentlichen Programms muß der AVR das GSM-Modul
resetten. (siehe Bild)


Hier zwei Universal-Code`s von Andrew:

$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 100
$swstack = 100
$framesize = 100
$baud = 19200


Config Adc = Single , Prescaler = Auto , Reference = AVCC
Start Adc

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 20 * 4
Cls
Cursor Off

Config Serialin = Buffered , Size = 160 , Bytematch = 13
Config Serialout = Buffered , Size = 160

config PORTB.0 = output ' zum GSM-IGT Pin / GSM-RESET auslöser
GSM_Reset alias portb.0


dim GSM_Daten As String * 160
dim GSM_Text as string * 200
dim ADC_Wert1 as word
dim ADC_Wert2 as word
dim ADC_Wert3 as word
dim ADC_Wert4 as word
dim ADC_Wert1_merken as word
dim ADC_Wert2_merken as word
dim ADC_Wert3_merken as word
dim ADC_Wert4_merken as word
dim ADC1_gesendet as byte
dim ADC2_gesendet as byte
dim ADC3_gesendet as byte
dim ADC4_gesendet as byte
dim ADC1_Alarm as byte
dim ADC2_Alarm as byte
dim ADC3_Alarm as byte
dim ADC4_Alarm as byte
dim Timeout as long
dim Zeile as Byte


Declare Sub init()
Declare Sub Wait_of_OK()
Declare Sub Serial0charmatch()
Declare Sub Conf_GSM()
Declare Sub Lokal_Echo_Off()
Declare Sub Pineingabe()
Declare Sub SMS_Loeschen()
Declare Sub Einstellungen()
Declare Sub Textmodus()
Declare Sub ADC_Anzeige()
Declare Sub SMS_Meldung()
Declare Sub Sende_SMS()
Declare Sub Pruefe_ADC()
Declare Sub ADC_Messung()
Declare Sub Pruefe_Senden()

waitms 2000
Enable Interrupts
call init
call Conf_GSM
call ADC_Anzeige


do

         call ADC_Messung
         call Pruefe_ADC
         call Pruefe_Senden

                  ' ~~~ Überprüfen ob SMS angekommen ist ~~~~
         if instr(1 , GSM_Daten , "+CMTI:") > 0 then
                  call SMS_Meldung
         endif

loop
end


' ########## Subroutinen ###########
Sub init()

         Deflcdchar 0 , 32 , 32 , 32 , 31 , 16 , 16 , 16 , 16 ' LO
         Deflcdchar 1 , 32 , 32 , 32 , 31 , 1 , 1 , 1 , 1 ' RO
         Deflcdchar 2 , 16 , 16 , 16 , 16 , 16 , 16 , 31 , 32 ' LU
         Deflcdchar 3 , 1 , 1 , 1 , 1 , 1 , 1 , 31 , 32 ' RU
         Deflcdchar 4 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 ' LL
         Deflcdchar 5 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ' RR
         cls

         locate 1 , 1
         lcd chr(0) ; "------------------" ; chr(1)
         locate 2 , 5
         lcd "GSM - Modul"
         locate 2 , 1 : lcd chr(4)
         locate 2 , 20 : lcd chr(5)
         locate 3 , 8
         lcd "TC35"
         locate 3 , 1 : lcd chr(4)
         locate 3 , 20 : lcd chr(5)
         locate 4 , 1
         lcd chr(2) ; "__________________" ; chr(3)

         GSM_Reset = 1
         waitms 2000
         GSM_Reset = 0
         wait 3
end sub


Sub Serial0charmatch()
         Input GSM_Daten Noecho
end Sub



Sub Conf_GSM()
      cls
      call Lokal_Echo_Off
      call Pineingabe
      call SMS_Loeschen
      call Einstellungen
      call Textmodus
      cls
end sub



Sub Lokal_Echo_Off()
         GSM_Daten = ""
         Zeile = 1
         locate 1 , 1
         lcd "lokal Echo aus ....."
         waitms 2000
         print "ATE0"

         call Wait_of_OK

         locate 1 , 15
         lcd " OK"
         waitms 2000
end sub



Sub Pineingabe()
         GSM_Daten = ""
         Zeile = 2
         locate 2 , 1
         lcd "Pineingabe ........ "
         print "AT+CPIN=1111"' PIN anpassen ;-)

         call Wait_of_OK

         locate 2 , 11
         lcd " OK"
         waitms 2000
end sub


Sub SMS_Loeschen()
         GSM_Daten = ""
         Zeile = 3
         locate 3 , 1
         lcd "SMS leeren ........."
         print "AT+CMGD=4"

         call Wait_of_OK

         locate 3 , 11
         lcd " OK"
         waitms 2000
end sub

Sub Einstellungen()
         GSM_Daten = ""
         Zeile = 4
         locate 4 , 1
         lcd "Voreinstellungen ..."
         print "AT+CNMI=3,1,2,2,1"

         call Wait_of_OK

         locate 4 , 17
         lcd " OK"
         waitms 2000
end sub


Sub Textmodus()
         GSM_Daten = ""
         Zeile = 4
         locate 4 , 1
         lcd "SMS Klartext an ...."
         print "AT+CNMI=3,1,2,2,1"

         call Wait_of_OK

         locate 4 , 17
         lcd " OK"
         waitms 2000
end sub


Sub Wait_of_OK()
         Timeout = 0
         do
               if instr(1 , GSM_Daten , "OK") > 0 then
                        exit do
               endif
               if instr(1 , GSM_Daten , "ERROR") > 0 then
                        locate 1 , 16
                        lcd "ERROR"
                        end
               endif
               incr Timeout
         loop until Timeout = 600000
         if Timeout = 600000 then
                  locate Zeile , 13
                  lcd " TIMEOUT"
                  end
         endif
end sub


Sub ADC_Anzeige()
            Locate 1 , 1
            lcd "ADC-Wert 1 : "
            locate 1 , 17
            lcd ADC_Wert1

            Locate 2 , 1
            lcd "ADC-Wert 2 : "
            locate 2 , 17
            lcd ADC_Wert2

            Locate 3 , 1
            lcd "ADC-Wert 3 : "
            locate 3 , 17
            lcd ADC_Wert3

            Locate 4 , 1
            lcd "ADC-Wert 4 : "
            locate 4 , 17
            lcd ADC_Wert4
end sub


Sub SMS_Meldung()
         GSM_Daten = ""
         cls
         locate 1 , 1
         lcd chr(0) ; "------------------" ; chr(1)
         locate 2 , 5
         locate 2 , 1
         lcd " SMS eingegangen ! "
         locate 2 , 1 : lcd chr(4)
         locate 2 , 20 : lcd chr(5)
         locate 3 , 1 : lcd chr(4)
         locate 3 , 20 : lcd chr(5)
         locate 4 , 1
         lcd chr(2) ; "__________________" ; chr(3)
         waitms 5000
         call ADC_Anzeige
end sub


Sub Sende_SMS()
         GSM_Daten = ""
         GSM_Text = ""
         cls

         locate 1 , 1
         lcd chr(0) ; "------------------" ; chr(1)
         locate 2 , 1
         lcd " sende SMS .... "
         locate 2 , 1 : lcd chr(4)
         locate 2 , 20 : lcd chr(5)
         locate 3 , 1 : lcd chr(4)
         locate 3 , 20 : lcd chr(5)
         locate 4 , 1
         lcd chr(2) ; "__________________" ; chr(3)

         GSM_Text = "Wert1: " + str(ADC_Wert1) + chr(13) + chr(10)
         GSM_Text = GSM_Text + "Wert2: " + str(ADC_Wert2) + chr(13) + chr(10)
         GSM_Text = GSM_Text + "Wert3: " + str(ADC_Wert3) + chr(13) + chr(10)
         GSM_Text = GSM_Text + "Wert4: " + str(ADC_Wert4)

         print "AT+CMGS=01729876543 "' Nummer anpassen ;-)
         print GSM_Text;
         print chr(26);
         waitms 3000

         call ADC_Anzeige
end sub


Sub ADC_Messung()
         ADC_Wert1 = getadc(0)
         if ADC_Wert1 <> ADC_Wert1_merken then
                  ADC_Wert1_merken = ADC_Wert1
                  locate 1 , 17
                  lcd ADC_Wert1
         endif
         ADC_Wert2 = getadc(1)
         if ADC_Wert2 <> ADC_Wert2_merken then
                  ADC_Wert2_merken = ADC_Wert2
                  locate 2 , 17
                  lcd ADC_Wert2
         endif
         ADC_Wert3 = getadc(2)
         if ADC_Wert3 <> ADC_Wert3_merken then
                  ADC_Wert3_merken = ADC_Wert3
                  locate 3 , 17
                  lcd ADC_Wert3
         endif
         ADC_Wert4 = getadc(3)
         if ADC_Wert4 <> ADC_Wert4_merken then
                  ADC_Wert4_merken = ADC_Wert4
                  locate 4 , 17
                  lcd ADC_Wert4
         endif
end sub



Sub Pruefe_ADC()

         if ADC_Wert1 < 400 then
                  ADC1_Alarm = 1
         endif
         if ADC_Wert1 > 500 then
                  ADC1_Alarm = 1
         endif
         if ADC_Wert2 < 400 then
                  ADC2_Alarm = 1
         endif
         if ADC_Wert2 > 500 then
                  ADC2_Alarm = 1
         endif
         if ADC_Wert3 < 400 then
                  ADC3_Alarm = 1
         endif
         if ADC_Wert3 > 500 then
                  ADC3_Alarm = 1
         endif
         if ADC_Wert4 < 400 then
                  ADC4_Alarm = 1
         endif
         if ADC_Wert4 > 500 then
                  ADC4_Alarm = 1
         endif

         if ADC_Wert1 > 400 and ADC_Wert1 < 500 then
                  ADC1_Alarm = 0
                  ADC1_gesendet = 0
         endif
         if ADC_Wert2 > 400 and ADC_Wert2 < 500 then
                  ADC2_Alarm = 0
                  ADC2_gesendet = 0
         endif
         if ADC_Wert3 > 400 and ADC_Wert3 < 500 then
                  ADC3_Alarm = 0
                  ADC3_gesendet = 0
         endif
         if ADC_Wert4 > 400 and ADC_Wert4 < 500 then
                  ADC4_Alarm = 0
                  ADC4_gesendet = 0
         endif

end sub


Sub Pruefe_Senden()
         if ADC1_Alarm = 1 and ADC1_gesendet = 0 then
                  ADC1_Alarm = 0
                  ADC1_gesendet = 1
                  call Sende_SMS
         endif
         if ADC2_Alarm = 1 and ADC2_gesendet = 0 then
                  ADC2_Alarm = 0
                  ADC2_gesendet = 1
                  call Sende_SMS
         endif
         if ADC3_Alarm = 1 and ADC3_gesendet = 0 then
                  ADC3_Alarm = 0
                  ADC3_gesendet = 1
                  call Sende_SMS
         endif
         if ADC4_Alarm = 1 and ADC4_gesendet = 0 then
                  ADC4_Alarm = 0
                  ADC4_gesendet = 1
                  call Sende_SMS
         endif
end sub


Hier mal ein wenig geändert , so das zum Einen die Signalstärke ausgewertet wird und zum Anderen eine ankommende
SMS auf dem Display angezeigt wird:

$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 60
$swstack = 60
$framesize = 60
$baud = 19200


Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 20 * 4
Cls
Cursor Off

Config Serialin = Buffered , Size = 160 , Bytematch = 13
Config Serialout = Buffered , Size = 160

config PORTB.0 = output ' GSM-IGT / GSM-RESET
GSM_Reset alias portb.0


dim GSM_Daten As String * 160
dim GSM_Text as string * 160
dim Text as string * 160
dim Timeout as long
dim Zeile as Byte
dim Pos1 as byte
dim Pos2 as byte
dim Signalstaerke as byte
dim Signal as single
dim Signalzaehler as word
dim SMS_Nummer as byte


Declare Sub init()
Declare Sub Wait_of_OK()
Declare Sub Serial0charmatch()
Declare Sub Conf_GSM()
Declare Sub SMS_Meldung()
Declare Sub Sende_SMS()
Declare Sub SMS_Auswerten()


waitms 2000
Enable Interrupts
call init
call Conf_GSM


do

                  ' ~~~ Überprüfen ob SMS angekommen ist ~~~~
         if instr(1 , GSM_Daten , "+CMTI:") > 0 then
                  call SMS_Meldung
         endif

         ' ~~~~ im Interval wird die Signalstärke abgefragt ~~~~
         incr Signalzaehler
         if Signalzaehler >= 32000 then
                  gosub Show_Signalstaerke
                  Signalzaehler = 0
         endif

loop
end


' ########## Subroutinen ###########
Sub init()

         Deflcdchar 0 , 32 , 32 , 32 , 31 , 16 , 16 , 16 , 16 ' LO
         Deflcdchar 1 , 32 , 32 , 32 , 31 , 1 , 1 , 1 , 1 ' RO
         Deflcdchar 2 , 16 , 16 , 16 , 16 , 16 , 16 , 31 , 32 ' LU
         Deflcdchar 3 , 1 , 1 , 1 , 1 , 1 , 1 , 31 , 32 ' RU
         Deflcdchar 4 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 ' LL
         Deflcdchar 5 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ' RR
         cls

         locate 1 , 1
         lcd chr(0) ; "------------------" ; chr(1)
         locate 2 , 5
         lcd "GSM - Modul"
         locate 2 , 1 : lcd chr(4)
         locate 2 , 20 : lcd chr(5)
         locate 3 , 8
         lcd "TC35"
         locate 3 , 1 : lcd chr(4)
         locate 3 , 20 : lcd chr(5)
         locate 4 , 1
         lcd chr(2) ; "__________________" ; chr(3)

         GSM_Reset = 1
         waitms 2000
         GSM_Reset = 0
         wait 3
end sub


Sub Serial0charmatch()
         Input GSM_Daten Noecho
end Sub



Sub Conf_GSM()
         cls
         GSM_Daten = ""
         Zeile = 1
         locate 1 , 1 : lcd "lokal Echo aus ....."
         print "ATE0"
         call Wait_of_OK
         locate 1 , 15 : lcd " OK"
         waitms 500
         '-----------------------------------------
         GSM_Daten = ""
         Zeile = 2
         locate 2 , 1 : lcd "Pineingabe ........ "
         print "AT+CPIN=1111"' PIN anpassen
         call Wait_of_OK
         locate 2 , 11 : lcd " OK"
         waitms 500
         '-----------------------------------------
         GSM_Daten = ""
         Zeile = 3
         locate 3 , 1 : lcd "SMS leeren ........."
         print "AT+CMGD=4"
         call Wait_of_OK
         locate 3 , 11 : lcd " OK"
         waitms 500
         '-----------------------------------------
         GSM_Daten = ""
         Zeile = 4
         locate 4 , 1 : lcd "Voreinstellungen ..."
         print "AT+CNMI=3,1,2,2,1"
         call Wait_of_OK
         locate 4 , 17 : lcd " OK"
         waitms 500
         '-----------------------------------------
         GSM_Daten = ""
         Zeile = 4
         locate 4 , 1 : lcd "SMS Klartext an ...."
         print "AT+CMGF=1"
         call Wait_of_OK
         locate 4 , 17 : lcd " OK"
         waitms 2000
         GSM_Daten = ""
         cls
end sub


Sub Wait_of_OK()
         Timeout = 0
         do
               if instr(1 , GSM_Daten , "OK") > 0 then
                        exit do
               endif
               if instr(1 , GSM_Daten , "ERROR") > 0 then
                        locate 1 , 16
                        lcd "ERROR"
                        end
               endif
               incr Timeout
         loop until Timeout = 600000
         if Timeout = 600000 then
                  locate Zeile , 13
                  lcd " TIMEOUT"
                  end
         endif
end sub


Sub SMS_Meldung()
         cls
         locate 1 , 1
         lcd chr(0) ; "------------------" ; chr(1)
         locate 2 , 5
         locate 2 , 1
         lcd " SMS eingegangen ! "
         locate 2 , 1 : lcd chr(4)
         locate 2 , 20 : lcd chr(5)
         locate 3 , 1 : lcd chr(4)
         locate 3 , 20 : lcd chr(5)
         locate 4 , 1
         lcd chr(2) ; "__________________" ; chr(3)
         if instr(1 , GSM_Daten , "+CMTI:") > 0 then
                  Pos1 = instr(1 , GSM_Daten , "SM")
                  Pos1 = Pos1 + 4
                  GSM_Text = mid(GSM_Daten , Pos1 , 2)
                  SMS_Nummer = val(GSM_Text)
         endif
         GSM_Daten = ""
         waitms 3000
         call SMS_Auswerten
         cls
end sub


Sub Sende_SMS()
         GSM_Daten = ""
         GSM_Text = ""

         locate 1 , 1
         lcd chr(0) ; "------------------" ; chr(1)
         locate 2 , 1
         lcd " sende SMS .... "
         locate 2 , 1 : lcd chr(4)
         locate 2 , 20 : lcd chr(5)
         locate 3 , 1 : lcd chr(4)
         locate 3 , 20 : lcd chr(5)
         locate 4 , 1
         lcd chr(2) ; "__________________" ; chr(3)

         print "AT+CMGS=01729876543"' Nummer anpassen :-)
         print GSM_Text;
         print chr(26);
         waitms 3000
         cls
end sub


Show_Signalstaerke:
         ' falls gerade eine Meldung kommt
         if len(GSM_Daten) > 0 then
                  return
         endif

         GSM_Daten = ""
         GSM_Text = ""
         locate 2 , 1
         lcd "Signalstaerke = "
         locate 3 , 1
         lcd " "
         print "AT+CSQ"
         do
               if instr(1 , GSM_Daten , "+CSQ:") > 0 then
                        GSM_Text = GSM_Daten
                        exit do
               endif
         loop

         Pos1 = instr(1 , GSM_Text , "+CSQ:")
         if Pos1 > 0 then
                  Pos1 = Pos1 + 6
                  GSM_Text = mid(GSM_Text , Pos1 , 2)
                  Signal = val(GSM_Text)
                  Signal = Signal * 100
                  Signal = Signal / 32
                  Signalstaerke = Signal
                  locate 2 , 17
                  lcd Signalstaerke ; " % "
         endif
Return


Sub SMS_Auswerten()
      GSM_Daten = ""
      cls
      GSM_Text = str(SMS_Nummer)
      print "AT+CMGR=" ; GSM_Text
      GSM_Text = ""
      Text = ""
      do
            if len(GSM_Daten) > 0 then
                     Text = Text + GSM_Daten
                     GSM_Daten = ""
            endif
            if instr(1 , Text , "OK") > 0 then
                     exit do
            endif
      loop

      ' Anrufer-Nummer ermitteln
      Pos1 = instr(1 , Text , "+49")
      if Pos1 > 0 then
               Pos2 = instr(Pos1 , Text , ",")
               if Pos2 > 0 then
                        Pos2 = Pos2 - 1
                        Pos1 = Pos1 + 3
                        Pos2 = Pos2 - Pos1
                        GSM_Text = mid(Text , Pos1 , Pos2)
                        GSM_Text = "0" + GSM_Text
                        cls
                        locate 1 , 1
                        lcd "SMS von: " ; GSM_Text
               endif
      endif

      ' SMS Text ermitteln
      Pos1 = instr(1 , Text , "+04")
      Pos1 = Pos1 + 5
      Pos2 = Len(Text)
      Pos2 = Pos2 - 8
      Pos2 = Pos2 - Pos1
      GSM_Text = mid(Text , Pos1 , Pos2)
      locate 3 , 1
      lcd GSM_Text

      waitms 8000
end sub