Swordfish Simple HTTP Client

IMG 1081Back in 2008, David Barker released a partial port of the Microchip ethernet libraries. At the time I excitedly looked at it, then promptly forgot about it.

Fast forward to now, and I rediscovered the stack, lurking about at the bottom of my UserLibrary. Having powered up my PICDEM.net2 board and uploaded the demo samples, I lamented the lack of a HTTP client.

Having used the Microchip Ethernet Stack at work in a number of projects, I suddenly realised that a simple HTTP Client would be fairly trivial to port into Swordfish, and so ladies and gentlemen, here I present the Swordfish Simple HTTP Client.

Download the HTTPClient.bas and Demo file here.

You'll need the original stack port from here.

Hardware:

IMG 1081

The Swordfish stack is dependent upon the ENC28J60 stand alone ethernet controller (no support for 18F97J60 internal ethernet yet). The demos I present here were tested on the PICDEM.net 2 board, with a 18F97J60 configured to use the external ENC28J60.

Note: The .inc file for the 18F97J60 needs modifying to disable the internal Ethernet:

set #const _ethernet to $00

Whichever PIC device you use, be aware that the stack takes up quite a lot of Flash and RAM; for example HTTPClientTest.bas takes 31726 program bytes and 1006 variable bytes.

Connect your ethernet cable from J2 to your router/switch.
Connect to the serial port using the Serial Communicator at 115200 baud.

Running the Demo:

Example Swordfish Code
{
*****************************************************************************
*  Name    : HTTPClientTest.BAS                                             *
*  Author  : RangerBob                                                      *
*  Notice  : Copyright (c) 2012                                             *
*          : All Rights Reserved                                            *
*  Date    : 23/03/2012                                                     *
*  Version : 1.0                                                            *
*  Notes   : See www.Digital-DIY.com or www.SFCompiler.co.uk for details    *
*          :                                                                *
*****************************************************************************
}
 
// device and clock - Note set #const _ethernet = $00 in 18F97J60 to disable the onboard
// ethernet device as no support yet. Uses ENC28J60. Other PIC devices will also work.
// This configuration uses the PICDEM.net 2 board. Connect ethernet cable to J2 for ENC28J60.
 
Device = 18F97J60
Clock = 25// important configurations...
#option ENC28J60_CS = PORTD.3
#option NET_ICMP = true                                           // enable ping
#option NET_DHCP = true                                           // enable Dynamic Host Configuration Protocol (DHCP)
#option NET_NBNS = true                                           // enable NETBIOS
#option NET_SNTP = true                                           // enable time server#option STACK_USE_DNS = true
#option STACK_USE_TCP = true
 
Include "NETApp.bas"                                              // always first!
Include "system.bas"// TCPIP stack specifics...
Include "NETTypes.bas"// program helpers...
Include "NETAppDisplay.bas"
Include "usart.bas"
Include "convert.bas"
Include "string.bas"Include "HTTPClient.bas"Const
    CR = #13,
    LF = #10
 
Dim I As Byte
Dim W As Word
Dim Buffer As String// program start...
OSCTUNE = %01000000
DelayMS(100)
USART.ReadTerminator = #13
SetBaudrate(br115200)#if NET_DHCP
Write("Waiting for DHCP...",13,10)
#else
DisplayConfig
Write("Enter server name:",13,10)
#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    // If DHCP is enabled, display configuration when a DHCP event
    // has occurred...
    #if NET_DHCP
    If NETApp.DHCPEvent() Then
        DisplayConfig()
        Write("Enter server name: (eg. www.google.com)",13,10)
    EndIf
    #endif
 
    // read Entered server name
    If DataAvailable Then
        USART.Read(ServerName)
 
        // Connect to server (port 80) - this also starts the send state machine
        Write("Connecting to ", ServerName, "..."13,10)
        CLIENT.Connect(ServerName, 80)        // Keep the state machines going until we get the connection or disconnected (Error)
        Repeat
             NETApp.Task()
            CLIENT.Task()
        Until CLIENT.ClientState >= CLIENT_CONNECTED          // We are now connected to the remote server, send our HTTP GET request    
        If CLIENT.ClientState = CLIENT_CONNECTED Then
            Write("Connected to ", ServerName, ", sending GET request...",13,10)
            // Send our GET request
            CLIENT.PutString("GET /index.html")
            CLIENT.PutString(" HTTP/1.1" + CR + LF)
            CLIENT.PutString("Host: " + ServerName + CR + LF)
            CLIENT.PutString("Connection: close" + CR + LF + CR + LF)
            CLIENT.SendData()
 
        EndIf
 
        // Keep the state machines going until we get disconnected
        If CLIENT.ClientState = CLIENT_RESPONSE Then
            Write("Got...",13,10,13,10)
            Repeat
 
                // Keep stack going
                 NETApp.Task()
                    CLIENT.Task()                    // Buffer out the response, otherwise we get bogged down in the usart too much
                W = CLIENT.IsDataReady
 
                I = SizeOf(Buffer) - 1
                Buffer(I) = 0
                While W > 0
                    If W < I Then
                        I = W
                        Buffer(I) = 0
                    EndIf
 
                    W = W - GetArray(@Buffer, I)
 
                    USART.Write(Buffer)
 
                Wend
            Until CLIENT.ClientState >= CLIENT_DISCONNECT
        EndIf
 
        // Keep the state machines going until we have fully released the socket
        Repeat
             NETApp.Task()
            CLIENT.Task()
        Until CLIENT.ClientState >= CLIENT_READY
 
        Write(13,10,ServerName, " Disconnected",13,10,13,10)    
 
        Write("Enter server name: (eg. www.google.com)",13,10)
    EndIf
