Differences

This shows you the differences between two versions of the page.

Link to this comparison view

atmel:smsrelaycontrollersource [2009/11/27 17:53] (current)
Line 1: Line 1:
 +<code vb>
 +'​********************************************************************
 +'* SMS Message Relay controller
 +'* uP:                AT89S2313
 +'* Language: ​         BASCOM-AVR 1.11.8.7
 +'* Originally posted: 2005.Feb.27
 +'* Last updated: ​     2007.Nov.19
 +'* Version: ​          V1.10
 +'​********************************************************************
 +$regfile = "​2313def.dat"​
 +$crystal = 8000000
 +$baud = 19200
 +
 +Const Dlcd = 0
 +
 +Dim Rs232_exit As Byte
 +Dim Read_ok As Bit
 +Dim Data_ok As Bit
 +Dim Sync_ok As Bit
 +Dim Read_num As Byte
 +
 +Dim Read_select As Byte
 +Dim S2 As String * 40
 +Dim Gsm_signal As String * 3
 +
 +Dim Time1_count As Byte
 +Dim Time1_ok As Bit
 +Dim Ch As Byte
 +Dim S2addr As Integer
 +
 +Read_noop Alias 0
 +Read_gsm_sta1 Alias 1
 +Read_gsm_m1 Alias 2
 +
 +Dim Relay(4) As Byte
 +Control_char Alias 0
 +Status_action Alias 1
 +Single_action Alias 2
 +Multiple_action Alias 3
 +Invalid_action Alias 4
 +On_action Alias 5
 +Off_action Alias 6
 +Toggle_action Alias 7
 +
 +#if Dlcd
 +Declare Sub Lcdlocation(byval Row As Byte , Byval Col As Byte)
 +#endif
 +
 +Config Portb = Output
 +
 +' Set all Relays OFF
 +Relay(1) = 2 : Relay(2) = 3 : Relay(3) = 4 : Relay(4) = 7
 +For Ch = 1 To 4
 +  Set Portb.relay(ch)
 +Next Ch
 +
 +#if Dlcd
 +'​Serial connection to LCD is via Port B.6
 +'LCD runs at 9600 baud
 +Open "​comb.6:​9600,​8,​n,​1"​ For Output As #2
 +
 +'LCD Reset pin is driven from PortB.5
 +Reset Portb.5 ​                                              '​Drive pin low
 +Waitms 400
 +Set Portb.5 ​                                                '​Then high
 +Waitms 400
 +#endif
 +
 +' Once enabled, the timer counts each clock period (or you can select a
 +' divided down input clock if you prefer). When the timer overflows (65536
 +' counts) you get an interrupt. With a 8MHz clock, this doesn'​t work out to
 +' anything very useful. At 8MHz, each clock pulse is 125nS and 65536 of them
 +' is 8.192 milliseconds.
 +
 +' I want a timer that resolves to 1000mS, so the first step is to divide down
 +' the input clock .  Input clock to divide by 256, so now each clock pulse is
 +' worth (8.192/​256)=32uS.
 +
 +' The trick is to preload the counter with a value that will cause it to count
 +' for 1000mS. Each time the counter expires, you can force the new number back
 +' into the timer register. We need 1/.000032 or 31250 counts. However, the
 +' counter expires at 65536, so the correct number to preload is 65536-31250 or
 +' 34285 This way, the timer will count up 31250 counts (1 second) and
 +' expire.
 +
 +Const 1000ms = 34285
 +Config Timer1 = Timer , Prescale = 256
 +
 +On Timer1 Timer1_int
 +On Urxc Rec_rs232 ​                                          '​define serial receive ISR
 +
 +' Initialize the GSM Modem
 +Print "​AT&​FE0V0+CMGF=1;​+CNMI=2,​1,​0,​0,​0"​
 +
 +Time1_count = 0 : Timer1 = 1000ms : Time1_ok = 0
 +Enable Timer1
 +Enable Interrupts
 +
 +Start Timer1
 +
 +Do
 +  If Time1_ok = 1 Then                                      ' Timer fires every 1 sec and wraps at 10sec
 +      Read_ok = 0 : Read_num = 0 : Data_ok = 0 : Rs232_exit = 0 : Sync_ok = 0
 +      Stop Timer1
 +
 +      If Time1_count = 5 Then                               '​ t+5
 +            Read_select = Read_gsm_m1
 +            Print "​AT+CMGR=1" ​                              '​ Read Message
 +            Gosub Rs232_r
 +            If Data_ok = 1 Then
 +               Print "​AT+CMGD=1" ​                           ' Delete Message
 +               #if Dlcd
 +               Call Lcdlocation(3 , 0)
 +               Print #2 , "Msg: " ; S2
 +               #​endif
 +               Gosub Read_message
 +               ​Time1_count = Time1_count + 5
 +            End If
 +      Elseif Time1_count = 3 Then                           '​ t+3
 +            Read_select = Read_gsm_sta1 : Gsm_signal = ""​
 +            Print "​AT+CSQ" ​                                 ' Signal Quality
 +            Gosub Rs232_r
 +            If Read_ok = 0 Then Gsm_signal = "​--" ​          '​If Timeout waiting for Response
 +            #if Dlcd
 +            Call Lcdlocation(1 , 14)
 +            Print #2 , "​Signal:​ " ; Gsm_signal ;
 +            #endif
 +      End If
 +
 +      Reset Time1_ok
 +      Start Timer1
 +   End If
 +Loop
 +
 +Timer1_int:
 +   ​Timer1 = 1000ms
 +   Set Time1_ok
 +   Incr Time1_count
 +   Incr Rs232_exit
 +   If Time1_count > 9 Then Time1_count = 0                  ' 10 * 1sec = 10sec
 +   ​Return
 +
 +Rec_rs232:
 +   Incr Read_num
 +      If Read_select = Read_gsm_m1 Then
 +'​+CMGR:​ "REC READ","​+447762722186",,"​05/​02/​26,​11:​07:​47+00"​ chr(13)chr(10)
 +'​Hello ​ chr(13)chr(10)
 +          If Udr = 43 And Sync_ok = 0 Then     '"​+"​-->​43
 +            Read_num = 1
 +            Sync_ok = 1
 +            S2 = ""​
 +          Elseif Sync_ok = 1 Then
 +             ​Select Case Read_num
 +               Case 5:
 +                  If Udr <> 82 Then Read_ok = 1             '"​R"​-->​82
 +               Case Else
 +                  If Data_ok = 1 Then
 +                     If Udr = 13 Then                       '​ Until 1st chr(13)
 +                        Read_ok = 1
 +                     ​Else ​                                  '​ Accumulate data
 +                        S2 = S2 + Chr(udr)
 +                     End If
 +                  End If
 +                  ' Read to end of first line before we are ready
 +                  If Udr = 10 Then Data_ok = 1
 +            End Select
 +         End If
 +   '​ Signal quality check
 +      Elseif Read_select = Read_gsm_sta1 Then
 +'+CSQ: 31,99
 +         If Udr = 43 Then Read_num = 1
 +         ​Select Case Read_num
 +            Case 4:
 +               If Udr <> 81 Then Read_ok = 1                '"​Q"​-->​81
 +            Case 7 To 8:
 +               '"​0..9"​-->​48..57
 +               If Udr > 47 And Udr < 58 Then Gsm_signal = Gsm_signal + Chr(udr)
 +            Case 9:
 +               ​Read_ok = 1
 +         End Select
 +      End If
 +
 +   ​Rs232_exit = 0                                           '​Reset RS232 timeout
 +   ​Return
 +
 +Rs232_r:
 +   Udr = 0
 +   Reset Usr.7
 +   Reset Ucr.7
 +   ​Enable Urxc                                              '​enable receive isr
 +   Start Timer1
 +   Do
 +     If Rs232_exit > 3 Then Exit Do
 +   Loop Until Read_ok = 1
 +   ​Disable Urxc
 +   Stop Timer1
 +   ​Return
 +
 +
 +'​Inbound String From The Gsm Modem Will Have The Following Syntax:
 +' a. R - Single Relay action followed by [SRT]
 +' ​     - Set / Reset / Toggle action and a number of the relay [1-4]
 +'
 +' ​       RS2 - Set relay number 2 (ON).
 +' ​       RR4 - Reset relay number 4 (OFF)
 +
 +Read_message:​
 +' Use address pointer its more efficent than this--> mid(s2,​read_num,​1)
 +   ​S2addr = Varptr(s2)
 +   ​Read_select = Control_char
 +   For Read_num = 1 To Len(s2)
 +     Ch = Inp(s2addr)
 +     Incr S2addr
 +
 +     ​Select Case Read_select
 +       Case Control_char:​
 +            Select Case Ch
 +' ​                Case 83 : Read_select = Status_action ​     '"​S"​-->​83
 +                 Case 82 : Read_select = Single_action ​     '"​R"​-->​82
 +                 Case Else Read_select = Invalid_action
 +            End Select
 +       Case Single_action:​
 +         ​Select Case Ch
 +            Case 82 : Read_select = Off_action ​             '"​RR"​
 +            Case 83 : Read_select = On_action ​              '"​RS"​
 +            Case Else Read_select = Invalid_action
 +         End Select
 +       Case On_action:
 +         If Ch > 47 And Ch < 53 Then                        ' 1..4
 +           Ch = Ch - 48
 +           Reset Portb.relay(ch)
 +         End If
 +       Case Off_action:
 +         If Ch > 47 And Ch < 53 Then                        ' 1..4
 +           Ch = Ch - 48
 +           Set Portb.relay(ch)
 +         End If
 +     End Select
 +     Next
 +   ​Return
 +
 +#if Dlcd
 +Sub Lcdlocation(byval Row As Byte , Byval Col As Byte)
 +  Col = Col + 32
 +  Row = Row + 32
 +  Print #2 , "​\B"​ ; Chr(col) ; Chr(row);
 +End Sub
 +#endif
 +</​code>​
 +{{tag>​bascom programming avr}}