Wireless 1

From Interactive Device Design Fall13
Jump to: navigation, search

Slides

File:Slides-14-wireless1.pdf

Code Examples

We have code examples in a git repo at:

   git://repo.eecs.berkeley.edu/users/bjoern/idd-examples.git

Connecting hardware via serial port to a web server

Your hardware device needs to be connected directly to the machine running your web server. This may be possible in home automation scenarios, but will not work if your device needs to be wireless, mobile, etc. Your web server will then have to open a serial port to exchange data with the device.

  • Node.js example with static pages: idd-examples/web/nodeServerSerial
  • Node.js example with socket.io for real-time updates: idd-examples/web/nodeServerSerialSocket
  • These require NPM, the Node Package Manager. Run npm install in an example directory to download and install required modules. To be able to compile the serial port module, you need to be able to compile native modules - on OS X, this requires XCode, on Windows, some form of Visual Studio. See the serialport documentation. Then sudo npm start to run the server.

Connecting directly to the Web with the CC3000 WiFi breakout board

  • You will connect using the EECS wireless network. This network is available in all of Soda, Cory and SDH. It uses WEP encryption and requires a key. The key is not public but will be provided in class. Furthermore, authentication is by MAC address - meaning only pre-registered devices with known MAC addresses will receive service.

We have pre-registered the modules we'll use in class - their hostname and MAC address are on a sticker on the bottom of the board. Do not change their MAC address in software or the modules will not work on our network! ( More details on available wireless networks are in the IRIS Wireless FAQ).

Wire up the breakout board

  • Follow the Adafruit Tutorial for wiring up the breakout board - the given pin numbers will work on your Boarduino. For reference:
    • IRQ -> D3
    • VBEN ->D5
    • CS -> D10
    • MOSI -> D11
    • MISO -> D12
    • CLK -> D13
    • VIN -> 5V
    • GND -> GND

Cc3000-uno.jpg CC3000-boarduino.jpg

buildtest: Confirm that you can get online

  1. #define WLAN_SSID       "EECS"        // cannot be longer than 32 characters!
  2. #define WLAN_PASS       "WillBeGivenOutInClass"
  3. // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
  4. #define WLAN_SECURITY   WLAN_SEC_WEP
  • Upload and run the buildtest example, then open the Serial monitor at 115200 bps. A successful run will look like this:
Hello, CC3000!
 
RX Buffer : 131 bytes
TX Buffer : 131 bytes
Free RAM: 1233
 
Initialising the CC3000 ...
Firmware V. : 1.24
MAC Address : 0x08 0x01 0x28 0x57 0x34 0x91
Started AP/SSID scan
 
Networks found: 9
================================================
 
SSID Name    : AirBears
RSSI         : 47
Security Mode: 0
 
SSID Name    : EECS
RSSI         : 40
Security Mode: 1
 
...many more skipped here
================================================
 
Deleting old connection profiles
 
Attempting to connect to EECS
Started AP/SSID scan
 
Connecting to EECS...Waiting to connect...Connected!
Request DHCP
 
IP Addr: 128.32.39.58
Netmask: 255.255.254.0
Gateway: 128.32.38.1
DHCPsrv: 1.1.1.1
DNSserv: 128.32.38.21
www.adafruit.com -> 207.58.139.247
 
Pinging 207.58.139.247...2 replies
Ping successful!
 
Closing the connection
  • We tested all boards before handing them out. If your board fails the build test, double check your network settings and your wiring.

Using the CC3000 as a Web Client

Telnet experimentation
$ telnet husk.eecs.berkeley.edu 80
Trying 169.229.63.101...
Connected to husk.eecs.berkeley.edu (169.229.63.101).
Escape character is '^]'.
GET /projects/cc3000/hello.txt HTTP/1.0
[newline]
  • If everything goes well, you should receive a response like the following:
 HTTP/1.1 200 OK
 Date: Mon, 21 Oct 2013 01:20:58 GMT
 Server: Apache/2.2.22 (Unix) mod_python/3.3.1 Python/2.6.1 PHP/5.3.16 mod_ssl/2.2.22 OpenSSL/0.9.8x
 Last-Modified: Sat, 19 Oct 2013 00:47:12 GMT
 ETag: "2340dee-e-4e90d6436c400"
 Accept-Ranges: bytes
 Content-Length: 14
 Cache-Control: max-age=60
 Expires: Mon, 21 Oct 2013 01:21:58 GMT
 MS-Author-Via: DAV
 Connection: close
 Content-Type: text/plain
 
 Hello, CC3000!Connection closed by foreign host.
  • Note the format of the results: one status line reporting protocol version (HTTP/1.1) a status code (200) and a plain text reason (OK). Following that, a set of header lines of form "Header-Name: value", and the body.
  • Not all servers handle HTTP/1.0 requests gracefully. For example try to open http://cc3000-test.nodejitsu.com/hello and you'll get a 400 Bad Request error:
