'******************************************************************** '* 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