Wend

Power up your board. You should see the board attempt to get a DHCP connection (see the Wiki page here for more information). Once connected, you will be prompted for a server name. As configured, the demo will get the root page (index.html) of whatever server name you enter. If all goes well, you’ll then be presented with the returned page. For example www.google.com:

Output
Waiting for DHCP...
Host Name     : SWORDFISH      
MAC Address   : $00 $04 $A3 $00 $00 $00
IP address    : 172.16.136.9
Mask          : 255.255.0.0
Gateway       : 172.16.255.254
Primary DNS   : 172.16.0.2
Secondary DNS : 172.16.0.1
Enter server name: (eg. www.google.com)
Connecting to www.google.com...
Connected to www.google.com sending GET request...
Got...
 
HTTP/1.1 302 Found
Location: http://www.google.co.uk/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=b9e98ec8d0ddaec4:FF=0:TM=1333020080:LM=1333020080:S=pgiLoQv2AQ-PNpw7; expires=Sat, 29-Mar-2014 11:21:20 GMT; path=/; domain=.google.com
Set-Cookie: NID=58=NvX2fo96Cq_HPzxFY_VdRFTb2daNHwWRku0JSPHdRJKe02RhjQKVADSMpbbGJlJNYf5D4PtRKOeXZfEjXpvPCgXiSHFKqz6ejCSdeyIKnXrdaS2arHDxKdlvGCU0i1OX; expires=Fri, 28-Sep-2012 11:21:20 GMT; path=/; domain=.google.com; HttpOnly
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&;answer=151657 for more info."
Date: Thu, 29 Mar 2012 11:21:20 GMT
Server: gws
Content-Length: 221
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Connection: close
 
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.co.uk/">here</A>.
</BODY></HTML>
 
www.google.com Disconnected

So what use is all this? Good question! I hope I’ve whet your appetite and stick around for the next article to find out!

Update - Have a look at my other article "Swordfish Pachube (Patch-Bay) Client" for an example of using Pachube (pronounced “Patch-Bay”) which is an online database service that allows users and developers to upload and download data from their own “Feeds”, or from feeds from other users.

 


Rangerbob


Posted: 6 years 11 months ago by Ph1lj #11530
Ph1lj's Avatar
Hi

Hope you can help - when I compile I get the following error
- any ideas ?

[ASM Error]] E:\Documents and Settings\user\My Documents\Omachron Stuff\Omachron SwordFish\My_Cosm\HTTPclient\HTTPclientTest.asm 18121 : Symbol not previously defined (TXIF)

I did modify the appropriate *.inc file

Hope you can help - this work be really useful if I can get it to work.
Posted: 6 years 11 months ago by RangerBob #11532
RangerBob's Avatar
Hi there!

It would be helpful if you could open the ASM file (press F2, or go to "Plugin - IDE Assembler view" and copy the chunk of code around line 18121.

Can you also please confirm which PIC device you are running on? And which SF version you are running?

TXIF is part of a structure in the ENC28J60.bas file, so might be worth having a check that everything looks ok in there. I am totally not sure what would cause an error like this to occur.

Regards,

Rangerbob
Posted: 6 years 11 months ago by Ph1lj #11533
Ph1lj's Avatar
Hi thanks for getting back to me.

Here is the copy of the requested code

NOP;#REQ#_GOTO PROC_WRITEBYTE_0
PROC_OL_7_WRITEITEM_0
?I002274_F023_000480_P000331 ; L#MK FSR0 = ADDRESSOF(PTEXT)
LFSR 0,F53_U320
?I002275_F023_000492_P000331 ; L#MK ASM
LIST
;[SB#START_OF_ASM]
VARIABLE PIR = PIR1
VARIABLE TXRegister = TXREG1
movf POSTINC0, W
bz $ + 10
btfss PIR, TXIF - ***** LINE 18121
bra $ - 2
movwf TXRegister
bra $ - 10
;[SB#END_OF_ASM]

The compiler is set to use the 18F97J60

My version of Swordfish is 2.2.1.3 - ICC 1.1.5.7

Look forward to your response
Posted: 6 years 11 months ago by RangerBob #11553
RangerBob's Avatar
Yeah, totally not sure what's going on there.

The "btfss PIR, TXIF" line should read "btfss PIR, 4". I'm running a slightly newer beta version but that should not affect that.

If you could [edit]download this zip file for me and try to compile it. Check the 18F97J60.inc file has the "#const _ethernet = $00" line set again please.

I notice you are trying to interface with COSM from your paths, do check out the Pachube demo, as Pachube became COSM, but all the old pachube APIs still work!
Posted: 6 years 11 months ago by RangerBob #11555
RangerBob's Avatar
Ah ha! Might have found it. Do you have an older version of "USART.bas" to me? I'm running 1.5. Can you confirm which version you are running please?

If you are running an older version, check out the instructions posted at the bottom of that post to get a newer version.
Posted: 6 years 11 months ago by Ph1lj #11556
Ph1lj's Avatar
You are correct the version I'm using is 1.3, where can I get v1.5 from - I cant see it on the forum (swordfish)
Posted: 6 years 11 months ago by Ph1lj #11557
Ph1lj's Avatar
Sorry - that was supposed to be can't find it on the Swordfish wiki
Posted: 6 years 11 months ago by Ph1lj #11558
Ph1lj's Avatar
OK FIXED it .....
Now I just have to wait for the Picdem to arrive

Forum Activity

  • No posts to display.

Member Access