Using CC3000 Wifi shield
2015/12/11
Hi, everyone.
This is an arduino shield for the CC3000 WiFi Module.
SparkFun WiFi Shield – CC3000
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.
HTTP Get method
You can use WebClient Example for HTTP GET Method.
WebClient Example
You should change the ap_ssid[] and ap_password[] variables to match your wireless network.
And you can get the response like this. This example gets the HTML document file (http://www.example.com/index.html).
You can also get the HTML document via Web browser.
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.
Click Headers tab and click Add button. Select “Content-Type” and “application/x-www-form-urlencoded”.
Click Representation tab and put parameter variables into the text area. In this image, I put “prm1=abc&prm2=xyz&prm3=999”.
Click submit button. And you can get response like this.
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!!}