Last active
December 5, 2017 23:38
-
-
Save fcalderan/7561109 to your computer and use it in GitHub Desktop.
Arduino sketch code and PHP code for H-art tweeting weather station.
This projects was tested with an Arduino UNO + ethernet shield + DHT22 sensor.
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
<?php | |
function roundNum($n) { return round(10 * $n)/10; } | |
// Insert your keys/tokens | |
$consumerKey = '<your-key>'; | |
$consumerSecret = '<your-key>'; | |
$oAuthToken = '<your-key>'; | |
$oAuthSecret = '<your-key>'; | |
// Full path to twitteroauth.php (change oauth to your own path) | |
require_once($_SERVER['DOCUMENT_ROOT'].'/oauth/twitteroauth.php'); | |
// create new instance | |
$tweet = new TwitterOAuth($consumerKey, $consumerSecret, $oAuthToken, $oAuthSecret); | |
/* Create persistent DB connection */ | |
$dbh = new PDO('mysql:host=localhost;dbname=arduino', 'root', '', array( | |
PDO::ATTR_PERSISTENT => true | |
)); | |
/* Insert values read from sensor DHT22 */ | |
$stmt = $dbh->prepare("INSERT INTO dht22 (cdate, ctime, temperature, humidity) VALUES (:cd, :ct, :t, :h)"); | |
$stmt->bindParam(':cd', $cd); | |
$stmt->bindParam(':ct', $ct); | |
$stmt->bindParam(':t', $t); | |
$stmt->bindParam(':h', $h); | |
$cd = date("Y-m-d"); | |
$ct = date("H:i:s"); | |
$t = $_POST['t']; | |
$h = $_POST['h']; | |
$stmt->execute(); | |
/* Count rows inserted */ | |
$collections = 0; | |
$stmt = $dbh->prepare("SELECT COUNT(id) FROM dht22"); | |
if ($stmt->execute()) { | |
$row = $stmt->fetch(); | |
$collections = (int)$row[0]; | |
} | |
echo "{$collections} collections retrieved on database"; | |
$collections_before_tweet = 750; | |
if (($collections % $collections_before_tweet) === 0) { | |
$dt_tweet = date("M j, Y"); | |
$hr_tweet = date("H:i"); | |
$delay = (int) $_POST['i']; // delay in seconds between sensor read | |
$interval = (int) ($collections_before_tweet * $delay / 60); // interval minutes | |
$interval_tweet = "{$interval}m."; | |
if ($interval > 60) { | |
$interval_tweet = floor($interval / 60) . "h." . $interval % 60 . "m."; | |
} | |
$avgquery = "SELECT AVG(temperature), AVG(humidity) "; | |
$avgquery .= "FROM dht22 ORDER BY cdate DESC, ctime DESC "; | |
$avgquery .= "LIMIT {$collections_before_tweet}"; | |
$stmt = $dbh->prepare($avgquery); | |
$avgt = 0; | |
$avgh = 0; | |
if ($stmt->execute()) { | |
$row = $stmt->fetch(); | |
$avgt = roundNum(floatval($row[0])); | |
$avgh = roundNum(floatval($row[1])); | |
} | |
$avgt = number_format($avgt, 1, '.', ''); | |
$avgh = number_format($avgh, 1, '.', ''); | |
// Your Message | |
$message = "On {$dt_tweet} at {$hr_tweet} "; | |
$message .= "H-ART avg. temp. is {$avgt}C "; | |
$message .= "and rel. humidity is {$avgh}% "; | |
$message .= "(observing last ~{$interval_tweet}) "; | |
$message .= "- via #arduino/EthShield #hartmakers"; | |
echo "\n$message"; | |
// Send tweet | |
$tweet->post('statuses/update', array('status' => "$message")); |
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
#include <DHT22.h> | |
#include <SPI.h> | |
#include <Ethernet.h> | |
#include <LiquidCrystal.h> | |
// Data wire is plugged into port 6 on the Arduino | |
// Connect a 4.7K resistor between VCC and the data pin (strong pullup) | |
#define DHT22_PIN 6 | |
int RSpin = 7; | |
int Enablepin = 8; | |
int D4pin = 9; | |
int D5pin = 3; | |
int D6pin = 4; | |
int D7pin = 5; | |
// Setup a DHT22 instance | |
DHT22 myDHT22(DHT22_PIN); | |
// Enter a MAC address for your controller below. | |
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x07, 0xFE }; | |
IPAddress ip(192,168,0,2); | |
char server[] = "192.168.0.1"; | |
EthernetClient client; | |
boolean lastConnected = false; // state of the connection last time through the main loop | |
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds | |
const unsigned long postingInterval = 20 * 1000; // delay between updates, in milliseconds | |
unsigned long lastSensorValues = 0; // state of the last sensor read time through the main loop | |
const unsigned long sensorInterval = 10 * 1000; // delay between sensor read, in milliseconds | |
// initialize the library with the numbers of the interface pins | |
LiquidCrystal lcd(RSpin, Enablepin, D4pin, D5pin, D6pin, D7pin); | |
String tmp = ""; | |
String hum = ""; | |
void setup(void) { | |
// start serial port | |
Serial.begin(9600); | |
lcd.begin(20, 4); | |
lcd.print("H-art (Officina)"); | |
delay(3000); | |
} | |
void httpRequest(String t, String h) { | |
Ethernet.begin(mac, ip); | |
delay(1000); | |
String query = "t=" + t + "&h=" + h + "&i=" + postingInterval/1000; | |
if (client.connect(server, 80)) { | |
Serial.println("connecting..."); | |
// send the HTTP PUT request: | |
client.println("POST /oauth/meteotweet.php HTTP/1.1"); | |
client.println("Host: 192.168.0.1"); | |
client.println("Content-Type: application/x-www-form-urlencoded"); | |
client.println("Connection: close"); | |
client.println("User-Agent: arduino/1.0"); | |
client.print("Content-Length: "); | |
client.println(query.length()); | |
client.println(); | |
client.println(query); | |
client.println(); | |
} | |
else { | |
// if you couldn't make a connection: | |
Serial.println("connection failed"); | |
Serial.println("disconnecting."); | |
client.stop(); | |
} | |
// note the time that the connection was made: | |
lastConnectionTime = millis(); | |
} | |
void getSensorValues(void) { | |
String tmpString = ""; | |
String humString = ""; | |
DHT22_ERROR_t errorCode; | |
errorCode = myDHT22.readData(); | |
switch(errorCode) | |
{ | |
case DHT_ERROR_NONE: | |
Serial.print("Got Data "); | |
Serial.print(myDHT22.getTemperatureC()); | |
Serial.print("C "); | |
Serial.print(myDHT22.getHumidity()); | |
Serial.println("%"); | |
// Alternately, with integer formatting which is clumsier but more compact to store and | |
// can be compared reliably for equality: | |
char buf[128]; | |
sprintf(buf, "Integer-only reading: Temperature %hi.%01hi C, Humidity %i.%01i %% RH", | |
myDHT22.getTemperatureCInt()/10, abs(myDHT22.getTemperatureCInt()%10), | |
myDHT22.getHumidityInt()/10, myDHT22.getHumidityInt()%10); | |
Serial.println(buf); | |
lcd.setCursor(0, 1); | |
tmp = String(myDHT22.getTemperatureCInt()/10) + "." + String(abs(myDHT22.getTemperatureCInt()%10)); | |
tmpString = "Temp: " + tmp + " C"; | |
lcd.print(tmpString); | |
lcd.setCursor(0, 2); | |
hum = String(myDHT22.getHumidityInt()/10) + "." + String(myDHT22.getHumidityInt()%10); | |
humString = "Humidity: " + hum + " %"; | |
lcd.print(humString); | |
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; | |
} | |
lastSensorValues = millis(); | |
} | |
void loop(void) { | |
if (client.available()) { | |
char c = client.read(); | |
Serial.print(c); | |
} | |
// if there's no net connection, but there was one last time | |
// through the loop, then stop the client: | |
if (!client.connected() && lastConnected) { | |
Serial.println(); | |
Serial.println("disconnecting."); | |
client.stop(); | |
} | |
if(millis() - lastSensorValues > sensorInterval) { | |
getSensorValues(); | |
} | |
// if you're not connected, and ten seconds have passed since | |
// your last connection, then connect again and send data: | |
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) { | |
httpRequest(tmp, hum); | |
} | |
// store the state of the connection for next time through | |
// the loop: | |
lastConnected = client.connected(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment