Da Arduino a MySQL: ho aggiunto la temperatura esterna

Arduberry_finale

Dato che Yahoo Weather offre il feed della situazione meteo della mia città, ho deciso di aggiungere questi dati al mio database, in modo da avere sia la temperatura interna che quella esterna. Ho quindi modificato il codice in Python aggiungendo queste righe:

from xml.dom.minidom import *
import urllib
import csv
LocationID = '714505'
# Fetch weather XML for Como, Italy
Trier = urllib.urlopen('http://weather.yahooapis.com/forecastrss?w=' + LocationID + '&u=c').read()
# Parse the XML
Trier = parseString(Trier)
# Get date
Date = Trier.getElementsByTagName('lastBuildDate')[0].firstChild.data
# Get today's weather
Today = Trier.getElementsByTagName('yweather:condition')[0]
T = Today.attributes["temp"].value
W = Today.attributes["text"].value
#print(W,T)

Se vuoi divertirti anche tu, ho messo online il nuovo arduinotomysql.py con le relative modifiche.

Tra parentesi, questa sera canto nel coro alla prima della Cavalleria Rusticana che dovrebbe tenersi all’aperto nell’Arena del teatro Sociale. In questo momento splende il sole, ma si prevede nuvolo con occasionali piogge. Incrocio le dita.

Arduino: connessione a MySQL su Raspberry Pi

Ecco il mio Arduberry:

Arduberry

Un Arduino Leonardo con sensore di temperatura e di luce, connesso direttamente via porta USB a un Raspberry Pi su cui gira un server LAMP. I dati del sensore vengono scritti ogni dieci minuti su un database MySql sul Raspberry.

Il vantaggi di questa soluzione rispetto a quella precedente sono che a) non si appoggia a nessun servizio esterno e quindi ne ho il pieno controllo, e b) che mi sono divertito un casino a smanettare tra java, python, sudo nano e crontab. Ho tratto grande giovamento dai vari tutorial in circolazione, in particolare Connect Raspberry Pi and Arduino with Serial USB CableTutorial: store Arduino data with RaspBerry PI to MySql che ringrazio di cuore: ragazzi, non ce l’avrei mai fatta senza di voi.

Prossimo passo: trovare un alimentatore separato per l’Arduino, che la porta USB del Raspberry alimenta ma appena appena. Potrei provare a utilizzare il server Apache del Raspberry per la visualizzazione dei dati. Magari un’altra volta.

Ecco la non semplicissima ricetta, al netto degli innumerevoli prova ed errore:

1)

/*
  Termometro 
  con smoothing dei valori del sensore
  (media di 10 letture)

  vedi
  http://www.arduino.cc/en/Tutorial/Smoothing
  
*/


const int numReadings = 10;     // numero di letture per la media
int readings[numReadings];      // le letture dal sensore analogico
int index = 0;                  // 'indice della lettura corrente
int total = 0;                  // il totale corrente
int average = 0;                // la media
float temp;                       // la temperatura in C°
int light;
int inputPin = A0;              //la connessione al sensore di temperatura
int lightPin = A1;
int x;
int y;
unsigned long temptot;



void setup()
{
  Serial.begin(9600);
  // metto a 0 le letture: 
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;          
}

void loop() {
  // tolgo l'ultima lettura:
  total= total - readings[index];         
  // leggo più volte dal sensore
  // e faccio la media per stabilità: 
  temptot = 0;
  for(x = 0; x < 64; x++) {
    temptot += analogRead(inputPin);
  }
  y = temptot >> 6;
  readings[index] = y;
 
  //readings[index] = analogRead(inputPin); 
  // aggiungo la lettura al totale:
  total= total + readings[index];       
  // avanzo alla posizione seguente nell'array:  
  index = index + 1;                    

  // se siamo alla fine dell'array...
  if (index >= numReadings) {              
    // ...ricomincio da capo: 
    index = 0;                           
  }
  // calcolo la media:
  average = total / numReadings;
  
  // converto voltaggio sensore in °C
  temp = ( 5.0 * average * 100.0) / 1024.0;  
  // leggo l'output per debug:
  // Serial.println(temp); 
  light = analogRead(lightPin);
  

  // scrivo sulla porta seriale:
  Serial.print(temp);
  //Serial.print(average);
  Serial.print(" ");
  Serial.print(light);
  Serial.println();

  delay(2000);        // ritardo tra le letture per stabilità 
  
}

2)

