AHA - AnotherHomeAutomation




A new project for remote control....

In the process to save energy, I came to the point to turn on/off remotely my home appliances. So, this is why AHA was born. In this way, I can turn on things only when needed.

Let's begin with some part list:
 - 1 classic Arduino or a compatible board, like Seeeduino Stalker, if you want to add some additional features (save data maybe). The original project was done with Arduino Duemilanove

- 1 GSM shield, like

- RF relay (you can use 433Mhz or 315Mhz)

- RF relay controller

You can find Arduino code at my SourceForge site, under AHA folder: http://sourceforge.net/projects/enerduino/files/AHA/
I think the code is quite self-explanatory, it basically read the GSM shield for SMS messages (only coming from authorized numbers) and it turns on/off remote switches.  
In order to connect the "RF relay controller" to the Arduino, Seeedstudio site has very good documentation on how to do it. Anyway, if you need calrifications, feel free to ask me.

This is the "core", able to get SMS message and to process them:


The core is able to control, via 433 Mhz, some custom sockets. The socket is built with a RF relay and a little 12v transformer (in order to keep the relay listening for RF). When it gets the signal from the "core", it turns on/off the switch:


Here is an example of use:


So, I'm able to control with an SMS all my home appliances...:-)

Enerduino 2.0 (English)

Finally, after one year of work (few hours in the weekend...), Enerduino 2.0 is here!!
What's new? Let's have a look:


In few words, I upgraded the Enerduino (power meter monitor, see old post) with a wireless connection (XBee), I added another logger to monitor the solar power plant (Rotex) and both are sending data to a coordinator which sends the data in CACTI (an rrd tool) to show graphs. The idea was to build two autonomous nodes, able to store data locally and send them to a central system (coordinator) when it is available. Then data are loaded in a web tool like CACTI:





How I did it

I decided to buy a couple of Arduino Stalker from www.seeedstudio.com with enclosure. The reason is mainly because these boards already have a built in storage (SD Card), clock, XBee socket and look very very robust. I'm very happy with them.
With these I bought also 3 XBee modules (XBee PRO Series 2) with one UART module to connect (via USB) the XBee coordinator to the PC.

