Ho fatto un’esercizio di stile, probabilmente non andrò avanti con il progetto ma ve lo mostro comunque, si tratta di un indicatore di email non lette in arrivo per Gmail. Il modulo funziona con l’ethernet, quindi non è necessaria la connessione al pc perchè funzioni.
Il funzionamento è semplice:
- arduino interroga una mia pagina php.
- php si logga ed elabora il mio feed gmail restituendo il numero di email non lette.
- letto il dato lo visualizzo sui display a 7 segmenti.
Difetti attuali:
- il refresh è per ora manuale pigiando il tasto di reset
- il display delle decine non mi va, devo aver sbagliato qualcosa mettendo in cascata i shift register.
Possibili sviluppi:
Il principio di notifica può essere applicato anche ad altri ambiti, tipo facebook o multimail invece che solo gmail.
Codice php:
<?php
// Dati personli di accesso
$username = "USERNAME";
$password = "PASSWORD";
// Indirizzo da interrogare (nota bene si poù accere alle label di gmail aggiungendo /nome_label)
$c = curl_init('https://gmail.google.com/gmail/feed/atom');
$headers = array(
"Host: gmail.google.com",
"Authorization: Basic ".base64_encode($username.":".$password),
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4",
"Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
"Accept-Language: en-gb,en;q=0.5",
"Accept-Encoding: text",
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7",
"Date: ".date(DATE_RFC822)
);
curl_setopt($c, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($c, CURLOPT_COOKIESESSION, true);
curl_setopt($c, CURLOPT_HTTPHEADER, $headers);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($c, CURLOPT_UNRESTRICTED_AUTH, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 1);
// Metto in str il feed xml
$str = curl_exec($c);
// estraggo dall'xml il nodo fullcoun che contiene il numero di mail non lette nella posta in arrivo
$xml = simplexml_load_string($str);
$fullcount = (string) $xml->fullcount;
// stampo il numero estratto
print_r($fullcount);
// chiudo la connessione curl
curl_close($c);
?>
Note:
- la pagina può essere interrogata anche da browser e mostrerà il numero di email.
- una miglioria potrebbe essere quella di inviare username e password da arduino, in modo da gestire più account
- l’host deve supportare le curl con php, altrimenti è necessario attivarle (non sono espertissimo di php, altro non so dire)
Codice arduino:
#include <SPI.h>
#include <Ethernet.h>
int latchPin = 5;
int clockPin = 7;
int dataPin = 6;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1, 177 }; //IP ARDUINO DA PAERSONALIZZARE IN BASE ALLA PROPRIA RETE
byte server[] = { 62,149,140,194 }; // IP DEL SERVER HOST
byte segments[] = { 129,183,194,146,180,152,140,179,128,176 }; // CONFIGURATO PER I MIEI DISPLAY
// Inizializzazione client
Client client(server, 80);
char c; // usato per il buffer e come ultimo carattere
char prevc; // usato per tener traccia del penultimo carattere
void setup()
{
// configurazione per i pin che pilotano i shift register
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// avvio la connessione
Ethernet.begin(mac, ip);
// avvio la seriale per il debug
Serial.begin(9600);
delay(1000);
Serial.println("connecting...");
if (client.connect()) {
Serial.println("connected");
// creo la richiesta http
client.print("GET /miacartella/miofile.php HTTP/1.0\n"); // ATTENZIONE QUI SI INDICA LA PAGINA DA INTERROGARE, SE E' IN UNA SOTTOCARTELLA INDICARLA, ALTRIMENTI LASCIARE SOLO /nomepagina.php
client.print("Host: www.mioindirizzo.it\n"); // PARTE NECESSARIA PER HOST CHE HANNO PIU' SITI CON LO STESSO IP (NEL MIO CASO ARUBA)
client.println(); // NON RIMUOVERE, NECESSARIO PER AVVIARE LA RICHIESTA
} else {
Serial.println("connection failed");
}
digitalWrite(latchPin, LOW); // SPENDO I DISPLAY
}
void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
prevc = c; // TENGO SALVATO IL DATO PRECEDENTE
c = client.read(); // PRENDO L'ULTIMO BYTE LETTO
Serial.print(c); // SCRIVO BYTE PER BYTE LA RISPOSTA SULLA SERIALE
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.print(int(c)-48); // CONVERTO IL CARATTERE IN NUMERO (-48 perchè 0 in esadecimale è il carattere numero 48)
shiftOut(dataPin, clockPin, MSBFIRST, segments[int(c)-48]); // SCRIVO IL VALORE LETTO SUL DIPLAY
digitalWrite(latchPin, HIGH);
Serial.println();
Serial.println("disconnecting.");
client.stop(); // CHIUDO LA CONNESSIONE
// do nothing forevermore:
for(;;) // QUI INVECE CHE MANDARE IN LOOP INFINITO SAREBBE IDEALE RIMANDARE LA RICHIESTA ALLA PAGINA DOPO UN DELAY PER AVERE UN CONTINUO REFRESH
;
}
}
Note:
- il codice è un mix tra ShiftOut e Client ethernet più altre nozioni trovate in giro.
- Ho calcolato i valori per i display a 7 segmenti in base a come ho messo io i fili, quindi potrebbe essere necessario cambiare i byte
- Il codice non fa refresh, si deve resettare ogni volta
- supporta massimo 2 decimali
- manca il codice per la visualizzazione delle decine