Wednesday, 24 July 2019
Main Menu
Home Home
Shop Shop
News News
Products Products
Application Notes Application Notes
Publications Publications
Links Links
Support Center Support Center
Downloads Downloads
Forum Forum
Resellers Resellers
Contact Us Contact Us
Updates Updates
MCS Wiki MCS Wiki
Online Help
BASCOM-8051 Help BASCOM-8051 Help
Contents in Cart
Show Cart
Your Cart is currently empty.
Search the Shop

Products Search

User Login


If you have problem after log in with disappeared login data, please press F5 in your browser

RSS News

AN #33 - SMS driven automat Print
Let us make a Bascom program for  SMS - driven automat!
by Vilko Sustic

Attached is a fully working sample program for an SMS driven automat. You can use this example to build your own project based on it. The program and its subroutines are provided 'as is'. However you are free to remove some subroutines and add your own code but you have to be careful with others..

Dim I As Byte
Dim J As Byte
Dim K As Byte
Dim L As Byte
Dim M As Byte
Dim N As Word

The above work variables are used by diferent soubroutines and also available for use in your program. The subroutines save the original values of the variables to stack and restore afterwards.

Dim X As Byte
Dim Bajt As Byte
Dim Y(1) As Byte
Dim Niz As String * 18 'X=2
Dim Pdu As String * 34 'X=21 multiple of 7!
Dim Text As String * 38 'X=56 multiple of 8!
Dim Telno As String * 14 'X=95
Const Xpdu = 21 'multiple of 7!
Const Xtext = 56 'multipleo of 8!
Const Xtelno = 95
Const Xkonec = 120

String variables must be kept in the same order and size.  Any byte of any string variable can be addressed by using the variable Y with appropriate index.

Variable Niz is a string variable. It is used to store the commands to send to GSM and for receiving replies back. The subroutine to send the command is Poslji:

Disable Serial
Set Scon.1
Print Niz
Reset Scon.1
push {i}
For I = 2 To 16
(i) = 0
Pop {i}
= 2
Enable Serial

It sends the command, it clears the variable string and it sets variable X to 2, in order to prepare the index for being used in the Serial interrupt routine, which is responsible to intercept the reply.

 The Serial Interrupt routine is this:

Dim Pdubit As Bit
Dim Levi As Bit
= Inkey()
.1 = 0
If Bajt <> 0 Then
If X < 10 Then : Reset Pdubit : End If
If Pdubit = 0 Then
If Bajt = &H0A Then : Bajt = &H2F : End If
(x) = Bajt
If Bajt <> &H0D And X < Xtext Then : Incr X : End If 'ignore carriage return
If X > 15 And Bajt = &H2F Then : Set Pdubit : Set Levi : End If
= Bajt - &H30
If Bajt > 9 Then : Bajt = Bajt - 7 : End If
If Levi = 1 Then
Shift Bajt , Left , 4
(x) = Bajt
Reset Levi
(x) = Y(x) Or Bajt
Incr X
Set Levi
End If
End If
End If

It puts the intercepted byte to the next byte of the variable Niz. It uses the variable X as the index, and that is why you should not use this variable while gsm reply  is expected. If the reply is long when an SMS message is read, it puts the reply behind the variable Niz in the variable Pdu, but it takes two intercepted characters among 0-F for one byte of the variable PDU.

It takes some time to receive a reply from the GSM, so we should wait a bit before analizing  the reply. Instead of using wait statements, we use time interrupt driven code to do it.

We define Timer0 Interrupt procedure:

Config Timer0 = Timer , Gate = Internal , Mode = 1
On Timer0 Titi
Load Timer0 , 180


Load Timer0 , 180
Incr Tistevec

This way we get 20 interrupts per seconds using this method. So we count them at the begining of main program loop:

If Tistevec > 20 Then
= Tistevec - 20
Incr Sekunde
If Sekunde > 59 Then
= Sekunde - 60
Incr Minute

If we intend to send a GSM command, we use a second to send it one or two seconds after we analyze the reply:

 If Sekunde = 3 Then 'vsako 3. sekundo minute
= "AT+CALM=1"
Gosub Poslji
End If
If Sekunde = 4 Then 'vsako 4. sekundo minute
(18) = 0
Locate 1 , 1 'prikaži odgovor
Lcd Niz ; " "
Locate 2 , 1
If Y(3) <> &H4F Or Y(4) <> &H4B Then ' ali je odgovor OK ?
Lcd "Ni C35i!!"
Reset C35i
Lcd " "
(3) = 0
Set C35i
End If
End If