Codice in python (il file è questo) che legge la USB del Raspberry , preleva i valori dei sensori e li scrive nel database MySQL:

arduinotomysql1

 

3)

La riga aggiunta in Raspberry con il comando crontab -e che esegue la lettura della porta seriale ogni dieci minuti (l’ultima parte serve a evitare le mail di alert):

*/10 * * * * /usr/bin/arduinotomysql.py >/dev/null 2>&1

 4)

Enjoy!

Arduino: il grafico delle temperature

ArduTemp

Per cucinare il grafico della temperatura della mia camera da letto, ho impiegato i seguenti ingredienti:

  • Un Arduino 2009 con Internet Shield
  • Un sensore analogico di temperatura LM35
  • Un database MySQL su Amazon Web Services (gratis) su cui registrare i dati ogni 10 minuti
  • MySQL Workbench (gratis) per creare e gestire il database e la tabella
  • Un account su Temboo (gratis fino a 1000 calls/mese)) per trasferire i dati da Arduino a MySQL
  • MySQL for Excel (gratis) per riversare i dati raccolti in un foglio di Excel
  • Excel 2013 per trasformare i dati del sensore in gradi centigradi e creare la media oraria con relativo grafico.

La ricetta ha molti passaggi ma non è complicatissima. Richiede qualche conoscenza di programmazione, di SQL e di Excel, oppure richiede il tempo di fare numerosi errori, consultare gli innumerevoli manuali presenti in rete, riprovare con maggiore fortuna.

E’ un buon inizio e sono soddisfatto, ma c’è molto da migliorare.

Il fatto è che avevo già in casa un server MySQL sul Raspberry Pi, e il Raspberry ha i suoi bei pin di input/output. Ma ho scoperto che i PIO del Rasberry sono digitali, mentre il mio sensore è analogico. Morale: comprerò un sensore di temperatura digitale (tipo questo) e riproverò con una soluzione più diretta e più elegante.

Nel frattempo: come spiegare il picco delle ore sei?

AGGIORNAMENTO:

MySQL for Excel è fantastico e funziona perfettamente; inoltre importa automaticamente le connessioni create con MySQL Workbench; ma alla terza volta che riscaricavo i dati per aggiornare il grafico mi sono stufato.

Ho invece installato il driver ODBC per MySQL, e adesso la pivot si aggiorna direttamente dal database, senza passaggi intermedi e senza dove ogni volta rifare il lavoro. Molto meglio.

Da Spark a Google Spreadsheets: una storia d’amore con finale tragico

Temp/light sensor

Una delle cose interessanti dello Spark (il simil-Arduino con WiFi integrato) è che pubblica automaticamente nel cloud il suo stato.

Una delle cose interessanti di Google Spreadsheets è che è programmabile, e gli puoi chiedere di prendere i dati da una url:
Gdocscript

Metti insieme le due cose, e questo è il risultato:

gdocsresult

Ero molto contento della scoperta, che mi apriva nuovi e mirabolanti orizzonti. Poi sono andato ad automatizzare il tutto, creando un trigger che mi eseguisse automaticamente lo script ogni 15 minuti:

Gdocstrigger

E qui il bel sogno è svanito. Il trigger di Google Drive non funziona, oppure funziona quando vuole lui. Una veloce ricerca mi ha confermato che è un problema comune a tutti quelli che ci hanno provato.

Morale: bisogna cercare altre strade. Per esempio, alimentare direttamente un database MySQL tramite Temboo.

 

Tutti gli oggetti elettrici saranno connessi a internet

Per esempio, quando tutti gli oggetti elettrici di casa tua saranno connessi a internet, il loro consumo di corrente sarà negoziato di volta in volta con il contatore, che sarà anche lui connesso a internet, e con l’Enel.

Alla lavatrice dirai “lava entro domani alle otto”: lei aspetterà che il forno finisca prima di partire e prenoterà con l’Enel  il momento meno caro per lavare.

Risultato: verranno livellati i picchi sia del consumo che della produzione, con risparmi che potrebbero essere importanti. Tieni presente che la bolletta energetica italiana nel 2011 è stata di 60 miliardi di Euro, quindi ogni singolo punto percentuale risparmiato varrebbe ben 600 milioni di Euro.

Spannometricamente, un risparmio annuale del 5% basterebbe da solo in sette anni a ripagare i 20 miliardi di Euro necessari alla copertura in fibra ottica di tutta l’Italia.