Independence Systems Yokohama

My Name is Goro Nishida. I'm a software engineer living in Yokohama, Japan.

*

Using CC3000 Wifi shield

      2015/12/11

Hi, everyone.

This is an arduino shield for the CC3000 WiFi Module.
SparkFun WiFi Shield – CC3000
wifishld1

In this article, I’d like to show you how to use HTTP method(GET and POST) by the shield. First of all, you need to install CC3000 Library. You can do it as follows.
CC3000 Library Installation

I installed CC3000 Library as follows.
0009

0010

HTTP Get method
You can use WebClient Example for HTTP GET Method.
WebClient Example
WS000028

You should change the ap_ssid[] and ap_password[] variables to match your wireless network.
0012

And you can get the response like this. This example gets the HTML document file (http://www.example.com/index.html).
0011

You can also get the HTML document via Web browser.
0013

If you need more details, please refer to the following link.
WebClient Example

HTTP POST Method
I’d like to modify WebClient Example to HTTP POST Method. Before modification, I’d like to check what is “POST Method”. I know that I understand it if I check RFC. In this article, I use “HTTP Resource Test”. It is a Firefox extension for testing HTTP Resources.
HTTP Resource Test

You can post URL encoded variables with “content-type” header to the server as follows using “HTTP Resource Test”.

First, I wrote simple PHP script as follows to print POST parameter variables.

<?php 
    foreach($_POST as $key => $val){
    	print('{' . $key . '} ' . ' => ' . '{' . $val . '} ');
    	print("\n");
    }
?>

And next, You can post variables using HTTP Resource Test.

Launch HTTP Resource Test. And put PHP script URL into URL text box.
WS000029

Select POST Method.
0014

Click Headers tab and click Add button. Select “Content-Type” and “application/x-www-form-urlencoded”.
0015

Click Representation tab and put parameter variables into the text area. In this image, I put “prm1=abc&prm2=xyz&prm3=999”.
0017

Click submit button. And you can get response like this.
0019

According to the above test results, I think you need to specify items as follows to post URL encoded variables. And you need to specify POST method.

header:
“Content-Type: application/x-www-form-urlencoded”
“Content-Length: 999” (999 means length.)
body:
URL encoded variables

This is modified WebClient Example for HTTP POST.

/****************************************************************
WebClient.ino
CC3000 WebClient Test
Shawn Hymel @ SparkFun Electronics
March 1, 2014
https://github.com/sparkfun/SFE_CC3000_Library

Manually connects to a WiFi network and performs an HTTP GET
request on a web page. Prints the contents of the page to
the serial console.

The security mode is defined by one of the following:
WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA, WLAN_SEC_WPA2

Hardware Connections:

 Uno Pin    CC3000 Board    Function

 +5V        VCC or +5V      5V
 GND        GND             GND
 2          INT             Interrupt
 7          EN              WiFi Enable
 10         CS              SPI Chip Select
 11         MOSI            SPI MOSI
 12         MISO            SPI MISO
 13         SCK             SPI Clock

Resources:
Include SPI.h, SFE_CC3000.h, and SFE_CC3000_Client.h

Development environment specifics:
Written in Arduino 1.0.5
Tested with Arduino UNO R3

This code is beerware; if you see me (or any other SparkFun
employee) at the local, and you've found our code helpful, please
buy us a round!

Distributed as-is; no warranty is given.

2015/12/04
Goro Nishida @ Independence Systems Yokohama
For HTTP POST Test.

****************************************************************/

#include <SPI.h>
#include <SFE_CC3000.h>
#include <SFE_CC3000_Client.h>

// Pins
#define CC3000_INT      2   // Needs to be an interrupt pin (D2/D3)
#define CC3000_EN       7   // Can be any digital pin
#define CC3000_CS       10  // Preferred is pin 10 on Uno

// Connection info data lengths
#define IP_ADDR_LEN     4   // Length of IP address in bytes

// Constants
char ap_ssid[] = "TO YOUR_SSID";          // SSID of network
char ap_password[] = "TO YOUR PASSWORD";  // Password of network
unsigned int ap_security = WLAN_SEC_WPA2; // Security of network
unsigned int timeout = 30000;             // Milliseconds
char server[] = "TO YOUR SITE";   // Remote host site

// Global Variables
SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS);
SFE_CC3000_Client client = SFE_CC3000_Client(wifi);