Each 3rd second of a minute we send the command AT+CALM and we expect the reply OK in the 4th second. If the reply OK is not received, we have no connection with the GSM and we reset the bit C35i, which indicates the connection.

In a similar way we  read SMS  when it’s received:

 If Sekunde = 5 And C35i = 1 Then 'vsako 5. sekundo minute
= "AT+CMGL=0" ' Daj sporočilo!
Gosub Poslji
End If

If Sekunde = 8 And C35i = 1 Then 'vsako 8. sekundo odgovor
'/OK/ če ni smsa
'/+CMGL: 9,0,,23 ....pdu... OK
' 0D0A 0D0A0D0A 0D0A če je sms
If Y(3) <> &H4F And C35i = 1 Then ' Je SMS!
Gosub Pdutxt 'Transformacija PDU v Text in Telno

Each 5th second we send AT+CMGL=0 Command and each 8th second we analyze the reply. If the answer is OK, then no message has arrived. If the answer is not OK, then an SMS message has been received and read into the variables Niz and Pdu ( and if message is very long also in Text). We call subroutine  Pdutxt to transform it into variables Telno and Text.

Subroutine Pdutxt to transforms information found in Niz:

+CMGL: 9,0,,23 t

into command


to delete the message in GSM.

In the same 8th second we call subroutine Poslji to delete the message and and we start analizing the received message, which resides in Text and of course Telno.

When we wish to send an SMS, we prepare it in Telno and in the GSM telno where the SMS is to be sent and in Text the message itself.  The actual sending is done in two phases. It has to be done in two different seconds. First we prepare the GSM handyphone for receiving a message and then we actually send the message. Therefore there are two subroutines, putsms1 and putsms2.  For actual triggering we set a bit Sendbit.

If Sekunde = 21 Then 'vsako 21. sekundo minute
' Če je postavljen bit Sendbit, pošljemo vsebino iz Text na Telno
= 2
If Sendbit = 1 And C35i = 1 Then : Gosub Putsms1 : End If
End If
If Sekunde = 22 Then 'vsako 22. sekundo minute
= 2
If Sendbit = 1 And C35i = 1 Then : Gosub Putsms2 : End If
Reset Sendbit
End If

Here’s an example of how to control some relays. There are 5 relays to be controlled

'Releji in Led diode
Alias P1.0
Alias P1.1
Alias P1.2
Alias P1.3
'Rele5 Alias P1.4
Alias P1.4
' Števci minut za releje:
Dim Relestevec(5) As Word

The appropriate counters for each relay one are minute counters. If the counter is zero, the relay is off, if not,the relay in on.

 ' krmiljenje relejev:
If Relestevec(1) <> 0 Then : Reset Rele1 : Else : Set Rele1 : End If
If Relestevec(2) <> 0 Then : Reset Rele2 : Else : Set Rele2 : End If
If Relestevec(3) <> 0 Then : Reset Rele3 : Else : Set Rele3 : End If
If Relestevec(4) <> 0 Then : Reset Rele4 : Else : Set Rele4 : End If
' If Relestevec(5) <> 0 Then : Reset Rele5 : Else : Set Rele5 : End If

We decrement each relay-counter every minute:

 Incr Minute
' vsako minuto odštevamo števce relejev, če niso 0
For I = 1 To 5
If Relestevec(i) <> 0 Then
Decr Relestevec(i)
End If

If we receive a message like this:

Tr  2:30 4:6000 3:0

It should be interpreted as this command: relay2 on for 30 minutes, relay 4 on for 6000 minutes, relay 3 off immediately, the others remain unchanged,

We intercept this commant in 8th second:

If Y(xtext) = &H54 And Y(i) = &H72 Then : Gosub Tr : End If 'set rele

Subroutine Tr sets appropriate counters and afterwards prepares message about all relays counter to be sent to originator.

Text = "Raport: " 'Še sestavimo poročilo
For I = 1 To 5
= Str(i)
= Niz + ":"
= Niz + Str(relestevec(i))
= Niz + " "
= Text + Niz

So after calling the subroutine, we set the bit Sendbit to trigger sending. If Command is not recognised as a valid command,  then the original SMS is sent back to originator.

Download source code here

I hope this will help.

Vilko Sustic