$ telnet cc3000-test.nodejitsu.com 80
Trying 165.225.130.235...
Connected to cc3000-test.nodejitsu.com (165.225.130.235). 
Escape character is '^]'.
GET /hello HTTP/1.0
[newline]
HTTP/1.1 400 Bad Request
[html error page omitted]
  • The minimum viable HTTP/1.1 request that will be accepted needs a "Host: " header and should include a "Connection:close" header:
$ telnet cc3000-test.nodejitsu.com 80
Trying 165.225.130.235...
Connected to cc3000-test.nodejitsu.com (165.225.130.235). 
Escape character is '^]'.
GET /hello HTTP/1.1
Host: cc3000-test.nodejitsu.com
Connection: close
[newline] 
HTTP/1.1 200 OK 
x-powered-by: Express
content-type: text/plain
content-length: 15
date: Mon, 21 Oct 2013 01:36:45 GMT
connection: close

Hello, CC3000!
Connection closed by foreign host.
  • Now we can apply the same approach to retrieving web pages on CC3000.
Retrieve a web page using CC3000
  • Load the Adafruit_CC3000/WebClient example.
  • Change WLAN_SSID, WLAN_PASS, WLAN_SECURITY in lines 44-47.
  • Change WEBSITE, WEBPAGE in lines 50-51 to grab http://husk.eecs.berkeley.edu/projects/cc3000/hello.txt .
  • Understand how the request mirrors what you did in telnet - look at lines 119-132:
/* Try connecting to the website */
  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
  if (www.connected()) {
    www.fastrprint(F("GET "));
    www.fastrprint(WEBPAGE);
    www.fastrprint(F(" HTTP/1.0\r\n"));
    www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE); www.fastrprint(F("\n"));
    www.fastrprint(F("Connection: close\n"));
    www.fastrprint(F("\n"));
    www.println();
  } else {
    Serial.println(F("Connection failed"));    
    return;
  }
  • Successful output should look like this in the Serial monitor:
Hello, CC3000!
 
Free RAM: 1139
 
Initializing...
Started AP/SSID scan
 
Connecting to EECS...Waiting to connect...Connected!
Request DHCP
 
IP Addr: 128.32.39.58
Netmask: 255.255.254.0
Gateway: 128.32.38.1
DHCPsrv: 1.1.1.1
DNSserv: 128.32.38.21
husk.eecs.berkeley.edu -> 169.229.63.101
 
Connect to 169.229.63.101:80
-------------------------------------
HTTP/1.1 200 OK
Date: Mon, 21 Oct 2013 01:48:17 GMT
Server: Apache/2.2.22 (Unix) mod_python/3.3.1 Python/2.6.1 PHP/5.3.16 mod_ssl/2.2.22 OpenSSL/0.9.8x
Last-Modified: Sat, 19 Oct 2013 00:47:12 GMT
ETag: "2340dee-e-4e90d6436c400"
Accept-Ranges: bytes
Content-Length: 14
Cache-Control: max-age=60
Expires: Mon, 21 Oct 2013 01:49:17 GMT
MS-Author-Via: DAV
Connection: close
Content-Type: text/plain
 
Hello, CC3000!-------------------------------------
 
Disconnecting
Send data to a web server using CC3000
  • The easiest way to send data to a web server is to encode it as URL parameters in a GET request as follows:
GET /relative_path?param1=value&param2=value&param3=value... HTTP/1.1
  • URL parameters and values need to be URL-encoded according to RFC3986. Here's a C implementation.
  • We have set up a very simple chat interface with two pages to experiment with URL parameters:
  • Your turn: Modify the WebClient example so your Arduino adds a message to the chat log whenever a button is pressed or released.
  • Hints:
    • SRAM, the memory for runtime variable storage, is in short supply - ATMega 328 has 2k of it. To avoid filling all available SRAM with string, you can also store strings that are constant and known at compile time in Flash memory (program space). ATMega 320 has 32k of Flash memory. The function F("..") that you find in the CC3000 code is used to define a program-space string (previously, this was done with the PROGMEM keyword). More info: http://playground.arduino.cc/Learning/Memory. Program memory strings cannot be changed at runtime so they are not suitable for dynamically assembling strings.
  • As a next step, consider sending sensor data to exisiting web services that consume and visualize such data - take a look at the Adafruit CC3000 Xively tutorial.
Parse structured data received from a web server