Created
March 24, 2015 20:31
-
-
Save jimblom/8bf222c059bd92a3e10a to your computer and use it in GitHub Desktop.
Photon_Weather_Report
This file contains hidden or 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
/** | |
* Phant.cpp | |
* | |
* .-.._ | |
* __ /` '. | |
* .-' `/ ( a \ | |
* / ( \,_ \ | |
* /| '---` |\ =| | |
* ` \ /__.-/ / | | | |
* | / / \ \ \ \_\ jgs | |
* |__|_| |_|__\ | |
* never forget. | |
* | |
* Author: Todd Treece <[email protected]> | |
* | |
* Copyright (c) 2014 SparkFun Electronics. | |
* Licensed under the GPL v3 license. | |
* | |
*/ | |
#include "Phant.h" | |
#include <stdlib.h> | |
Phant::Phant(String host, String publicKey, String privateKey) { | |
_host = host; | |
_pub = publicKey; | |
_prv = privateKey; | |
_params = ""; | |
} | |
void Phant::add(String field, String data) { | |
_params += "&" + field + "=" + data; | |
} | |
void Phant::add(String field, char data) { | |
_params += "&" + field + "=" + String(data); | |
} | |
void Phant::add(String field, int data) { | |
_params += "&" + field + "=" + String(data); | |
} | |
void Phant::add(String field, byte data) { | |
_params += "&" + field + "=" + String(data); | |
} | |
void Phant::add(String field, long data) { | |
_params += "&" + field + "=" + String(data); | |
} | |
void Phant::add(String field, unsigned int data) { | |
_params += "&" + field + "=" + String(data); | |
} | |
void Phant::add(String field, unsigned long data) { | |
_params += "&" + field + "=" + String(data); | |
} | |
void Phant::add(String field, double data) { | |
char tmp[30]; | |
//dtostrf(data, 1, 4, tmp); | |
sprintf(tmp, "%f", data); | |
_params += "&" + field + "=" + String(tmp); | |
} | |
void Phant::add(String field, float data) { | |
char tmp[30]; | |
//dtostrf(data, 1, 4, tmp); | |
sprintf(tmp, "%f", data); | |
_params += "&" + field + "=" + String(tmp); | |
} | |
String Phant::queryString() { | |
return String(_params); | |
} | |
String Phant::url() { | |
String result = "http://" + _host + "/input/" + _pub + ".txt"; | |
result += "?private_key=" + _prv + _params; | |
_params = ""; | |
return result; | |
} | |
String Phant::get() { | |
String result = "GET /output/" + _pub + ".csv HTTP/1.1\n"; | |
result += "Host: " + _host + "\n"; | |
result += "Connection: close\n"; | |
return result; | |
} | |
String Phant::post() { | |
String params = _params.substring(1); | |
String result = "POST /input/" + _pub + ".txt HTTP/1.1\n"; | |
result += "Host: " + _host + "\n"; | |
result += "Phant-Private-Key: " + _prv + "\n"; | |
result += "Connection: close\n"; | |
result += "Content-Type: application/x-www-form-urlencoded\n"; | |
result += "Content-Length: " + String(params.length()) + "\n\n"; | |
result += params; | |
_params = ""; | |
return result; | |
} | |
String Phant::clear() { | |
String result = "DELETE /input/" + _pub + ".txt HTTP/1.1\n"; | |
result += "Host: " + _host + "\n"; | |
result += "Phant-Private-Key: " + _prv + "\n"; | |
result += "Connection: close\n"; | |
return result; | |
} |
This file contains hidden or 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
/** | |
* Phant.h | |
* | |
* .-.._ | |
* __ /` '. | |
* .-' `/ ( a \ | |
* / ( \,_ \ | |
* /| '---` |\ =| | |
* ` \ /__.-/ / | | | |
* | / / \ \ \ \_\ jgs | |
* |__|_| |_|__\ | |
* never forget. | |
* | |
* Author: Todd Treece <[email protected]> | |
* | |
* Copyright (c) 2014 SparkFun Electronics. | |
* Licensed under the GPL v3 license. | |
* | |
*/ | |
#ifndef Phant_h | |
#define Phant_h | |
#include "application.h" | |
class Phant { | |
public: | |
Phant(String host, String publicKey, String privateKey); | |
void add(String field, String data); | |
void add(String field, char data); | |
void add(String field, int data); | |
void add(String field, byte data); | |
void add(String field, long data); | |
void add(String field, unsigned int data); | |
void add(String field, unsigned long data); | |
void add(String field, float data); | |
void add(String field, double data); | |
String queryString(); | |
String url(); | |
String get(); | |
String post(); | |
String clear(); | |
private: | |
String _pub; | |
String _prv; | |
String _host; | |
String _params; | |
}; | |
#endif |
This file contains hidden or 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
#include "SFE_DHT22.h" | |
DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) { | |
_pin = pin; | |
_type = type; | |
_count = count; | |
firstreading = true; | |
} | |
void DHT::begin(void) { | |
// set up the pins! | |
pinMode(_pin, INPUT); | |
digitalWrite(_pin, HIGH); | |
_lastreadtime = 0; | |
} | |
float DHT::readTemperature() { | |
float f; | |
if (read()) { | |
switch (_type) { | |
case DHT11: | |
f = data[2]; | |
return f; | |
case DHT22: | |
case DHT21: | |
f = data[2] & 0x7F; | |
f *= 256; | |
f += data[3]; | |
f /= 10; | |
if (data[2] & 0x80) | |
f *= -1; | |
return f; | |
} | |
} | |
return NAN; | |
} | |
float DHT::getHumidity() { | |
return readHumidity(); | |
} | |
float DHT::getTempCelcius() { | |
return readTemperature(); | |
} | |
float DHT::getTempFarenheit() { | |
return convertCtoF(readTemperature()); | |
} | |
float DHT::getTempKelvin() { | |
return convertCtoK(readTemperature()); | |
} | |
float DHT::getHeatIndex() { | |
return convertFtoC(computeHeatIndex(convertCtoF(readTemperature()), readHumidity())); | |
} | |
float DHT::getDewPoint() { | |
return computeDewPoint(readTemperature(), readHumidity()); | |
} | |
float DHT::convertFtoC(float f) { | |
return (f - 32) * 5 / 9; | |
} | |
float DHT::convertCtoF(float c) { | |
return c * 9 / 5 + 32; | |
} | |
float DHT::convertCtoK(float c) { | |
return c + 273.15; | |
} | |
float DHT::readHumidity(void) { | |
float f; | |
if (read()) { | |
switch (_type) { | |
case DHT11: | |
f = data[0]; | |
return f; | |
case DHT22: | |
case DHT21: | |
f = data[0]; | |
f *= 256; | |
f += data[1]; | |
f /= 10; | |
return f; | |
} | |
} | |
return NAN; | |
} | |
float DHT::computeHeatIndex(float tempFahrenheit, float percentHumidity) { | |
// Adapted from equation at: https://github.com/adafruit/DHT-sensor-library/issues/9 and | |
// Wikipedia: http://en.wikipedia.org/wiki/Heat_index | |
return -42.379 + | |
2.04901523 * tempFahrenheit + | |
10.14333127 * percentHumidity + | |
-0.22475541 * tempFahrenheit * percentHumidity + | |
-0.00683783 * pow(tempFahrenheit, 2) + | |
-0.05481717 * pow(percentHumidity, 2) + | |
0.00122874 * pow(tempFahrenheit, 2) * percentHumidity + | |
0.00085282 * tempFahrenheit * pow(percentHumidity, 2) + | |
-0.00000199 * pow(tempFahrenheit, 2) * pow(percentHumidity, 2); | |
} | |
float DHT::computeDewPoint(float tempCelcius, float percentHumidity) { | |
double a = 17.271; | |
double b = 237.7; | |
double tC = (a * (float) tempCelcius) / (b + (float) tempCelcius) + log( (float) percentHumidity / 100); | |
double Td = (b * tC) / (a - tC); | |
return Td; | |
} | |
boolean DHT::read(void) { | |
uint8_t laststate = HIGH; | |
uint8_t counter = 0; | |
uint8_t j = 0, i; | |
unsigned long currenttime; | |
// Check if sensor was read less than two seconds ago and return early | |
// to use last reading. | |
currenttime = millis(); | |
if (currenttime < _lastreadtime) { | |
// ie there was a rollover | |
_lastreadtime = 0; | |
} | |
if (!firstreading && ((currenttime - _lastreadtime) < 2000)) { | |
return true; // return last correct measurement | |
// delay(2000 - (currenttime - _lastreadtime)); | |
} | |
firstreading = false; | |
/* | |
Serial.print("Currtime: "); Serial.print(currenttime); | |
Serial.print(" Lasttime: "); Serial.print(_lastreadtime); | |
*/ | |
_lastreadtime = millis(); | |
data[0] = data[1] = data[2] = data[3] = data[4] = 0; | |
// pull the pin high and wait 250 milliseconds | |
digitalWrite(_pin, HIGH); | |
delay(250); | |
// now pull it low for ~20 milliseconds | |
pinMode(_pin, OUTPUT); | |
digitalWrite(_pin, LOW); | |
delay(20); | |
noInterrupts(); | |
digitalWrite(_pin, HIGH); | |
delayMicroseconds(40); | |
pinMode(_pin, INPUT); | |
// read in timings | |
for ( i=0; i< MAXTIMINGS; i++) { | |
counter = 0; | |
while (digitalRead(_pin) == laststate) { | |
counter++; | |
delayMicroseconds(1); | |
if (counter == 255) { | |
break; | |
} | |
} | |
laststate = digitalRead(_pin); | |
if (counter == 255) break; | |
// ignore first 3 transitions | |
if ((i >= 4) && (i%2 == 0)) { | |
// shove each bit into the storage bytes | |
data[j/8] <<= 1; | |
if (counter > _count) | |
data[j/8] |= 1; | |
j++; | |
} | |
} | |
interrupts(); | |
/* | |
Serial.println(j, DEC); | |
Serial.print(data[0], HEX); Serial.print(", "); | |
Serial.print(data[1], HEX); Serial.print(", "); | |
Serial.print(data[2], HEX); Serial.print(", "); | |
Serial.print(data[3], HEX); Serial.print(", "); | |
Serial.print(data[4], HEX); Serial.print(" =? "); | |
Serial.println(data[0] + data[1] + data[2] + data[3], HEX); | |
*/ | |
// check we read 40 bits and that the checksum matches | |
if ((j >= 40) && | |
(data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) { | |
return true; | |
} | |
return false; | |
} |
This file contains hidden or 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
#ifndef SFE_DHT22_H | |
#define SFE_DHT22_H | |
#include "application.h" | |
#include "math.h" | |
// how many timing transitions we need to keep track of. 2 * number bits + extra | |
#define MAXTIMINGS 85 | |
#define DHT11 11 | |
#define DHT22 22 | |
#define DHT21 21 | |
#define AM2301 21 | |
class DHT { | |
private: | |
uint8_t data[6]; | |
uint8_t _pin, _type, _count; | |
unsigned long _lastreadtime; | |
boolean firstreading; | |
float readTemperature(); | |
float convertFtoC(float); | |
float convertCtoF(float); | |
float convertCtoK(float); | |
float computeHeatIndex(float tempFahrenheit, float percentHumidity); | |
float computeDewPoint(float tempCelcius, float percentHumidity); | |
float readHumidity(void); | |
boolean read(void); | |
public: | |
DHT(uint8_t pin, uint8_t type, uint8_t count=6); | |
void begin(void); | |
float getHumidity(); | |
float getTempCelcius(); | |
float getTempFarenheit(); | |
float getTempKelvin(); | |
float getHeatIndex(); | |
float getDewPoint(); | |
}; | |
#endif |
This file contains hidden or 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
#include "Phant.h" | |
#include "SFE_DHT22.h" | |
int lightSensor = A0; | |
#define DHTPIN 2 // what pin we're connected to | |
#define DHTTYPE DHT22 // DHT 22 (AM2302) | |
DHT dht(DHTPIN, DHTTYPE); | |
const char server[] = "data.sparkfun.com"; | |
const char publicKey[] = "zDaREyrLnGfAQxdyxJLA"; | |
const char privateKey[] = "Yy4eqKJMZwTqPM69Mypq"; | |
Phant phant(server, publicKey, privateKey); | |
const int POST_RATE = 30000; // Time between posts, in ms. | |
unsigned long lastPost = 0; | |
void setup() | |
{ | |
Serial.begin(9600); | |
pinMode(lightSensor, INPUT); | |
dht.begin(); | |
postToPhant(); | |
} | |
void loop() | |
{ | |
if (lastPost + POST_RATE < millis()) | |
{ | |
if (postToPhant() > 0) | |
{ | |
lastPost = millis(); | |
} | |
} | |
printWeather(); | |
delay(1000); | |
} | |
int postToPhant() | |
{ | |
// Reading temperature or humidity takes about 250 milliseconds! | |
// Sensor readings may also be up to 2 seconds 'old' (its a | |
// very slow sensor) | |
float h = dht.getHumidity(); | |
// Read temperature as Celsius | |
float t = dht.getTempCelcius(); | |
// Read temperature as Farenheit | |
float f = dht.getTempFarenheit(); | |
// Check if any reads failed and exit early (to try again). | |
if (isnan(h) || isnan(t) || isnan(f)) { | |
//Serial.println("Failed to read from DHT sensor!"); | |
return -4; | |
} | |
float hi = dht.getHeatIndex(); | |
float dp = dht.getDewPoint(); | |
phant.add("room1_light", analogRead(lightSensor)); | |
phant.add("room1_temp", t); | |
phant.add("room2_light", hi); | |
phant.add("room2_temp", f); | |
phant.add("room3_humidity", h); | |
TCPClient client; | |
char response[512]; | |
int i = 0; | |
int retVal = 0; | |
if (client.connect(server, 80)) | |
{ | |
Serial.println("Posting!"); | |
client.print(phant.post()); | |
delay(1000); | |
while (client.available()) | |
{ | |
char c = client.read(); | |
//Serial.print(c); | |
if (i < 512) | |
response[i++] = c; | |
} | |
if (strstr(response, "200 OK")) | |
{ | |
Serial.println("Post success!"); | |
retVal = 1; | |
} | |
else if (strstr(response, "400 Bad Request")) | |
{ | |
Serial.println("Bad request"); | |
retVal = -1; | |
} | |
else | |
{ | |
retVal = -2; | |
} | |
} | |
else | |
{ | |
Serial.println("connection failed"); | |
retVal = -3; | |
} | |
client.stop(); | |
return retVal; | |
} | |
void printWeather() | |
{ | |
// Reading temperature or humidity takes about 250 milliseconds! | |
// Sensor readings may also be up to 2 seconds 'old' (its a | |
// very slow sensor) | |
float h = dht.getHumidity(); | |
// Read temperature as Celsius | |
float t = dht.getTempCelcius(); | |
// Read temperature as Farenheit | |
float f = dht.getTempFarenheit(); | |
// Check if any reads failed and exit early (to try again). | |
if (isnan(h) || isnan(t) || isnan(f)) { | |
//Serial.println("Failed to read from DHT sensor!"); | |
return; | |
} | |
// Compute heat index | |
// Must send in temp in Fahrenheit! | |
float hi = dht.getHeatIndex(); | |
float dp = dht.getDewPoint(); | |
float k = dht.getTempKelvin(); | |
Serial.print("Light: "); | |
Serial.println(analogRead(lightSensor)); | |
Serial.print("Humid: "); | |
Serial.print(h); | |
Serial.print("% - "); | |
Serial.print("Temp: "); | |
Serial.print(t); | |
Serial.print("*C "); | |
Serial.print(f); | |
Serial.print("*F "); | |
Serial.print(k); | |
Serial.print("*K - "); | |
Serial.print("DewP: "); | |
Serial.print(dp); | |
Serial.print("*C - "); | |
Serial.print("HeatI: "); | |
Serial.print(hi); | |
Serial.println("*C"); | |
Serial.println(Time.timeStr()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment