1

I'm struggling to get the CC3000 to connect to a heroku hosted app, and other examples posted online haven't turned on the light bulb quite yet for me.

The gist is that I collect some temperature and humidity readings, and then send those via a GET request using the CC3000. The heroku app then reads the parameters and displays them on a page.

The CC3000 hardware is A-OK, as I've tested it using the test sketches. The sketch I've put together (on github: https://github.com/jsimms/compost_monitor) works except for the last bit where it needs to connect to the server and send the HTTP request. Which makes me wonder if this is a heroku quirk, or if I'm just screwing something up right at the finish line.

First, I define everything

#define WEBSITE      "myapp.herokuapp.com"
String route = "/sensor";
uint32_t ip;
int port = 80; 

Then during setup, I use getHostByName to assign the ip variable. I print it out, just to confirm it was able to snag an ip. I then close it to make sure I don't screw up anything during the loop.

  ip = 0;
  Serial.print(WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }

  cc3000.printIPdotsRev(ip);
  Serial.println("");

  // Close the connection
  Serial.println(F("Closing connection..."));
  cc3000.disconnect();
  Serial.println(F("Connection closed."));

During the loop, I create a String with the request, and then call a function that actually does the request.

String request = "GET " + route + "?temp=" + temperature + "&hum=" + humidity + " HTTP/1.0\r\n";
send_request(request);

Finally, the send_request function is supposed to take care of connecting via TCP and sending it.

void send_request (String request)
{
  // Connect to server 
  Serial.println("Connecting to server...");
  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, port); 

  // Send the request 
  if (www.connected()) {
      www.println(request);
      www.println(F("User-agent: CompostMonitor/1.0\r\n"));      
      www.println(F("\r\n"));
      Serial.println("Connected & data sent successfully...");
    } 
    else {
      Serial.println(F("Connection failed."));    
    }

    while (www.connected()) {
      while (www.available()) {

      // Read answer
      char c = www.read();
      Serial.println(c); 
      }
    }

  // Disconnect 
  Serial.println("Closing connection...");
  Serial.println(""); 
  www.close(); 
}

However, I never get anything but connection failed.

Any insight and help would be wonderfully appreciated. :)

UPDATE: Ok. So, through the comments below, I was able to identify by telnet'ing the web app, that there was something wrong with the HTTP requests. I made a small tweak to the app, but the real issue was that I wasn't including Host: weathervane.herokuapp.com in the header. FML! I'm going to test out sending the request with the Arduino later tonight. Hopefully that puts an end to this HTTP 101 lesson I've been doing.

0

2 Answers 2

2

Have a look at this code: https://github.com/adafruit/Adafruit_CC3000_Library/blob/master/examples/SendTweet/SendTweet.ino

There is a delay after cc3000.connectTCP to wait for connection. Your code does not wait for the connection and thus gives 'connection failed' straight away.

Serial.print(F("OK\r\nConnecting to server..."));
t = millis();
do {
    client = cc3000.connectTCP(ip, 80);
} while((!client.connected()) &&
    ((millis() - t) < connectTimeout));

if(client.connected()) { // Success!

etc

Edit based on comment:

getHostByName returns positive value on success and negative on failure. Therefore the check should be

if (cc3000.getHostByName(WEBSITE, &ip) < 0)

Also try putting http:// in the website address

10
  • That's a very good point. I did put in the timeout, however, it still does not successfully connect. Part of me wonders if I'm missing something important in regards to Heroku architecture. In addition to the timeout, I tried two things - first, I tried using port 5000 - this did not work. Second, I moved the getHostByName lookup into the send_request function. This resulted in a "could not resolve" error message. Both for ports 80 and 5000.
    – Jake Simms
    May 29, 2014 at 15:55
  • @JakeSimms please see edits to answer May 30, 2014 at 11:55
  • @JakeSimms I wonder if it wasn't getting the right address May 30, 2014 at 11:58
  • @JakeSimms Oh, what happens if you don't disconnect? It might be that because you disconnect the socket you can't connect the TCP connection. That might be why getHostByName fails when you move it into send_request. May 30, 2014 at 12:05
  • If you use http:// it actually hangs everything up. Even in their examples. Not sure why. One thing I did not do your other suggestions yet, mainly because I'm unsure if the sketch is the issue anymore. I'm getting bad gateway and bad request errors as you can see in the printout. Which is strange because things work fine in a browser.
    – Jake Simms
    May 30, 2014 at 22:24
0
www.println(request);
www.println(F("User-agent: CompostMonitor/1.0\r\n"));      
www.println(F("\r\n"));

Both request and the other two strings end with \r\n. You also use println(), which adds \r\n of itself. This means that you end every line with two CRLF sequences, which is not correct according to the HTTP standard (Sec 2.2, Basic Rules).

Instead, use print() which doesn't add anything, or don't add \r\n to the strings yourself.

Servers may not complain about this but your code is not conform the standard and may not work on all servers / may stop working after a server update. It's also possible that some of the header fields are not being considered by the server because it treats them as body instead of headers.


Besides that, you should considering use HTTP 1.1. There's no hard reason to change now, but it's newer, includes more features, is supported by (almost) all server software, and will still work even when (if) servers decide to start phasing out HTTP 1.0 support. You then need to change 1.0 to 1.1 in the request string, and after that specify the Host field explicitly:

www.println("Host: myapp.herokuapp.com");

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.