The source code for the data loggers and the server side scripts are available at SourceForge (it was compiled with arduino 0023, in a while I'll convert them for 1.0).

The Coordinator and XBee modules

The first thing to remember is to upgrade the XBee firmware with the last (and correct) version. Then, I selected the AT command mode. The modules must be configured as ROUTER for the two nodes (ENERDUINO and ROTEXUINO) and as COORDINATOR for the Coordinator.

The nework identifiers (ATNI) will be

ENERDUINO
ROTEXUINO

All the modules must be in the same PAN.

The Coordinator will be just an XBee module (with antenna) mounted on UART to connect it to a PC via USB. As you can see I used some "friendly plastic" to lock the module at the case:



The Coordinator will be only an interface to connect the two nodes, all the logic is in the xh.pl perl script which waits for the "SYN" packet from the nodes and then saves locally the data collected. Then, data are loaded in two different RRD databases with the rrdload.pl script.
Look at the comment of the rrdload.pl script  to see the rrdtool command used to create the databases.

Then you can have a look to this to understand how to configure CACTI to read the databases.

ENERDUINO & ROTEXUINO

The two nodes are built with two Arduino Stalker and two XBee:


To build the ENERDUINO cable (to read flashes) see the old ENERDUINO post. ROTEXUINO uses a serial connection to the Rotex R3 solar plant. You can refer to the manual to configure the serial connection on it.

The two modules, try to reach the coordinator at configured hours (see sources). If the coordinator is found, collected data are sent and removed from the SD card. Otherwise they will retry later. You can modify the source to meet your requirements on this. The sources are here (Rotexuino.pde and Enerduino.pde).

Updated 22 Apr 2012: Checksum added

I modified the sources for Enerduino, Rotexuino and xh.pl. I added a checksum when the file is sent via XBee, so that xh.pl checks for it before saving it and give the OK to the Enerduino/Rotexuino.
I did it because sometimes the data were corrupted during the wireless transfer.

Arduino 1.0 version (English)

Thanks to Andrea Manzini, we have now the the Arduino 1.0 IDE version. You can download it here.

Versione per Arduino 1.0 (Italiano)

Grazie ad Andrea Manzini, esiste ora anche il porting per il nuovo IDE Arduino 1.0. Potete scaricalo qui.

Enerduino (Italiano)




Cos'e' Enerduino? Un progetto nato per controllare il consumo di energia nella mia casa. E perche' dovrei fare questo tipo di monitoraggio, chiederete voi? Per esempio per capire le mie abitudini di consumo, per valutare offerte biorarie. Oppure solo per capire dove consumo di piu' e magari risparmiare un po' di energia.

Esistono molti strumenti per poter fare questo tipo di monitoraggio che si possono acquistare su internet. Questa e' la mia soluzione fai-da-te, basata sul controller hardware Arduino.

Questo progetto puo' essere realizzato da chiunque abbia un po' di manualita' e abbia voglia di divertisi a costruire qualcosa.


COME FUNZIONA

Molto semplice: grazie a una fotoresistenza che verra' applicata alla lucina RA del contatore elettronico ENEL, verranno contati i lampeggi. Siccome ad ogni lampeggio dovrebbe corrispondere 1w/h di consumo, contando i lampeggi e salvandone il numero su un file, saremo in grado di fare delle elaborazioni grazie ad un semplice foglio di calcolo.

Lista dei componenti richiesti:

  • 1 Arduino (controller)
  • 1 SD Card shield (utilizzato per salvare i dati su una SD Card)
  • 1 modulo DS1307 (in pratica un'orologio, per conservare data/ora)
  • 1 resistenza da 10Kohm
  • 1 fotoresistenza
  • fili vari per i collegamenti

I componenti si possono trovare su Internet. Io generalmente mi servo su http://www.seeedstudio.com



REALIZZAZIONE

Come prima cosa prendete l'Arduino. L'SD card shield va montato direttamente sopra l'arduino inserendo il PIN D9 nel pin 9. Lo switch dell'alimentazione va messo su D9, in quanto la libreria che useremo per scrivere sulla card (Filelogger a http://code.google.com/p/arduino-filelogger/) utilizza questa modalita'.
A questo punto bisogna collegare modulo DS1307, l'orologio. In teoria anche questo andrebbe montato direttamente sull'Arduino, ma essendoci gia' il modulo SD questo non e' possibile. Andra' quindi montato di lato e poi bisognera' procedere ai collegamenti. I due pin in alto a sinistra nella foto andranno nelle porte analogiche 4 e 5. L'alimentazione (+ e GND) si prende invece dalla porta ICSP (vedi anche lo schema finale dei collegamenti).

Adesso pensiamo al sensore dei flash: il photoresistor va montato con una resistenza da 10Kohm in questo modo

+5V ---PhotoResistor-------.-----Resistenza 10K--- GND
|
Pin 0 ------------------------------------------

Per collegare il tutto ho sciacallato un cavetto a 4 fili (ne useremo solo 3), ho estratto un pin come si vede sotto (questo andra' alla PIN 0 analogico)

Dall'altra parte del cavetto il collegamento e' cosi' (il filo rosso si collega al connettore che dall'altro lato va alla porta 0)
Siccome siamo a corto di porte per l'alimentazione, il tutto verra' collegato ancora alla porta ICSP



Direi che siamo alla fine. A questo punto va caricato il software (che trovate in fondo al post), inserita una carta SD (ATTENZIONE: Filelogger funziona solo con partizioni FAT16, blocchi di 512 byte e al massimo 64MB di RAM. Si dovra' creare una partizione di 64MB e formattarla con format f: /fs:fat /a:512. Inoltre va creato un file vuoto data.log nella root, altrimenti niente dati) e poi si deve attaccare il photoresistor alla luce del contatore (io ho usato il Patafix):
Qui sotto trovate uno schema per chiarirvi come sono fatti i collegamenti alle porte della board ArduinoIo ho tentato di farlo funzionare con una pila a 9V, ma dura pochissimo. E' meglio attaccarlo ad un alimentatore....

Dopo qualche giorno potete spegnere il tutto, estraete l'SD card, prendete il file data.log che dovrebbe contenere una lista di "DATAORA NUMEROLAMPEGGI". Elaborando questa lista con un comune foglio elettronico e' semplice ottenere un grafico tipo questo:



IL CODICE

 // 
//  
// Enerduino 
//  
// version 0.2 
//  
// Internal revision: $Id: Enerduino.pde,v 0.22 2009/11/28 16:30:16 cesare Exp cesare $ 
//  
// written by Cesare Pizzi 
//  
// This simple Arduino application allow to monitor power consumpion by checking the flashing  
// light of the power meter. 
// There are 2 lights on italian ENEL power meters: RA (active) and RR (reactive). 
// Only RA led is computed for home contracts 
// One flash should be 1 w/h 
//  
// 

#include <stdlib.h> 

// Include files for Filelogger library 
#include <Spi.h> 
#include <mmc.h> 
#include <nanofat.h> 
#include <FileLogger.h> 

// Include files for clock DS1307 library 
#include <WProgram.h> 
#include <Wire.h> 
#include <DS1307.h> 

// Include files for MsTimer2 library 
#include <MsTimer2.h> 

/// The PIN to power the SD card shield 
#define MEM_PW 9 
// Analog input for photoresistor 
#define PHOTO_IN  0 

unsigned long timer=3600000; // Log file is written every 60 minutes (3600000)  FIXME 
unsigned long flash=0; 
int threshold=450;     // If photoresistor read more than this value, it count a flash 
int writeLog=0; 

// Arduino setup routine 
void setup(void)  
{ 

// This is to power on the SD shield 
pinMode(MEM_PW, OUTPUT); 
digitalWrite(MEM_PW, HIGH); 

// Setup for photoresistor 
pinMode(PHOTO_IN,INPUT); 

// Initialize timer 
MsTimer2::set(timer, flushCounter); 
MsTimer2::start(); 

// Serial.begin(9600);       // FIXME 

// Enable to set up external clock 
// setClock(0,38,17,6,14,11,9); 
} 

// Main 
void loop(void)  
{ 

// Serial.println(analogRead(PHOTO_IN));  // FIXME 

// Read the photo sensor value 
if (analogRead(PHOTO_IN) > threshold) 
{ 
while (analogRead(PHOTO_IN) > threshold) 
{ 
// Just wait the flash to turn off (to avoid multiple counts)    
}  

flash++; 
// Serial.println("Flash");       // FIXME 
} 

// Write the log file if interrupt has been called 
if (writeLog==1) 
{ 
char time[10]; 
char date[15]; 
char logStr[50]; 
char buffer[5]; 

// Write flashes to log file 
strcpy(logStr,getDate(time)); 
strcat(logStr," "); 
strcat(logStr,getClock(date)); 
strcat(logStr,"\t"); 
itoa(flash,buffer,10); 
strcat(logStr,buffer); 
strcat(logStr,"\n"); 

write_log(logStr); 

writeLog=0; 
flash=0;  
} 

delay(10); 
} 

///////////////// 
// Subroutines // 
///////////////// 

// Setup the external clock 
void setClock(int seconds, int minutes, int hour, int dow, 
int day, int month, int year) 
{ 

RTC.stop(); 
RTC.set(DS1307_SEC,seconds);    //set the seconds 
RTC.set(DS1307_MIN,minutes);    //set the minutes 
RTC.set(DS1307_HR,hour);      //set the hours 
RTC.set(DS1307_DOW,dow);      //set the day of the week 
RTC.set(DS1307_DATE,day);     //set the date 
RTC.set(DS1307_MTH,month);     //set the month 
RTC.set(DS1307_YR,year);      //set the year 
RTC.start(); 

} 

// Get the time from the external clock 
char* getClock(char *timeStr) 
{ 
char buffer[5]=" "; 

itoa(RTC.get(DS1307_HR,true),buffer,10); 
strcpy(timeStr,buffer); 
strcat(timeStr,":"); 
itoa(RTC.get(DS1307_MIN,false),buffer,10); 

// Add 0 if a single digit minute has been returned 
if (strlen(buffer)==1) 
{ 
strcat(timeStr,"0");  
}  
strcat(timeStr,buffer); 

// Seconds are not useful at this time. Commented out 
// strcat(timeStr,":"); 
// itoa(RTC.get(DS1307_SEC,false),buffer,10); 
// strcat(timeStr,buffer); 

return timeStr; 
} 

// Get the date from extrenal clock 
char* getDate(char *dateStr) 
{ 
char buffer[5]=" "; 

itoa(RTC.get(DS1307_DATE,true),buffer,10); 
strcpy(dateStr,buffer); 
strcat(dateStr,"/");  
itoa(RTC.get(DS1307_MTH,false),buffer,10); 
strcat(dateStr,buffer); 
strcat(dateStr,"/"); 
itoa(RTC.get(DS1307_YR,false),buffer,10);  
strcat(dateStr,buffer); 

return dateStr; 
} 

// Write data to log file named data.log 
void write_log(char msg[]) 
{ 
int i; 
unsigned int length = (strlen(msg)+1); 
byte buffer[length]; 

for(i=0; i<length;i++) 
{ 
buffer[i] = msg[i]; 
} 

FileLogger::append("data.log", buffer, length-1); 
// We should check for errors here....we'll do it... 
} 

// Routine executed by the timer interrupt. This flush the  
// data to the log file 
void flushCounter(void) 
{ 
writeLog=1; 
} 

Enerduino (English)




What's Enerduino? This is a project created to monitor the energy consumption of my house. The reasons behind this monitoring can be more than one: to evaluate offers from energy suppliers, to understand where I'm wasting energy and to save some money. Or just for curiosity.

There are a lot of project out there, very similar to this one. This is my way, a DIY solution based on Arduino controller.

I think everybody can build this: it is very simple and require few electronic knowledge. This project is mainly built on the italian power meter installed by the national company, but it can be easily adapted for any other device, I guess.



HOW IT WORKS

Very simple: thanks to a photoresistor that will be applied on the RA LED of the power meter, we can count the flashes. Every flash should be 1W/H, so by counting these and saving them in a file, we'll be able to do some graphs by using a spreadsheet.

Required components:

  • 1 Arduino controller
  • 1 SD Card shield
  • 1 DS1307 module (a clock with battery, to save date/time)
  • 1 resistor (10Kohm)
  • 1 photoresistor
  • wires

I bought most of these on http://www.seeedstudio.com, but you can choose your own supplier



LET'S BUILD IT

Get the Arduino board. The SD card shield must be placed directly over the controller. PIN D9 must be placed in Arduino PIN 9. The SD power switch must be placed on D9, as the Filelogger library we'll use, requires this mode (http://code.google.com/p/arduino-filelogger/).
Now we have to connect the DS1307 module. Also this one should be placed on top of the Arduino, but since we already have the SD shield, this is not possible. So, we'll place it beside the controller. The two pins shown on top-left of the picture will be connected to analog ports 4 and 5. Power (+ and GND) will come from the ICSP port (please, have a look to the schema at the end of the post).

Then, we have to assemble the photoresistor. It must be used with a resistor in this way

+5V ---PhotoResistor-------.-------Resistor 10K--- GND
|
Pin 0 ------------------------------------------

To connect this, I used a scrap cable: I extracted one pin (this will be connected to analog PIN 0)

This is the picture of the opposite side of the cable: the red wire is placed in the PIN that is connected to port 0 on the other side)

There is shortage of power lines...we need to connect this to ICSP port again...


OK, we mostly completed our work here. Now we need to load the software (see the end of the post), place a SD card (BE CAREFUL: Filelogger works only with FAT16 partitions, with 512 bytes block. You need to create a 64MB partition and then format it with "format f: /fs:fat /a:512". Remember to create a file named data.log in root directory, otherwise nothing will be logged).
I sticked the photoresistor to the power meter LED with Patafix:
Here below a schema to clarify some of the connectionsI tried to use it with a 9V battery, but it last very few hours....it's better to use an external power supply.

Wait some days, then extract the SD card: the data.log file will contain a list of "DATE # OF FLASHES". With a common spreadsheet you can build a graph like this one:



THE CODE

 // 
//  
// Enerduino 
//  
// version 0.2 
//  
// Internal revision: $Id: Enerduino.pde,v 0.22 2009/11/28 16:30:16 cesare Exp cesare $ 
//  
// written by Cesare Pizzi 
//  
// This simple Arduino application allow to monitor power consumpion by checking the flashing  
// light of the power meter. 
// There are 2 lights on italian ENEL power meters: RA (active) and RR (reactive). 
// Only RA led is computed for home contracts 
// One flash should be 1 w/h 
//  
// 

#include <stdlib.h> 

// Include files for Filelogger library 
#include <Spi.h> 
#include <mmc.h> 
#include <nanofat.h> 
#include <FileLogger.h> 

// Include files for clock DS1307 library 
#include <WProgram.h> 
#include <Wire.h> 
#include <DS1307.h> 

// Include files for MsTimer2 library 
#include <MsTimer2.h> 

/// The PIN to power the SD card shield 
#define MEM_PW 9 
// Analog input for photoresistor 
#define PHOTO_IN  0 

unsigned long timer=3600000; // Log file is written every 60 minutes (3600000)  FIXME 
unsigned long flash=0; 
int threshold=450;     // If photoresistor read more than this value, it count a flash 
int writeLog=0; 

// Arduino setup routine 
void setup(void)  
{ 

// This is to power on the SD shield 
pinMode(MEM_PW, OUTPUT); 
digitalWrite(MEM_PW, HIGH); 

// Setup for photoresistor 
pinMode(PHOTO_IN,INPUT); 

// Initialize timer 
MsTimer2::set(timer, flushCounter); 
MsTimer2::start(); 

// Serial.begin(9600);       // FIXME 

// Enable to set up external clock 
// setClock(0,38,17,6,14,11,9); 
} 

// Main 
void loop(void)  
{ 

// Serial.println(analogRead(PHOTO_IN));  // FIXME 

// Read the photo sensor value 
if (analogRead(PHOTO_IN) > threshold) 
{ 
while (analogRead(PHOTO_IN) > threshold) 
{ 
// Just wait the flash to turn off (to avoid multiple counts)    
}  

flash++; 
// Serial.println("Flash");       // FIXME 
} 

// Write the log file if interrupt has been called 
if (writeLog==1) 
{ 
char time[10]; 
char date[15]; 
char logStr[50]; 
char buffer[5]; 

// Write flashes to log file 
strcpy(logStr,getDate(time)); 
strcat(logStr," "); 
strcat(logStr,getClock(date)); 
strcat(logStr,"\t"); 
itoa(flash,buffer,10); 
strcat(logStr,buffer); 
strcat(logStr,"\n"); 

write_log(logStr); 

writeLog=0; 
flash=0;  
} 

delay(10); 
} 

///////////////// 
// Subroutines // 
///////////////// 

// Setup the external clock 
void setClock(int seconds, int minutes, int hour, int dow, 
int day, int month, int year) 
{ 

RTC.stop(); 
RTC.set(DS1307_SEC,seconds);    //set the seconds 
RTC.set(DS1307_MIN,minutes);    //set the minutes 
RTC.set(DS1307_HR,hour);      //set the hours 
RTC.set(DS1307_DOW,dow);      //set the day of the week 
RTC.set(DS1307_DATE,day);     //set the date 
RTC.set(DS1307_MTH,month);     //set the month 
RTC.set(DS1307_YR,year);      //set the year 
RTC.start(); 

} 

// Get the time from the external clock 
char* getClock(char *timeStr) 
{ 
char buffer[5]=" "; 

itoa(RTC.get(DS1307_HR,true),buffer,10); 
strcpy(timeStr,buffer); 
strcat(timeStr,":"); 
itoa(RTC.get(DS1307_MIN,false),buffer,10); 

// Add 0 if a single digit minute has been returned 
if (strlen(buffer)==1) 
{ 
strcat(timeStr,"0");  
}  
strcat(timeStr,buffer); 

// Seconds are not useful at this time. Commented out 
// strcat(timeStr,":"); 
// itoa(RTC.get(DS1307_SEC,false),buffer,10); 
// strcat(timeStr,buffer); 

return timeStr; 
} 

// Get the date from extrenal clock 
char* getDate(char *dateStr) 
{ 
char buffer[5]=" "; 

itoa(RTC.get(DS1307_DATE,true),buffer,10); 
strcpy(dateStr,buffer); 
strcat(dateStr,"/");  
itoa(RTC.get(DS1307_MTH,false),buffer,10); 
strcat(dateStr,buffer); 
strcat(dateStr,"/"); 
itoa(RTC.get(DS1307_YR,false),buffer,10);  
strcat(dateStr,buffer); 

return dateStr; 
} 

// Write data to log file named data.log 
void write_log(char msg[]) 
{ 
int i; 
unsigned int length = (strlen(msg)+1); 
byte buffer[length]; 

for(i=0; i<length;i++) 
{ 
buffer[i] = msg[i]; 
} 

FileLogger::append("data.log", buffer, length-1); 
// We should check for errors here....we'll do it... 
} 

// Routine executed by the timer interrupt. This flush the  
// data to the log file 
void flushCounter(void) 
{ 
writeLog=1; 
}