Monday, July 4, 2011

Sending SMS with VB.NET and AT commands


In the previews post, we have learn about sending and receiving SMS using AT commands. Now using VB.NET i will be showing you how to send SMS with your window forms and discuss the process along the way. For this project I will be using VB.NET for my code behind.

Lets start with creating a project. I am naming the project "ConnSMS" and you can name your own as you wish. For this project I will be using one form which will contain all the controls that we will need to build this application. You can design your own but for the purpose of this discussion I will try to shrink all the functions into one form. Name the form and the controls as to your preference. I will be discussing each as we proceed.

Window Form:





Name the form and the controls as you prefer.  For this application we need some controls that will be used to establish connection from the computer to our GSM modem using the available serial port. The form load function will populate the combo box control with the available serial ports to which we can establish connection. I made a frame containing the text box for the recipient and the message followed by a button to send. The AT commands are then displayed to the text area at the right side of the form. The message received will then be displayed at the bottom list control. I also added a status strip to indicate current status of each event. The form and the code for this application is shown below.

ConnSMS.vb

Imports System.IO.Ports

Public Class ConnSMS
    Dim WithEvents serialport As New IO.Ports.SerialPort
    Private Declare Sub Sleep Lib "kernel32" (ByVal milsec As Long)

    Dim objport As New SMSclass

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For i As Integer = 0 To My.Computer.Ports.SerialPortNames.Count - 1
            cmbport.Items.Add(My.Computer.Ports.SerialPortNames(i))
        Next
    End Sub

    Private Sub butSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butSend.Click
            If objport.SendSMS(serialport, TxtTo.Text, rtxtto.Text) Then
                lblstatStrip.Text = "Message Sent"
            Else
                lblstatStrip.Text = "Message Sending Failed"
            End If
    End Sub

    Private Sub butRead_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butLoad.Click
       
    End Sub
    Private Sub butLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butLoad.Click
        Dim objShortMessageCollection = objport.ReadSMS(serialport, TxtTo.Text)
        For Each msg As ShortMessage In objShortMessageCollection

            Dim item As New ListViewItem(New String() {msg.Index, msg.Sent, msg.Sender, msg.Message})
            item.Tag = msg

            ListView1.Items.Add(item)
        Next
    End Sub
    Private Sub butConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butConnect.Click
        Try
            serialport = objport.OpenPort(cmbport.Text)
            If Not serialport Is Nothing Then
                lblstatStrip.Text = "Modem is connected at PORT " & cmbport.Text & "."
            Else
                lblstatStrip.Text = "Invalid port settings."
            End If
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Private Sub butDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butDisconnect.Click
        Try
            objport.ClosePort(serialport)
            lblstatStrip.Text = "Not Connected"
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    
End Class


Lets create a class that will handle the different events that we need. I will be naming this class the SMSclass.
The code for this class is shown below.

SMSclass.vb

Imports System.IO.Ports
Imports System.IO.Ports
Imports System.Threading
Imports System.Text
Imports System.Text.RegularExpressions

