Enerduino (Italiano)



Enerduino e' stato aggiornato: Enerduino 2.0


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; 
}