Les mer om 1Wire Templogging med Arduino
Jeg har også laget 3.5mm jack kontakter til LDR sensor, lcd og 1Wire nettet. Dette satt jeg på et custom ProtoShield som nå kan stackes mellom Arduino og Ethernet shieldet.
Alle delene den består av:
“Ferdig” montert og i drift ser det slik ut.. Henger i kablene enn så lenge.
LDR montert på hovedstrømmåleren:
Det hender jo at internettlinjen detter ned, eller at strømmen går, i disse tilfellene blir det ikke registrert noe til databasen. Om det går 5 min eller mer mellom to registreringer så får jeg en sms om det. Og etter ytterligere en time så en ny. Dette er løst vha et php script som sjekker differanse mellom tidspunkt for siste rad i basen mot nåværende tidspunkt. Er dette mer enn 5 min, så sendes SMS, og jeg setter et “flagg” for at wattwatcher er offline. På den måten slipper jeg å varsles flere ganger for samme feil. Denne sjekken kjører via cron hvert 5 minutt, og neste gang den oppdager ny registrering så fjernes “offline” flagget, og sms sendes om at den nå er oppe å kjører.
php kode for sms varsling
<?
include ("db.php");
$watts = $_GET['watt'];
$pw = $_GET['pw'];
$temp1 = $_GET['temp1'];
$temp2 = $_GET['temp2'];
$mail_to="espen@gmx.no";
$mail_from="Powermeter";
$mail_sub="No update last 2 minutes";
$mail_mesg="Sjekk kWh tellern!!!";
$time = date("Y-m-d H:i:s");
$link = mysql_connect($mysql_host, $mysql_user, $mysql_pass) or die("Feil x01");
if ( $link ) {
mysql_select_db($mysql_db) or die(mysql_error());
$result = mysql_query("SELECT * FROM 14418_usage order by id DESC LIMIT 0,1 ") or die(mysql_error());
while($row = mysql_fetch_array($result))
{
$lastdate = $row['time'];
}
//Sjekker først om 5min sms er sendt.
$result2 = mysql_query("SELECT * FROM config where id= 1") or die(mysql_error());
while($row2 = mysql_fetch_array($result2))
{
$status5 = $row2['value'];
}
//Sjekker så om 60min sms er sendt.
$result2 = mysql_query("SELECT * FROM config where id= 2") or die(mysql_error());
while($row2 = mysql_fetch_array($result2))
{
$status60 = $row2['value'];
}
echo"lastupdate: ".$lastdate."<br>";
//$curtime = date("Ymdhi", strtotime(date("Y-m-d h:i:s")));
$curtime = time();
echo"curtime: ".$curtime."&amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;gt;";
$lastupdate = strtotime($lastdate);
echo"lastupdate stamp: ".$lastupdate."&amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;gt;";
$diff = $curtime - $lastupdate;
echo "Det er : ". $diff ." sekunder siden oppdatering.&amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;gt;";
}
if ($diff &amp;amp;amp;amp;amp;amp;lt; "300") // Vi har ferske data, sjekker om sms er satt til sendt, hvis den er det så nuller vi flagget, slik at den kan sendes på nytt neste gang vi har feil..
{
if ($status5 == "1")
{
mysql_query("UPDATE config SET `value` = '0' WHERE `id` =1") or die(mysql_error());
$msg = "[online] last update: ";
$sendurl = sendsms($msg, $lastdate);
if (file_get_contents($sendurl)) {
echo "&amp;amp;amp;amp;amp;amp;lt;BR&amp;amp;amp;amp;amp;amp;gt;SMS er sendt!! OK&amp;amp;amp;amp;amp;amp;lt;br\&amp;amp;amp;amp;amp;amp;gt;";
//echo $sendurl;
}
else
{
echo "error while sending";
}
}
if ($status60 == "1")
{
mysql_query("UPDATE config SET `value` = '0' WHERE `id` =2") or die(mysql_error());
$msg = "[online] last update: ";
$sendurl = sendsms($msg, $lastdate);
if (file_get_contents($sendurl)) {
echo "&amp;amp;amp;amp;amp;amp;lt;BR&amp;amp;amp;amp;amp;amp;gt;SMS er sendt!! OK&amp;amp;amp;amp;amp;amp;lt;br\&amp;amp;amp;amp;amp;amp;gt;";
}
else
{
echo "error while sending";
}
}
}
if ($diff &amp;amp;amp;amp;amp;amp;gt; "300") // Mer enn 5 min siden siste oppdatering. Vi sender sms
{
if ($status5 == "0") // SMS er ikke sendt, så vi sender nå.
{
$msg = "[5min]Ingen update siden: ";
$sendurl = sendsms($msg, $lastdate);
if (file_get_contents($sendurl)) {
echo "&amp;amp;amp;amp;amp;amp;lt;BR&amp;amp;amp;amp;amp;amp;gt;SMS er sendt!! OK&amp;amp;amp;amp;amp;amp;lt;br\&amp;amp;amp;amp;amp;amp;gt;";
//echo $sendurl;
}
else
{
echo "error while sending";
}
// Må nå lagre i DB at sms er sendt.
mysql_query("UPDATE config SET `value` = '1' WHERE `id` =1") or die(mysql_error());
}
}
if ($diff &amp;amp;amp;amp;amp;amp;gt; "3600") // Mer enn 1 time siden siste oppdatering. Vi sender mail og sms på nytt.
{
$msg = "[60min] Ingen update siden: ";
$sendurl = sendsms($msg, $lastdate);
if (file_get_contents($sendurl)) {
echo "&amp;amp;amp;amp;amp;amp;lt;BR&amp;amp;amp;amp;amp;amp;gt;SMS er sendt!! OK&amp;amp;amp;amp;amp;amp;lt;br\&amp;amp;amp;amp;amp;amp;gt;";
//echo $sendurl;
}
else
{
echo "error while sending";
}
if(mail($mail_to,$mail_from,$mail_sub,$mail_mesg))
{
echo "&amp;amp;amp;amp;amp;amp;lt;span class='red'&amp;amp;amp;amp;amp;amp;gt;E-mail has been sent successfully from $mail_from to ###### &amp;amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;amp;gt;";
}
else
echo "&amp;amp;amp;amp;amp;amp;lt;span class='red'&amp;amp;amp;amp;amp;amp;gt;Failed to send the E-mail from $mail_from to #######&amp;amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;amp;gt;";
}
function sendsms($msg, $lastupdate)
{
$userid="sensur";
$time = date('Y-m-d H:i:s');
$password="sensur";
$last = $lastupdate;
$sender="WattWatcher";
$receiver="dittmobilnr;
$message= "[".$time ."]". $msg."[".$last."]";
$url="http://kjappsms.no/sms/SendSms.aspx?id=".$userid."&amp;amp;amp;amp;amp;amp;amp;Password=".$password."&amp;amp;amp;amp;amp;amp;amp;Sender=".$sender."&amp;amp;amp;amp;amp;amp;amp;Recipient=".$receiver."&amp;amp;amp;amp;amp;amp;amp;Msg=".urlencode($message);
return $url;
}
?&amp;amp;amp;amp;amp;amp;gt;
Koden for Arduinoen er nå slik:
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SoftwareSerial.h>
#include <Ethernet.h>
#define rxPin 2
#define txPin 3
#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress utesensor = { 0x28, 0x7E, 0xF9, 0x5E, 0x2, 0x0, 0x0, 0x42 }; // loddet på 3.5mm
// DeviceAddress innetemp = { 0x28, 0xF0, 0x12, 0x5F, 0x02, 0x0 , 0x0, 0x9E }; // på hylla
DeviceAddress innesensor = { 0x28,0x2A,0xDE,0x5E,0x02,0x00,0x00,0x19 }; // I BODEN.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 0, 0, 177 };
byte gw[] = {10,0,0,101};
byte server[] = { 88,87,42,5 }; // gmx.no
byte subnet[] = { 255, 255, 255, 0 };
SoftwareSerial lcdSerial = SoftwareSerial(rxPin, txPin);
int ledPin = 6;
int avgwatt = 5;
int switchPin = 7;
const int numReadings = 20;
unsigned long period_start;
unsigned long period_length = 57000;
unsigned long period_total;
unsigned long period_stop;
unsigned long run = 0;
int period_average;
int period_counter;
float itemp;
float utemp;
void setup()
{
Serial.begin(9600);
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(switchPin, INPUT);
pinMode(ledPin, OUTPUT);
lcdSerial.begin(9600);
sensors.begin();
sensors.setResolution(innesensor, 12);
sensors.setResolution(utesensor, 12);
}
void loop()
{
sensors.requestTemperatures(); // Send the command to get temperatures
lcdcls();
period_total = 0;
period_counter = 0;
period_start = millis();
period_stop = period_start + period_length;
if (run > 0) {
lcdgoTo(0);
lcdSerial.print(avgwatt);
lcdSerial.print(" Current. ");
lcdgoTo(17);
lcdSerial.print(period_average);
lcdSerial.print(" Average. ");
}
else { // First run.. write no data.
lcdgoTo(0);
lcdSerial.print("No data.");
lcdgoTo(17);
lcdSerial.print("No data.");
}
while( millis() <period_stop) {
lcdgoTo(0);
avgwatt = getAvgWatt(); // returns average watt
Serial.print("Snitt er: "); // for debugging
Serial.println(avgwatt);
lcdSerial.print(avgwatt);
lcdSerial.print(" Current. ");
// timedAction.check(); // check if its time to do the Senddata()
period_total += avgwatt;
period_counter += 1;
} // Etter at period- er utløpt. Dvs 1min. Vi regner ut avg og skriver til Linje2 på lcd.
lcdcls();
period_average = 0;
period_average = period_total / period_counter;
lcdgoTo(17);
lcdSerial.print(period_average);
lcdSerial.print(" Average. ");
sensors.requestTemperatures(); // Send the command to get temperatures
delay(750);
itemp = getTemp(innesensor);
utemp = getTemp(utesensor);
sendWatt();
run +=1;
}
void sendWatt(){
Ethernet.begin(mac, ip, gw, subnet);
Client client(server, 80);
// delay(1000);
Serial.println();
Serial.println("Initiates connection...");
Serial.println("Connecting...");
if (client.connect()) {
Serial.println("Connected!");
client.print("GET http://gmx.no/?watt=");
client.print(period_average);
client.print("&pass=*******&temp1=");
client.print(itemp);
client.print("&temp2=");
client.print(utemp);
// client.print(sensors.getTempC(innetemp));
client.println(" HTTP/1.1");
client.println("Host: www.gmx.no");
client.println();
// delay(1000); // Lar webserver rekke å returnere data før vi prøve å lese det ut.
// while(client.available()) {
// char c = client.read();
// Serial.print(c);
// }
} else {
Serial.println("Connection failed");
}
//stopper client
client.stop();
while(client.status() != 0) {
delay(5);
}
}
int getAvgWatt(){
int watt = 0;
int index = 0;
float average= 0;
float total = 0;
int old_val = 0;
unsigned long current_time = 0;
unsigned long last_time = 0;
float delayarray[numReadings];
float pulsedelay = 0;
last_time = millis();
int val = LOW;
for (int thisReading = 0; thisReading < numReadings; thisReading++)
{
delayarray[thisReading] = 0;
}
while (index < numReadings){
val = (digitalRead(switchPin)); // Reads value high/low and saves it
if ((val == HIGH) && (old_val == LOW)) { // We have light, lets read the time, and value.
current_time = millis(); // Current time
pulsedelay = current_time - last_time; // Delay since last pulse
pulsedelay = pulsedelay / 1000; // I want seconds, not ms
digitalWrite(ledPin, HIGH); // Blinks the LED
delayarray[index] = pulsedelay; // Add the value to the array
old_val = val; // Sets old_val high
Serial.println(pulsedelay); // THIS IS THE ONE THAT KEEPS IT FROM FREEZING
last_time = current_time; // for the next whileloop-cycle to know the next delay.
index +=1;
}
else {
digitalWrite(ledPin, LOW); // No light detected
old_val = val;
}
}
for (int i = 1; i< numReadings;i++){ //Skip the first value in the array, since millis() from the start is off.
total = total + delayarray[i];
}
average = total / (numReadings-1); // Minus 1 since we skipped the first value in the array.
watt = 360 / average; // 360 / average delay gives us current powerconsumption in watts.
total = 0; // for the next cycle
average= 0; // for the next cycle
// Empty out the array. Not sure if this is needed.
// for (int y = 0; y < numReadings; y++) {
//delayarray[y] = 0;
//}
return watt;
}
//SerialLCD Functions
void selectLineOne(){ //puts the cursor at line 0 char 0.
lcdSerial.print(0xFE, BYTE); //command flag
lcdSerial.print(128, BYTE); //position
}
void selectLineTwo(){ //puts the cursor at line 2 char 0.
lcdSerial.print(0xFE, BYTE); //command flag
lcdSerial.print(192, BYTE); //position
}
void lcdcls(){
lcdgoTo(0);
lcdSerial.print(" ");
}
void clearLCD(){
lcdSerial.print(0xFE, BYTE); //command flag
lcdSerial.print(0x01, BYTE); //clear command.
}
void backlightOn(){ //turns on the backlight
lcdSerial.print(0x7C, BYTE); //command flag for backlight stuff
lcdSerial.print(157, BYTE); //light level.
}
void backlightOff(){ //turns off the backlight
lcdSerial.print(0x7C, BYTE); //command flag for backlight stuff
lcdSerial.print(128, BYTE); //light level for off.
}
void lcdgoTo(int position) { //position = line 1: 0-19, line 2: 20-39, etc, 79+ defaults back to 0
if (position<16){
lcdSerial.print(0xFE, BYTE); //command flag
lcdSerial.print((position+128), BYTE); //position
}
else if (position<32)
{
lcdSerial.print(0xFE, BYTE); //command flag
lcdSerial.print((position+47+128), BYTE); //position
}
else { lcdgoTo(0); }
}
// Henter temp fra gitt sensor.
float getTemp(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
return tempC;
}

Veldig flott prosjekt
Har du noe mere informasjon over utstyret du bruker og verktøy som brukes ?
@Tunlid
Heisann, kan skrive litt om det ja. I utganspunktet kommer man langt med en loddebolt
Utstyret kjøpet jeg stort sett fra sparkfun.com, men finner en del på elfa/clas ohlson også.
Noe spesielt du tenkte på?