void setup() {

  ConnectionInfo connection_info;
  int i;

  // Initialize Serial port
  Serial.begin(115200);
  Serial.println();
  Serial.println("---------------------------");
  Serial.println("SparkFun CC3000 - WebClient");
  Serial.println("---------------------------");

  // Initialize CC3000 (configure SPI communications)
  if ( wifi.init() ) {
    Serial.println("CC3000 initialization complete");
  } else {
    Serial.println("Something went wrong during CC3000 init!");
  }

  // Connect using DHCP
  Serial.print("Connecting to SSID: ");
  Serial.println(ap_ssid);
  if (!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) {
    Serial.println("Error: Could not connect to AP");
  }

  // Gather connection details and print IP address
  if ( !wifi.getConnectionInfo(connection_info) ) {
    Serial.println("Error: Could not obtain connection details");
  } else {
    Serial.print("IP Address: ");
    for (i = 0; i < IP_ADDR_LEN; i++) {
      Serial.print(connection_info.ip_address[i]);
      if ( i < IP_ADDR_LEN - 1 ) {
        Serial.print(".");
      }
    }
    Serial.println();
  }

  // Make a TCP connection to remote host
  Serial.print("Performing HTTP POST of: ");
  Serial.println(server);
  if ( !client.connect(server, 80) ) {
    Serial.println("Error: Could not make a TCP connection");
  }

  // Make a HTTP POST request
  client.println("POST /yourscript.php HTTP/1.1");
  client.print("Host: ");
  client.println(server);

  // Content-Type
  client.println("Content-Type: application/x-www-form-urlencoded");

  //Body part (url encoded variables)
  String body = String("prm1=abc&prm2=xyz&prm3=efg");
 
  //This is how to convert number to string.
  //(There is no relation for HTTP POST).
  int num = 987;
  String numstr = String(num);
  body = body + numstr;  
    
  // Content-Length
  client.print("Content-Length: "); //no need CR LF
  client.println(body.length());
   
  // Close field
  client.println("Connection: close");
  client.println();
   
  //body 
  client.println(body); 
    
  Serial.println("setup finished.");
}

void loop() {

  // If there are incoming bytes, print them
  if ( client.available() ) {
    char c = client.read();
    Serial.print(c);
  }
  
  // If the server has disconnected, stop the client and wifi
  if ( !client.connected() ) {
    //Serial.println();

    // Close socket
    if ( !client.close() ) {
      Serial.println("Error: Could not close socket");
    }

    // Disconnect WiFi
    if ( !wifi.disconnect() ) {
      Serial.println("Error: Could not disconnect from network");
    }

    // Do nothing
    Serial.println("Finished WebClient test");
    while (true) {
      delay(1000);
    }
  }
}

I got response as follows via serial monitor.

---------------------------
SparkFun CC3000 - WebClient
---------------------------
CC3000 initialization complete
Connecting to SSID: SHL23_AP56
IP Address: 192.168.43.73
Performing HTTP POST of: independence-sys.net
setup finished.
HTTP/1.1 200 OK
Date: Thu, 10 Dec 2015 12:13:00 GMT
Server: Apache
Vary: User-Agent,Accept-Encoding
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

39
{prm1}  => {abc} 
{prm2}  => {xyz} 
{prm3}  => {efg987} 

0

Finished WebClient test

You can find HTTP OK status and posted variables.

What is the number 39 and 0? These are by “Transfer-Encoding: chunked”. These numbers mean size of chunk.

URLEncode
In the case of using “Content-Type: application/x-www-form-urlencoded”, you need to encode parameter values. I posted parameter as follows.

without encoding
prm1=Hello World!
response
{prm1} => {Hello World!}

encoded values
prm1=Hello+Arduino%20World%21
response
{prm1} => {Hello Arduino World!}

On the PHP script, I think you can post without encoding. If you would like to encode values, you can use encoding routine. One of example is as follows.

For Arduino sketch, you can use as follows.

String URLEncode(const char* msg)
{
    const char *hex = "0123456789abcdef";
    String encodedMsg = "";

    while (*msg!='\0'){
        if( ('a' <= *msg && *msg <= 'z')
                || ('A' <= *msg && *msg <= 'Z')
                || ('0' <= *msg && *msg <= '9') ) {
            encodedMsg += *msg;
        } else {
            encodedMsg += '%';
            encodedMsg += hex[*msg >> 4];
            encodedMsg += hex[*msg & 15];
        }
        msg++;
    }
    return encodedMsg;
}

Call as follows.

String body = String("prm1=") + URLEncode("Hello Arduino World!!");

I got response as follows.
{prm1} => {Hello Arduino World!!}

 - Arduino