As introduced in the previous post, we can easily use Google App Engine as a free datastore for this project.
The next step is getting the Arduino Temperature/Humidity Sensor, 7-Segment display and Ethernet Shield into one sketch, receiving a basic response from App Engine.
In order to do this we will:
1) Combine the previous sketches
2) Make app engine respond with the Temperature / Humidity included in the request.
Let's get started.
On the app-engine front, we'll simply want to make a request handler to respond with status code 200, and show the result in a header (for debugging purposes).
That request handler can be as simple as:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Weather(webapp.RequestHandler): | |
def get(self): | |
temp = str(float(cgi.escape(self.request.get('t')))/100) | |
humidity = str(float(cgi.escape(self.request.get('h')))/100) | |
self.response.headers.add_header("X-Arduino-Data", temp +','+ humidity ) |
Stitching the three sketches together yields something like the following (read through the comments for specifics!):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Twitter Client Libraries | |
#include <SPI.h> | |
#include <Ethernet.h> | |
//RHT03 Temperature Humidity Sensor Libraries | |
#include <DHT22.h> | |
//Serial 7-Seg Libraries | |
#include <SoftwareSerial.h> | |
//Included for dtostrf in order to convert Float to String | |
#include <stdio.h> | |
//Setup Serial connection for the 7-Seg display | |
SoftwareSerial mySerial(2, 3); | |
//Pin 7 used for the RHT03 Sensor | |
//Reminder: Connect a 4.7K resistor between VCC and the data pin (strong pullup) | |
#define DHT22_PIN 7 | |
// Setup a DHT22 instance | |
DHT22 myDHT22(DHT22_PIN); | |
//Character array to hold results | |
char s[4]; | |
// Enter a MAC address and IP address for your controller below. | |
// The IP address will be dependent on your local network: | |
byte mac[] = { | |
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01 }; | |
IPAddress ip(192,168,1,20); | |
// initialize the library instance: | |
EthernetClient client; | |
const int requestInterval = 20000; // delay between requests | |
char serverName[] = "feb10yarf.appspot.com"; // AppEngine URL | |
long lastAttemptTime = 0; // last time you connected to the server, in milliseconds | |
String currentLine = ""; // string to hold the text from server | |
boolean requestStatus = false; // helper for client status | |
void setup() { | |
// reserve space for the strings: | |
currentLine.reserve(256); | |
// initialize serial: | |
Serial.begin(9600); | |
Serial.print("Welcome! Will request temp and make API call in 20s"); | |
Serial.println(); | |
// attempt a DHCP connection: | |
if (!Ethernet.begin(mac)) { | |
// if DHCP fails, start with a hard-coded address: | |
Ethernet.begin(mac, ip); | |
} | |
mySerial.begin(2400); // Different Baud rate for 7-seg display - default is 9600 | |
delay(2000); // Wait two seconds on initial run before printing to the 7-seg display | |
mySerial.print("v"); // Print a clear character to the 7-Seg display | |
mySerial.write(0x77); //Special character for display brightness | |
mySerial.write((uint8_t)0x00); //Turn off all Decimal points | |
mySerial.write(0x7A); //Special Character for brightness | |
mySerial.write((uint8_t)0x00); //Set to max brightness | |
} | |
/* | |
Start Loop | |
1) read and format data from temperature sensor | |
2) make app engine request with data in query string | |
*/ | |
void loop() | |
{ | |
// If we made a request, print the response (must finish up before client.stop() in the conditional below) | |
if (client.connected()) { | |
if (client.available()) { | |
// read incoming bytes: | |
char inChar = client.read(); | |
Serial.print(inChar); //this will spit out the response headers and body for debugging | |
} | |
} | |
// Check to see if time has passed to make the next request | |
if (millis() - lastAttemptTime > requestInterval) { | |
DHT22_ERROR_t errorCode; | |
client.stop(); //kill any existing client since we re-establish below | |
delay(1000); | |
// The sensor can only be read from every 1-2s, and requires a minimum | |
// 2s warm-up after power-on. | |
Serial.println(); | |
Serial.print("Requesting temp and humidity data..."); | |
Serial.println(); | |
errorCode = myDHT22.readData(); | |
float temp = myDHT22.getTemperatureC(); | |
temp = (temp*9/5) + 32 - 1; //calibrate here | |
float humidity = myDHT22.getHumidity(); | |
// Convert each value to a string for our request to App Engine | |
String temp_string = dtostrf(temp*100, 4, 0, s); | |
String humidity_string = dtostrf(humidity*100, 4, 0, s); | |
switch(errorCode) | |
{ | |
case DHT_ERROR_NONE: | |
Serial.print("Got Data From Temp Sensor"); | |
mySerial.write(0x77); //Special character to change decimal points | |
mySerial.write(0x02); //Light up middle decimal | |
Serial.println(" "); | |
Serial.print(temp_string); | |
Serial.print("F "); | |
Serial.print(humidity_string); | |
Serial.println("%"); | |
break; | |
case DHT_ERROR_CHECKSUM: | |
Serial.print("check sum error "); | |
Serial.print(myDHT22.getTemperatureC()); | |
Serial.print("C "); | |
Serial.print(myDHT22.getHumidity()); | |
Serial.println("%"); | |
break; | |
case DHT_BUS_HUNG: | |
Serial.println("BUS Hung "); | |
break; | |
case DHT_ERROR_NOT_PRESENT: | |
Serial.println("Not Present "); | |
break; | |
case DHT_ERROR_ACK_TOO_LONG: | |
Serial.println("ACK time out "); | |
break; | |
case DHT_ERROR_SYNC_TIMEOUT: | |
Serial.println("Sync Timeout "); | |
break; | |
case DHT_ERROR_DATA_TIMEOUT: | |
Serial.println("Data Timeout "); | |
break; | |
case DHT_ERROR_TOOQUICK: | |
Serial.println("Polled to quick "); | |
break; | |
} | |
// if you're not connected, and two minutes have passed since | |
// your last connection, then attempt to connect again: | |
// attempt to connect, and wait a millisecond: | |
Serial.println("connecting to server..."); | |
if (client.connect(serverName, 80)) { | |
requestStatus = true; | |
Serial.println("making HTTP request..."); | |
//construct HTTP GET request to app engine: | |
String toGet = "GET /weather/?t="+temp_string+"&h="+humidity_string+" HTTP/1.1"; | |
//Make the request | |
client.println(toGet); | |
//Pass a host header as well | |
client.println("HOST: feb10yarf.appspot.com"); | |
client.println(); | |
} | |
// note the time of this connect attempt: | |
lastAttemptTime = millis(); | |
} | |
} |
Running this sketch yields the following output:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Welcome! Will request temp and make API call in 20s | |
Requesting temp and humidity data... | |
Got Data From Temp Sensor | |
7078F 2700% | |
connecting to server... | |
making HTTP request... | |
HTTP/1.1 200 OK | |
Content-Type: text/html; charset=utf-8 | |
Cache-Control: no-cache | |
X-Arduino-Data: 70.78,27.0 | |
Expires: Fri, 01 Jan 1990 00:00:00 GMT | |
Date: Sun, 29 Jan 2012 21:22:15 GMT | |
Server: Google Frontend | |
Content-Length: 0 | |
Requesting temp and humidity data... | |
Got Data From Temp Sensor | |
7078F 2820% | |
connecting to server... | |
making HTTP request... | |
HTTP/1.1 200 OK | |
Content-Type: text/html; charset=utf-8 | |
Cache-Control: no-cache | |
X-Arduino-Data: 70.78,28.2 | |
Expires: Fri, 01 Jan 1990 00:00:00 GMT | |
Date: Sun, 29 Jan 2012 21:22:35 GMT | |
Server: Google Frontend | |
Content-Length: 0 |
A few Notes:
-Most of the above sketch is comments / case handling for 3rd party libraries.
-If your sketch seems to hang on "connecting to server..." try restarting the sketch using the Arduino's on-board reset button.
In the next post, I will included the complete code used for Google App Engine. As of this moment, the Arduino / Hardware components are complete.
No comments:
Post a Comment