I'm currently trying to build an Arduino robot controlled via a wifi connection. I have an Arduino Mega running as a client and it successfully connects to the server on LAN via the Adafruit cc3000 wifi board. However instead of grabbing the contents of the JSON file and printing it to serial, I'm just getting a 100 continue response. While this means I'm doing something right, I don't know what to do next in order to grab the data I need. Do I need to get the 100 message then respond with the GET request, or is there a way that I can GET the data straight away?
Thank you all in advance. Here is the Arduino code I have so far:
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include <stdlib.h>
// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin!
#define ADAFRUIT_CC3000_VBAT 5 // Apparently these can be any two pins
#define ADAFRUIT_CC3000_CS 10 // But I wouldn't change these...
// Use hardware SPI for the remaining pins (On a Mega 2560, SCK = 52, MISO = 50, and MOSI = 51)
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);
#define WLAN_SSID "VM540258-2G"
#define WLAN_PASS "XXXXXXXX"
#define WLAN_SECURITY WLAN_SEC_WPA2
String readString = String(100); //string for fetching data from address
uint32_t ip = 3232235523; // This translates into the ip address we need
// 323223552X; 192.168.0.X
void setup(){
Serial.begin(115200); //Can also work at 9600
//Initialise CC3000 module
Serial.println(F("\nInitializing CC3000..."));
if (!cc3000.begin())
{
Serial.println(F("Couldn't begin()! Check your wiring?"));
while(1);
}
//Connect to the Wireless Access Point
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
Serial.println(F("Failed!"));
while(1);
}
Serial.println(F("Connected!"));
Serial.println(F("Request DHCP"));
while (!cc3000.checkDHCP()) { //Obtain IP addeess
delay(100);
}
while (! displayConnectionDetails())
{
delay(1000);
}
}
void loop(){
Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
if (client.connected()) {
client.println("GET /project-test/state.json HTTP/1.0"); //Make a request for state.json
client.println(""); //Mandatory blank line?
if (client.available()){
char c = client.read();
Serial.print(c);
//read char by char HTTP request
if (readString.length() < 100) {
//store characters to string
readString += c;
}
}
}
//Once we have obtained the data, disconnect from the server
client.close();
Serial.println(readString);
delay(1000);
}
bool displayConnectionDetails(void)
{
uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
{
Serial.println(F("Unable to retrieve the IP Address!\r\n"));
return false;
}
else
{
Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
Serial.println();
return true;
}
}
The initial JSON file I'm using contains the following:
{"speed_left":null,"speed_right":null,"direction_left":null,"direction_right":null}
And the serial output I get when I run the Sketch:
Initializing CC3000...
Started AP/SSID scan
Connecting to VM540258-2G...Waiting to connect...Connected!
Request DHCP
IP Addr: 192.168.0.7
Netmask: 255.255.255.0
Gateway: 192.168.0.1
DHCPsrv: 192.168.0.1
DNSserv: 192.168.0.1
Connect to 192.168.0.3:80
100
Connect to 192.168.0.3:80
100
ad infinitum
3 Answers 3
you are missing the HOST
header in the request, so the server tell you to 100 CONTINUE
you request.
Also yes, the final empty row IS mandatory
for example, to ask www.example.com/index.html
GET /index.html HTTP/1.1
Host: www.example.com
-
The Host header isn't required under HTTP/1.0, which is what he appears to be using. Those were the days before we hosted multiple websites on the same server.Bill Nace– Bill Nace2014年04月14日 21:17:21 +00:00Commented Apr 14, 2014 at 21:17
-
you are right, tecnically is not, but many server does not care, i'm quite sure as i can replicate this with google's server by telnetLesto– Lesto2014年04月14日 21:23:51 +00:00Commented Apr 14, 2014 at 21:23
I'm going to guess that it's a problem with your server not expecting an HTTP/1.0 request. I note the following from RFC 1945 about the response codes:
9.1 Informational 1xx
This class of status code indicates a provisional response, consisting only of the Status-Line and optional headers, and is terminated by an empty line. HTTP/1.0 does not define any 1xx status codes and they are not a valid response to a HTTP/1.0 request. However, they may be useful for experimental applications which are outside the scope of this specification.
I'd recommend changing your request to be HTTP/1.1 compliant (with a Host: header as suggested by @lesto)
-
This seems to support the idea that the server is ignoring the http/1.0 and act as HTTP/1.1 insteadLesto– Lesto2014年04月15日 08:47:08 +00:00Commented Apr 15, 2014 at 8:47
Okay, I have a better answer, again done without testing.
If I look at the BNF for an HTTP-message from the RFC, it indicates that the message body is terminated by a blank line.
So, you actually need 2 CRLFs (i.e. 2 blank lines). The first one separates the headers from the body of the HTTP request. You don't actually have a message body (which is fine, it is optional). But, you'll need another CRLF to terminate the (blank) body.
Since you only sent one blank line, the server is sending you the continue status codes, prompting you to finish sending your message (i.e. the message body).
So, try adding another client.println("");