This sample program uses the ICMP module to ping a remote host. The first example program requires you to enter a numeric IP address. In the second code example, the DNS module is used to resolve a hostname (for example, www.microchip.com) before pinging. Here's what you need to do.
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
Now enter a numeric IP address and press enter. For example,
88.221.127.45
which should return something like
Ping...40 ms
// device and clock - code will work on an 18F452 as well... Device = 18F4680 Clock = 20 // important configurations... #option ENC28J60_CS = PORTD.6 #option NET_ICMP = true // enable ping #option NET_DHCP = true // enable Dynamic Host Configuration Protocol (DHCP) #option NET_NBNS = true // enable NETBIOS Include "NETApp.bas" // always first! // TCPIP stack specifics... Include "NETTypes.bas" Include "NETUtils.bas" Include "Tick.bas" Include "ICMP.bas" // program helpers... Include "NETAppDisplay.bas" Include "usart.bas" Include "convert.bas" Include "ISRRX.bas" // state machine constants... Const SM_HOME = 0, SM_GET_RESPONSE = 1, SM_FINISHED = 2 // ping variables... Dim PingState As Byte, PingTimer As TICK { **************************************************************************** * Name : Init * * Purpose : Initialise timer and state machine * **************************************************************************** } Sub Init() PingTimer = 0 PingState = SM_HOME End Sub { **************************************************************************** * Name : Ping * * Purpose : Start a ping * **************************************************************************** } Sub Ping(ByRef pIP As String) Dim PingIP As IP_ADDR If PingState = SM_HOME Then If ICMPBeginUsage() Then NETUtils.StringToIPAddress(@pIP, PingIP) ICMPSendPing(PingIP.Val) PingState = SM_GET_RESPONSE PingTimer = TickGet() EndIf EndIf End Sub { **************************************************************************** * Name : PingTask * * Purpose : Process a ping task * **************************************************************************** } Function PingTask() As SHORT Result = -2 // do nothing... // ping has been started, now wait for ping response... If PingState = SM_GET_RESPONSE Then Result = ICMPGetReply() // the request timed out... If Result <> - 2 Then PingState = SM_FINISHED EndIf EndIf // wait at least one second before another ping - remove the ping timer // code if you do not need this functionality... If PingState = SM_FINISHED And (TickGet() - PingTimer) > 1000 Then PingState = SM_HOME ICMPEndUsage() EndIf End Function { **************************************************************************** * Name : OnData * * Purpose : The TCPIP stack is a co-operative state machine. Therefore, we * * : cannot wait around for USART data and use a buffered interrupt * * : instead. When a CR is received, set a ReadyToRead flag to true * **************************************************************************** } Dim ReadyToRead As Boolean Event OnData() If ISRRX.DataChar = #13 Then ReadyToRead = true EndIf End Event // main program variables... Dim Result As SHORT Dim StrIP As String(80) // program start... SetBaudrate(br115200) Init() #if NET_DHCP Write("Waiting for DHCP...",13,10) #else DisplayConfig #endif // use interrupt buffered USART... ReadyToRead = false USART.ReadTerminator = 13 ISRRX.Initialize(OnData) // 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 // If the ready to read flag has been set, read a string from the interrupt // buffer and start the ping... If ReadyToRead Then ReadyToRead = false ISRRX.ReadStr(StrIP,13) USART.Write("Ping...") Ping(StrIP) EndIf // Process the ping task state machine... Result = PingTask() If Result >= 0 Then USART.Write(DecToStr(Result), " ms", 13,10) ElseIf Result = -1 Then USART.Write("timed out",13,10) EndIf // If DHCP is enabled, display configuration when a DHCP event // has occurred... #if NET_DHCP If NETApp.DHCPEvent() Then DisplayConfig() EndIf #endif Wend
The next code example is pretty much the same as the above, except it uses the DNS module to resolve a hostname. This means you do not have to enter a numeric IP address. For example,
www.microchip.com
which should return something like
Ping...40 ms
// device and clock - code will work on an 18F452 as well... Device = 18F4680 Clock = 20 // important configurations... #option ENC28J60_CS = PORTD.6 #option NET_ICMP = true // enable ping #option NET_DHCP = true // enable Dynamic Host Configuration Protocol (DHCP) #option NET_NBNS = true // enable NETBIOS #option NET_DNS = true // enable Domain Name Service (DNS) Include "NETApp.bas" // always first! // TCPIP stack specifics... Include "NETTypes.bas" Include "NETUtils.bas" Include "Tick.bas" Include "ICMP.bas" Include "DNS.bas" // program helpers... Include "NETAppDisplay.bas" Include "usart.bas" Include "convert.bas" Include "ISRRX.bas" // state machine constants... Const SM_HOME = 0, SM_RESOLVING = 1, SM_PING = 2, SM_GET_RESPONSE = 3, SM_FINISHED = 4 // ping variables... Dim PingState As Byte, PingTimer As TICK, PingIP As IP_ADDR { **************************************************************************** * Name : Init * * Purpose : Initialise timer and state machine * **************************************************************************** } Sub Init() PingTimer = 0 PingState = SM_HOME End Sub { **************************************************************************** * Name : Ping * * Purpose : Start a ping * **************************************************************************** } Sub Ping(ByRef pHostname As String) If PingState = SM_HOME Then If DNSBeginUsage() Then DNSResolve(@pHostName, DNS_TYPE_A) PingState = SM_RESOLVING EndIf EndIf End Sub { **************************************************************************** * Name : PingTask * * Purpose : Process a ping task * **************************************************************************** } Function PingTask() As SHORT Dim PingResult As SHORT // default result is 0 Result = 0 // resolve hostname to an IP address... If PingState = SM_RESOLVING Then PingIP.Val = 0 If DNSIsResolved(PingIP) Then DNSEndUsage // resolved, start ping... If PingIP.Val <> 0 Then PingState = SM_PING // unable to resolve, abort... Else Result = -1 PingState = SM_HOME EndIf EndIf EndIf // hostname has been resolved, start ping using // the IP address obtained from the DNS server... If PingState = SM_PING Then If ICMPBeginUsage() Then ICMPSendPing(PingIP.Val) PingState = SM_GET_RESPONSE PingTimer = TickGet() EndIf EndIf // ping has been started, now wait for ping response... If PingState = SM_GET_RESPONSE Then PingResult = ICMPGetReply() // the request timed out... If PingResult = -1 Then Result = -2 PingState = SM_FINISHED // echo received, time elapsed is stored in result (units of TICK) ElseIf PingResult >= 0 Then Result = PingResult PingState = SM_FINISHED EndIf EndIf // wait at least one second before another ping - remove the ping timer // code if you do not need this functionality... If PingState = SM_FINISHED And (TickGet() - PingTimer) > 1000 Then PingState = SM_HOME ICMPEndUsage() EndIf End Function { **************************************************************************** * Name : OnData * * Purpose : The TCPIP stack is a co-operative state machine. Therefore, we * * : cannot wait around for USART data and use a buffered interrupt * * : instead. When a CR is received, set a ReadyToRead flag to true * **************************************************************************** } Dim ReadyToRead As Boolean Event OnData() If ISRRX.DataChar = #13 Then ReadyToRead = true EndIf End Event // main program variables... Dim Result As SHORT Dim StrHostname As String(80) // program start... SetBaudrate(br115200) Init() #if NET_DHCP Write("Waiting for DHCP...",13,10) #else DisplayConfig #endif // use interrupt buffered USART... ReadyToRead = false USART.ReadTerminator = 13 ISRRX.Initialize(OnData) // 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 // If the ready to read flag has been set, read a string from the interrupt // buffer and start the ping... If ReadyToRead Then ReadyToRead = false ISRRX.ReadStr(StrHostname,13) USART.Write("Ping...") Ping(StrHostname) EndIf // Process the ping task state machine... Result = PingTask() If Result > 0 Then USART.Write(DecToStr(Result), " ms", 13,10) ElseIf Result = -1 Then USART.Write("Unable to resolve ", StrHostname, 13,10) ElseIf Result = -2 Then USART.Write("timed out",13,10) EndIf // If DHCP is enabled, display configuration when a DHCP event // has occurred... #if NET_DHCP If NETApp.DHCPEvent() Then DisplayConfig() EndIf #endif Wend