Monday, December 14, 2009

Arduino: Standalone wifi http messenger (expanded version)

I've Had some interest in this post, so I'm writing up a longer definition detailing some of the ins and out of the arduino, where you can buy specific parts and how the parts fit together. Note if you already know about the Arduino and shields, you should jump straight to the "On the Code" section below.


Some hardware stuff:


The arduino comes in a variety of forms with the arduino duemilanove being a very popular one. This is the one that I use for my projects and includes the chip itself (an Atmiga 328) along with a usb port for transferring programs / power and an actual power plug. The Atmega 328 itself has a bootloader flashed onto it (a small program that handles uploading "sketches", which are  programs). It has 2k of RAM on the chip and 32k of ROM in which to install programs (although ~2k of ROM is used by the boot loader). In function, the chip supports 14 digital I/O pins  and 6 analogue I/O pins. Of th 14 digital pins, 6 support PWM for a form of analogue output. For an introduction to the arduino I would suggest starting at http://www.ladyada.net/learn/arduino/index.html that goes through some simple programs accessing the pins and setting up the software to create programs. Basically on the software side the arudino uses a java IDE that works with "sketches" in c like syntax. These are compiled and uploaded quite simply by the program. Also, being built in java there is a version available for windows, mac and linux.

In terms of buying the hardware to start with, there are a number of online stores that sell both the arduino and the wishield. A good place to start is adafruit (http://www.adafruit.com/index.php? main_page=product_info&cPath=17&products_id=68) or sparkfun (http://www.sparkfun.com/commerce/product_info.php?products_id=666). The adafruit link there is to a pack that includes a charger, lights, resistors and a heap of other stuff that makes it easy to start off with the arduino. If you do a google search though it is quite possible to find a vendor closer to your area. From these sites you can also buy a range of LCD screens. A lot of character driven displays (ones with eg 20x4 characters) are the same and are based on the HD44780 chip which makes them very easy to set up and use. For reference, I got mine from here: http://toysdownunder.com/arduino/lcd/lcd-5v-blue-20x4.html. Unfortunately I am have a hard time finding the wishield on adafruit or sparkfun, but I got mine from here: http://toysdownunder.com/arduino/arduino-shields/arduino-wifi-shield.html. Also unfortunately this is in Australia (where I'm from) so you might have to email the owner of the site if you go through him to sort out sending overseas. You could also buy from asynclabs direct at their store: http://asynclabs.com/store?page=shop.browse&category_id=6.

For the wishield, this is an attachment (a "shield" as they are called) that plugs into the top of the arduino to extend it's features. Basically, the 20 pins out from the arduino are aligned on either side of the board as female plugs. Shields extend the arduino's features by plugging into these with a male on the bottom of the board and extending through to a female at the top. It may be easier to explain this by looking at pictures of the arduino and wishield. The pins on the bottom of the wishield plug into the top of the arduino. This can cause some problems though as while all the pins are extended through to the top of the shield (so you can plug other things in), some are used by the wishield itself and cannot be used. On this build I had to take care not to use specific pins used by the wishield with the LCD (because both used quite a lot). In hindsite it probably would have been better to use just an ethernet shield rather than a wifi one. It would probably use less pins and the wifi adds another possible problem to development. An ethernet shield would also be much cheaper.

For further reading on all of these topics I would suggest:

1. The arduino tutorial site I talked bout above (http://www.ladyada.net/learn/arduino/index.html)
2. After installing the arduino software it comes with a large range of examples programs to look at, pull apart etc.
3. The arduino site also has a lot of tutorials about all sorts of arduino activities (http://arduino.cc/en/Tutorial/HomePage)
4. For the LCD specifically the arudino site has a good writeup on how to talk to it (http://arduino.cc/en/Tutorial/LiquidCrystal) via the liquidcrystal library. (http://www.arduino.cc/en/Reference/LiquidCrystal)
5. For the wishield specifically the asynclabs wiki will explain how to set it up along with sample programs (http://asynclabs.com/wiki/index.php?title=AsyncLabsWiki)
6. The arduino.cc forum is a great place for more advanced stuff (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl).

On to the code:


The server is very simple and is implemented in code as a header file; this is because of the relatively low power of the arduino. To explain how it works I will first explain a normal web server. In a normal web server everything is separate and largely reliant on operating system functions. The operating would handle the network interface via a driver to control it. It would accept packets sent to it, deconstruct them and send the information within them onto the server (eg Apache web server) that would act upon them. In general this means to check the URI (Uniform Resource Identifier) for the page required. The server program gets that page from the hard drive (again via operating system calls), compiles it as required and sends the information back to the OS to be put into packets and sent. Most of the functionality therefore is performed by the operating system with the server only required to generate the page. The page itself can be written in a multitude of web languages (in plain text) because the web browser compiles and maintains the pages automatically. In terms of the OSI Model the operating system performs all functions up to session (the sixth), with the web server only fulfilling the application layer.

The arduino + wishield handles serving web pages at a much lower level. The wishield itself has a driver that is written in c and compiled into the program when you create it. This handles the set up / configuration (which pins to use etc.) as well as general running of the wishield. The device as a whole splits the network stack between the arduino and the wishield. The wishield handles the OSI model up to around session before handing data off to the arduino for processing. The reason for this of course is that the arduino itself only has 2k of RAM; a full size Ethernet packet (1492 bytes) would largely fill this. The wishield however is a dump chip that requires a reasonable amount of arduino side programming to make it work.

The server itself is also written in c and loaded as a header. I used the SimpleServer application as a basis; It is available in File -> Examples -> WiShield -> SimpleServer once you have installed the wishield drivers and examples. This server handles the sockets and connections, accepting requests for a web page (GET) and returning status 200 (OK) along with a coded web page. With the use of constructs, variables, etc you can then check the requested URL and send whichever page is required. For a much simpler project involving this webserver you should check out my led server writeup at http://asynclabs.com/forums/viewtopic.php?f=18&t=104. This checks the url and turns a set of leds on or off as required. For a step in the other direction, you could check out tjk's wifi SMS gateway project at http://asynclabs.com/forums/viewtopic.php?f=18&t=89. For more generic information on the server itself you should check out the asynclabs example wiki page at http://asynclabs.com/wiki/index.php?title=AsyncLabsWiki, or a short page on the webserver itself at http://asynclabs.com/wiki/index.php?title=WebServer_sketch.

In terms of setting up the wishield on a network, this is hard coded into the software before it is uploaded. It may be possible to set up the network after the setup of the device, but I didn't have to go into it. The specific section of the code if you are interested comes looks like this:

// Wireless configuration parameters ----------------------------------------

unsigned char local_ip[] = {10,1,1,5};    // IP address of WiShield

unsigned char gateway_ip[] = {192,168,1,1}; // router or gateway IP address

unsigned char subnet_mask[] = {255,0,0,0};   // subnet mask for the local network

const prog_char ssid[] PROGMEM = {"DLINK"};             // max 32 bytes

unsigned char security_type = 0;        // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2

// WPA/WPA2 passphrase

const prog_char security_passphrase[] PROGMEM = {"12345678"};   // max 64 characters

// WEP 128-bit keys

// sample HEX keys

prog_uchar wep_keys[] PROGMEM = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,     // Key 0

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     // Key 1

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,     // Key 2

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00      // Key 3

};

// setup the wireless mode

// infrastructure - connect to AP

// adhoc - connect to another WiFi device

Here I set up a simple connection without encryption on the 10.1.1.5 network. The default gateway is left at 192.168.1.1 because my build did not need client access to the internet. It uses the 255.0.0.0 subnet and will automatically try to connect to the "DLINK" network.

This will do for now. If anyone else has any questions post them here and I will update this page. Also if you spot anything wrong or worthy of improvement drop me a line at kimbecause -a-t- gmail dot com.

0 comments:

Post a Comment