Public Class SMSclass

    Private Declare Sub Sleep Lib "kernel32" (ByVal milsec As Long)
    Public receiveNow As New AutoResetEvent(False)
    Shared readNow As New AutoResetEvent(False)
    Public Function OpenPort(ByVal comport As String) As SerialPort

        Dim serialport As New IO.Ports.SerialPort

        Try
            If comport <> Nothing Then
                With serialport
                    .PortName = comport
                    .BaudRate = 96000
                    .Parity = Parity.None
                    .DataBits = 8
                    .StopBits = StopBits.One
                    .Handshake = Handshake.RequestToSend
                    .ReadTimeout = 300
                    .WriteTimeout = 300
                    .Encoding = Encoding.GetEncoding("iso-8859-1")
                    .DtrEnable = True
                    .RtsEnable = True
                    .NewLine = vbCrLf
                End With
                serialport.Open()
                Return serialport
            Else
                Return serialport
            End If
        Catch ex As Exception
            Throw ex
        End Try
    End Function

    Public Sub ClosePort(ByVal serialport As SerialPort)
        Try
            serialport.Close()
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Public Sub port_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
        If e.EventType = SerialData.Chars Then
            receiveNow.Set()
        End If
    End Sub

    Private Shared Sub DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
        If e.EventType = SerialData.Chars Then
            readNow.Set()
        End If
    End Sub
    Public Function ExecCommand(ByVal port As SerialPort, ByVal strcommand As String, ByVal errmess As String)
        port.WriteLine(strcommand)
        'ConnSMS.SendMsg.Text = ConnSMS.SendMsg.Text & strcommand
        Dim input As String = ReadResponse(port, 400)
        ConnSMS.SendMsg.Text = ConnSMS.SendMsg.Text & input
        Return input
    End Function
    Public Function ReadResponse(ByVal port As SerialPort, ByVal timeout As Integer)
        Dim buff As String = ""
        Try
            Do
                Dim t As String = port.ReadExisting()
                buff = buff & t
            Loop Until buff.EndsWith(vbCrLf & "OK" & vbCrLf) Or buff.EndsWith(vbCrLf & "> ") Or buff.EndsWith(vbCrLf & "ERROR" & vbCrLf)
        Catch ex As Exception
            Throw ex
        End Try
        Return buff
    End Function
    Public Function SendSMS(ByVal port As SerialPort, ByVal PhoneNo As String, ByVal Message As String) As Boolean
        Dim isSent As Boolean = False
        Dim receivedData As String = ""

        receivedData = ExecCommand(port, "AT" & vbCr, "Unable to connect.")
        System.Threading.Thread.Sleep(200)
        receivedData = ExecCommand(port, "AT+CMGF=1" & vbCr, "Failed to set message format.")
        System.Threading.Thread.Sleep(200)
        receivedData = ExecCommand(port, "AT+CMGS=" & Chr(34) & PhoneNo & Chr(34) & vbCr, "Failed to accept phoneNo")
        System.Threading.Thread.Sleep(200)
        receivedData = ExecCommand(port, vbBack & vbBack & "FROM PICTU SMS: " & Message & Chr(26), "Failed to send message")
        System.Threading.Thread.Sleep(200)

        If receivedData.EndsWith(vbCrLf & "OK" & vbCrLf) Then
            isSent = True
        ElseIf receivedData.Contains("ERROR") Then
            isSent = False
        End If
        Return isSent

    End Function
    Public Function ReadSMS(ByVal port As SerialPort, ByVal command As String)
        Dim messages As ShrotMessageCollection = Nothing
        Dim receivedData As String = ""

        ExecCommand(port, "AT" & vbCr, "Unable to connect.")
        System.Threading.Thread.Sleep(200)
        ExecCommand(port, "AT+CMGF=1" & vbCr, "Failed to set message format.")
        System.Threading.Thread.Sleep(200)
        ExecCommand(port, "AT+CSCS=" & Chr(34) & "PCCP437" & Chr(34), "Failed to set character set.")
        System.Threading.Thread.Sleep(200)
        ExecCommand(port, "AT+CPMS=" & Chr(34) & "ME" & Chr(34), "Failed to select message storage.")
        System.Threading.Thread.Sleep(200)
        receivedData = ExecCommand(port, "AT+CMGL=" & Chr(34) & "REC UNREAD" & Chr(34), "Failed to read all message.")
        System.Threading.Thread.Sleep(200)
        messages = ParseMessages(receivedData)

        If Not messages Is Nothing Then
            Return messages
        Else
            Return Nothing
        End If
    End Function
    Public Function ParseMessages(ByVal input As String) As ShrotMessageCollection
        Dim messages As New ShrotMessageCollection()
        Try
            Dim r As New Regex("\+CMGL: (\d+),""(.+)"",""(.+)"",(.*),""(.+)""\r\n(.+)\r\n")
            Dim m As Match = r.Match(input)
            While m.Success
                Dim msg As New ShortMessage()
                'msg.Index = int.Parse(m.Groups[1].Value);
                msg.Index = m.Groups(1).Value
                msg.Status = m.Groups(2).Value
                msg.Sender = m.Groups(3).Value
                msg.Alphabet = m.Groups(4).Value
                msg.Sent = m.Groups(5).Value
                msg.Message = m.Groups(6).Value
                messages.Add(msg)

                m = m.NextMatch()

            End While
        Catch ex As Exception
            Throw ex
        End Try
        Return messages
    End Function
End Class

I also created an class named "ShortMessages.vb". This will contain the properties of the SMS and be used in reading the SMS from the GSM modem. Another object will hold the value for the collection of SMS. To do this I added another class named "ShortMessageCollection.vb" which inherits the "ShortMessage.vb" class.

ShortMessage.vb

Public Class ShortMessage
    Public Index As String
    Public Status As String
    Public Sender As String
    Public Alphabet As String
    Public Sent As String
    Public Message As String
End Class

ShrotMessageCollection.vb

Public Class ShrotMessageCollection
    Inherits List(Of ShortMessage)

