EthernetSMTP

This sample program uses the SMTP module to send an email from your PIC MCU. This program requires quite a bit of ROM - Ised an 18F4680 for testing as this has more than 32KB of ROM. You will need to edit the sample code a little, namely

// email constants...
Const
   SMTPServer = "post.myserver.co.uk",
   SMTPSendTo = "[email protected]",
   ...

The most important fields are "SMTPServer" and "SMTPSendTo". You must change these. Please note that the SMTP module does not support authentication. If your outgoing mail server requires a username and password, then this module will not work for you.

Assuming that you have edited the above correctly and you have confirmed that your outgoing mail server does not require a user name or password, then here is what you need to do next:

  • Plug a network cable into your board and connect to your network. For example, just plug your Ethernet board into your broadband router, which will act as a DHCP server.
  • Compile and then program the code into your device.
  • Start the Swordfish Serial Communicator plugin, and a connect to your MCUs USART at 115200 baud.
  • Reset the MCU.

If all goes well, something like the following should be displayed in the Serial Communicator window

 Waiting for DHCP...
 Host Name     : SWORDFISH      
 MAC Address   : $00 $04 $A3 $00 $00 $00 
 IP address    : 192.123.223.1
 Mask          : 255.255.255.0
 Gateway       : 192.123.223.254
 Primary DNS   : 192.123.223.254
 Secondary DNS : 158.123.223.58

Now enter "m" and press enter. The following should be displayed.

 Sending mail...
 MAIL SENT!

There may be quite a delay between "Sending mail" and "MAIL SENT" - please give it a little time. You email message when it arrives in your inbox should look something like this

 Swordfish
 Tue 05/02/2008 10:51:59

Sample Code

// device and clock
Device = 18F4680
Clock = 20

// important configurations...
#option ENC28J60_CS = PORTD.6
#option NET_ICMP = true   // enable ping
#option NET_DHCP = true   // enable DHCP
#option NET_NBNS = true   // enable NETBIOS
#option NET_SMTP = true   // enable mail
#option NET_SNTP = true   // enable time server
Include "NETApp.bas"      // always first

// TCPIP stack specifics...
Include "NETTypes.bas"
Include "NETUtils.bas"
Include "Tick.bas"
Include "SNTP.bas"
Include "SMTP.bas"

// program helpers...
Include "NETAppDisplay.bas"
Include "usart.bas"
Include "convert.bas"
Include "UTCDateTime.bas"

// email constants...
Const
   SMTPServer = "post.myserver.co.uk",
   SMTPSendTo = "[email protected]",
   SMTPFrom = "SMTP Service <[email protected]>",
   SMTPSubject = "SMTP Test"		    
{
****************************************************************************
* Name    : UTCTime                                                        *
* Purpose : Gets the UTC time and formats the output to                    *
*         : DayOfWeek DAY MONTH YEAR HOUR:MINS:SECS                        *
****************************************************************************
}
Function UTCTime() As String(24)
   Dim Seconds As DWORD
   Seconds = SNTPGetUTCSeconds
   UTC.Decode(Seconds)
   result = UTC.DayOfWeek(DateTime.DOW) + " " + 
            DecToStr(DateTime.Day,2) + "/" + DecToStr(DateTime.Month,2) + "/" + DecToStr(DateTime.Year) + " " + 
            DecToStr(DateTime.Hour,2) + ":" + DecToStr(DateTime.Min,2) + ":" + DecToStr(DateTime.Sec,2)
End Function

// state machine constants...
Const
   MAIL_HOME = 0,
   MAIL_BEGIN = 1,
   MAIL_SMTP_FINISHING = 2,
   MAIL_DONE = 3

// statics...
Dim MailBody As String(80)
Dim MailState As Byte
Dim WaitTime As TICK   
{
****************************************************************************
* Name    : SMTPTask                                                       *
* Purpose : SMTP task process                                              *
****************************************************************************
}
Sub SMTPTask()
   Dim MailResult As Word

   Select MailState

      // Note that strings must stay allocated in memory until SMTPIsBusy() 
      // returns FALSE.  To guarantee that the compiler does not reuse this 
      // memory, you must allocate the strings at the module level (static)   
      Case MAIL_BEGIN:    

         // begine SMTP usage...
         If SMTPBeginUsage() Then

            // init server, send to, from and subject...
            SMTPClient.Server.szROM = @SMTPServer
		    SMTPClient.ROMPointers.Server = true
            SMTPClient.SendTo.szROM = @SMTPSendTo
		    SMTPClient.ROMPointers.SendTo = true
            SMTPClient.From.szROM = @SMTPFrom
		    SMTPClient.ROMPointers.From = true
            SMTPClient.Subject.szROM = @SMTPSubject
		    SMTPClient.ROMPointers.Subject = true

            // body...
            MailBody = "Swordfish" + #13 + #10 + UTCTime
            SMTPClient.Body.szRAM = @MailBody

            // send the mail...
            SMTPSendMail()
		    Inc(MailState)
		    Write("Sending mail...",13,10)
        EndIf

     // are we finished sending email...
	 Case MAIL_SMTP_FINISHING:
        If Not SMTPIsBusy Then
		   Inc(MailState)
		   WaitTime = TickGet()
		   MailResult = SMTPEndUsage()
		   If MailResult = SMTP_SUCCESS Then
              Write("MAIL SENT!",13,10)
           ElseIf MailResult = SMTP_RESOLVE_ERROR Then
              Write("Unable to resolve SMTP server",13,10)
           ElseIf MailResult = SMTP_CONNECT_ERROR Then
              Write("Unable to connect to server",13,10)
           Else
              Write("ERROR : ",DecToStr(MailResult),13,10)
           EndIf            
        EndIf

	 // Wait for ate least one second to prevent flooding of email box!!
     Case MAIL_DONE:
		If TickGet() - WaitTime > TICK_SECOND Then
		   MailState = MAIL_HOME
		EndIf
   End Select
End Sub

// program variables...
Dim Key As Byte

// program start...
SetBaudrate(br115200)
MailState = MAIL_HOME

#if NET_DHCP
Write("Waiting for DHCP...",13,10)
#else
DisplayConfig
#endif

// loop forever...
While true

   // This task performs normal stack task including checking for incoming 
   // packet, type of packet and calling appropriate stack entity to process it.
   NETApp.Task
   SMTPTask()   

   // enter 't' to display the time, 'm' to send mail - make
   // sure you edit the email constants at the top of the program... 
   If DataAvailable Then
      Key = ReadByte 
      If Key = Byte("t") Then
         Write(UTCTime,13,10)
      ElseIf Key = Byte("m") And MailState = MAIL_HOME Then
         Inc(MailState)
      EndIf   
   EndIf

   // If DHCP is enabled, display configuration when a DHCP event
   // has occurred...
   #if NET_DHCP
   If NETApp.DHCPEvent() Then
      DisplayConfig()
   EndIf
   #endif
Wend