End Class

That's it! We are done with this project. Try to make your own application and see for your self. I hope that this post can guide you along the way. The project might have some bugs though. I have not tested it yet completely but the functions I have made seems to work for me. You can contribute by posting your comments and suggestions to improve this subject. I would be glad to here your suggestions. I will wrap things up and try to create a video of this project at run-time. 

Watch out for more. Cheers! 

33 comments:

  1. can you send me that project??
    it's hard to get the name of the object you put in the form...
    emailaddyourface@gmail.com

    ReplyDelete
  2. The code from the post gives you everything to get things done. The project was already integrated with my application and sorry but the source is no longer available for download. Please post your issues here and we will try to solve it.

    ReplyDelete
  3. Private Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click
    Try
    objport.ClosePort(serialport)
    lblstatStrip.Text = "Not Connected"
    Catch ex As Exception
    Throw ex
    End Try
    End Sub
    __

    i have an error in objport.ClosePort(serialport)
    i think there's no event for .ClosePort?
    __


    Public Function ExecCommand(ByVal Port As SerialPort, ByVal StrCommand As String, ByVal ErrMess As String)

    Port.WriteLine(StrCommand)
    Dim Input As String = ReadResponse(Port, 400)
    'ConnSMS.SendMsg.Text = ConnSMS.SendMsg.Text & StrCommand
    ConnSMS.sendMsg.text = ConnSMS.sendMsg.text & Input
    Return Input

    End Function
    __

    in this part... where did you do to ConnSMS.SendMsg.Text?? i've got an error there...
    __

    and wht would be the name of the "TextBox" below the Disconect Button??

    by the way... thank for your Tutuorial it's helps a lot for me ^_^

    ReplyDelete
  4. OK na sir^_^ THANKS tlga dito ^_^ try ko xa i integrate sa ggwin kong application ^_^ THAN YOU THANK YOU ^_^

    ReplyDelete
  5. sir probelm... pag nag coconect na ako... nag tTHROW ex xa...tama nmn ung port na nilalagay ko... anu kea problem nun?

    ReplyDelete
  6. parang ayaw gumana SIR...nag nNOT RESPONDING... hmmm... ge2 po...bukas ko nlng i ccontinue to... maxado ng gabi... ^_^

    ReplyDelete
  7. Are you still having some problem with your code?..I don't see any problem with the code as long as you have established the connection with the COM.

    ReplyDelete
  8. sir OK nmn po ung Connection with the COM port and OK nnmn po ung CODE na modify ko nmn po ng maaus... the problem is...if i click the LOAD button... ang tagal nya mag response then nag nNOT RESPONDING na... pag nag text nmn ako then CLICK SEND... same din... nag nNOT RESPONDING ung program...

    and may mga old text messages na dun sa modem, bakit po hindi ma read dun sa ListView??

    anu keang probelm dun?
    meron po kc akong na DL na ganyan... gawa nga lang po sa C#... OK nmn po nagana nmn kea lang hiram ako mag convert from C# to VB.NET... gusto ko kc manu manu ung coding para masanay... ayoko kc ng basta basta copy paste lang... ^_^

    well any way...THANK's po sa reply hehe ^_^

    ReplyDelete
  9. Sir...wala na po bang praan para maaus tong sample nyu??? na try ko na po sa GLOBE BROAD BAND at SMART BROAD BAND eh... di tlga xa nag s WORK... laging nag nNOT RESPONDING... ok nmn po ung connection... lagi ko pong tini-test... tlgang di maka send at read ng messages eh.... ^_^

    ReplyDelete
  10. Sir, not responding sakin. Pag mag.send, nag.hahang na ang app. Kaya close ko na lang. Bakit po kaya sir? Patulong naman ohh.

    BTW, thanks po pala sa pagpost nito. ;)

    ReplyDelete
  11. Thanks for sharing this,, i think mas madaling matutunan at mabasa yung code mo kung gumamit kg ng comments and also post the names of the tools you use ex: textbox and buttons.

    ReplyDelete
  12. Sir wala po akong error pero ayaw nya mag send.

    ReplyDelete
  13. It's not responding.... well nice try!!

    ReplyDelete
  14. Wow.! thanks po dito sir ito po talaga need ko. .easy to understand. .wla tlga ako idea dito eh. . btw panu nmn po ung sms notification program? pde ka po ba maka gawa ng simple tut? or references nlng po kung panu gumawa ng sms notification prog.. Thanks in advance idol

    emailadd ko po: michaelryanpaclibar@yahoo.com

    ReplyDelete
  15. sir, hindi ku pu madisplay sa listview ung mga textmessages na na receive nung prog panu pu un?

    ReplyDelete
  16. bakit palaging port close even if may code naman na nag oopen? actually la naman pong error pero during runtime meron na. bakit po ganun? btw, salamat po dito kuya! :D

    ReplyDelete
  17. brother RUF.DEV, kindly sort me out. i have some errors.

    Error 1 'msg' is not declared. It may be inaccessible due to its protection level.
    Error 2 'msg' is not declared. It may be inaccessible due to its protection level.
    Error 3 'msg' is not declared. It may be inaccessible due to its protection level.
    Error 4 'msg' is not declared. It may be inaccessible due to its protection level.
    Error 5 'msg' is not declared. It may be inaccessible due to its protection level.
    Error 6 'SendMsg' is not a member of 'WindowsApplication1.ConnSMS'.
    Error 7 'SendMsg' is not a member of 'WindowsApplication1.ConnSMS'.

    ReplyDelete
  18. "ConnSMS.sendMsg.text" im having error about this, how can i solve it? thanks :)

    ReplyDelete
  19. Hi... Pwede po bang magtanong... Gumamit po ba kayo ng DLL para sa iyong SMS application?

    ReplyDelete
  20. -put threading para d maghang
    -catch mo ung CMTI para auto n ung reading ng incoming sms, so no need to load pa using CMGR.

    by the why nice post

    ReplyDelete
  21. Sir ngeeror po ung load button..how can i fix that..


    OK

    OK

    ERROR

    +CPMS: 25,25,65,65,65,65

    OK

    OK

    ReplyDelete
  22. Sir I have the same problem like FirstName

    regarding this code:

    Public Function ExecCommand(ByVal Port As SerialPort, ByVal StrCommand As String, ByVal ErrMess As String)

    Port.WriteLine(StrCommand)
    Dim Input As String = ReadResponse(Port, 400)
    'ConnSMS.SendMsg.Text = ConnSMS.SendMsg.Text & StrCommand
    ConnSMS.sendMsg.text = ConnSMS.sendMsg.text & Input
    Return Input

    End Function

    Error Msg:'SendMsg' is not a member of 'ConnSMS.ConnSMS'.

    Hope you can assist me with this.

    Thank you

    ReplyDelete
  23. Sir,

    I have the same problem like FirstName with regards to the code below:

    ---
    Public Function ExecCommand(ByVal Port As SerialPort, ByVal StrCommand As String, ByVal ErrMess As String)

    Port.WriteLine(StrCommand)
    Dim Input As String = ReadResponse(Port, 400)
    'ConnSMS.SendMsg.Text = ConnSMS.SendMsg.Text & StrCommand
    ConnSMS.sendMsg.text = ConnSMS.sendMsg.text & Input
    Return Input

    ---

    End Function

    Hope you can assist me with this

    Thank you

    Error Message:'SendMsg' is not a member of 'ConnSMS.ConnSMS'.

    ReplyDelete
  24. Sir,

    Thank you very much for this post nakatulong ng malaki sa pag dev ko ng SMS

    Thank you and more power sir
    I hope marami pa kayo mga helpful post in the future...!

    ReplyDelete
  25. Can you help me with the mobile recharge AT commands? If you have any details please mail to me : outsourcingplus@gmail.com

    ReplyDelete
  26. hi... there seems to be a problem with your ReadSMS function... the AT+CMGL="ALL" command only returns " OK " and not the list of messages...

    ReplyDelete
  27. hi sir, i'm from malaysia a diploma student..

    i'm doing a project regarding your post. i understand your codes but i need to change the codes to use the usb com ports not using serial port. So in which part i have to change sir..

    Thank you.

    ReplyDelete
  28. Error 1 Name 'ConnSMS' is not declared.

    how can i solve this problem?
    what should i do? pls help
    tnx

    ReplyDelete
  29. Error 1 Name 'ConnSMS' is not declared.

    how can i solve this problem?
    pls help

    ReplyDelete
  30. sir pwede po b malaman ung mga name ng textboxes,buttons etc. d ko kc alam kung ano ilalagay sa ibang textbox.

    ReplyDelete
  31. Sir OK p ba to?? ng hahang kc pg ngsend ako

    ReplyDelete
  32. I badly need this. can you please send it to me in complete form.. I'm a total newbie. I'd like to learn this by exploring. radnarudellenaj@gmail.com

    ReplyDelete

You might also like:

Related Posts Plugin for WordPress, Blogger...