Qualche giorno fa, era notte, avevo una figlia unenne febbricitante in braccio, ho capito di aver bisogno che Arduino accendesse un led ogni volta che mi arrivava una mail, in modo da poter sporgere la testa nello studio e vedere la lucina accesa e andare a vedere la posta, oppure sporgere la testa nello studio, vedere la lucina spenta e andare a vedere la posta lo stesso perché magari è successo che il led si è bruciato proprio in quel momento. Voi mi capite.
Comunque, ho deciso di fare questa cosa che mi riempisse di autostima nerd e l’ho fatta, nel modo sbagliato, ma l’ho fatta.
Siccome sono certo che altre migliaia di persone trarranno beneficio da questa cosa ho deciso di scrivere qua sotto come si fa.

Innanzitutto il circuito

Il circuito è lo stesso che si fa per far accendere e spegnere la lampadina con un interruttore, non spendo una parola su questo sia perché si trova ampia documentazione in rete, sia perché di elettronica me ne capisco talmente poco che rischio di farvi bruciare qualcosa. Lascio parlare le immagini:
100_1810

Python

La seconda cosa era: come faccio a sapere se è arrivato un nuovo messaggio su Mail di osx? E soprattutto: come faccio a farlo sapere a Python? Dopo aver scartato la prima ipotesi (io guardo lo schermo fisso finché non vedo che è arrivata una mail e allora vado nel terminale e faccio partire lo script python ah ah scherzavo) e dopo aver scartato alcune caramelle che tengo opportunamento lato scrivania, ho cercato in rete qualche cosa che mi dicesse dove diavolo osx registra il fatto che è arrivata una nuova mail. Saperlo lo sa, perché lo mostra nelle icone del dock, ma se lo sa lo avrà salvato da qualche parte. La ricerca su google ha dato come principali risultati una serie di siti-fotocopia in cui vengono date informazioni essenziali come “scopri se è arrivata una mail guardando il dock”, o “scopri i segreti grafici del nuovo Mail” in cui viene mostrato qualche cambiamento di font dell’interfaccia fichetta di quelli di cupertino. Insomma: non ho trovato le specifiche che mi servivano, non dico che non ci siano, ma dopo mezz’ora, di notte, con la tipetta fra le mie braccia che mi scaldava il cuore, ho desistito.
E mi sono detto, beh, chi non ha la moto o sta fermo o cammina.
Insomma, ho usato un’altra strada, il metodo sbagliato di cui parlavo prima. Se non posso sapere dove Mail scrive il fatto che è arrivato un nuovo messaggio, posso sempre pesare la cartella di ingresso dei messaggi di posta, e poi ripesarla subito dopo, e poi ancora subito dopo, e così via finché non c’è una variazione. Se la cartella di ingresso dei messaggi pesa un pochino di più, vuol dire che è arrivato un nuovo messaggio. Non è un metodo pulito, ma se ci pensiamo bene in amore si fa anche di peggio.
Non avevo mai pesato una cartella in Python, ma per fortuna in rete ho trovato una funzione che faceva al caso mio e l’ho presa paro paro:


def get_size(start_path = '.'):
total_size = 0
for dirpath, dirnames, filenames in os.walk(start_path):
for f in filenames:
fp = os.path.join(dirpath, f)
total_size += os.path.getsize(fp)
return total_size

Questa non l’ho scritta io, eh. A questo punto ho scritto invece la semplice routine che controlla se c’è qualche variazione nella mia casella postale:


import serial
import os
ser = serial.Serial('/dev/tty.usbmodemfa121', 9600, timeout=1)

messaggioeff= get_size("/Users/fabriziovenerandi/Library/Mail/V2/POP-miacasellapostale/INBOX.mbox")
while 1:
nuovomessaggioeff=get_sizeget_size("/Users/fabriziovenerandi/Library/Mail/V2/POP-miacasellapostale/INBOX.mbox")

if nuovomessaggioeff>messaggioeff:
messaggioeff=nuovomessaggioeff
ser.write('5')

Cosa fa questo codice. Intanto chiama un po’ di librerie o come si chiamano, per gestire comandi da os e per gestire le comunicazioni seriali (attraverso la libreria, da installare, pySerial).
Viene aperta una comunicazione seriale a cui viene dato il nome ser, e la comunicazione seriale viene fatta proprio con la stessa porta seriale e lo stesso cavo che è collegato ad Arduino, curioso no?
Poi viene letto il peso iniziale della mia casella di posta (la vostra la trovate nella Libray/Mail del vostro utente, ma non sperate che sia interessante come la mia) e poi viene iniziato un ciclo while infinito, dove per infinito intendo finché non si ferma. L’infinito vero è più impegnativo.
Nel ciclo che lui crede essere infinito python cosa fa, rilegge il peso della casella, la confronta con il peso che aveva prima, poi lo rilegge, confronta ancora, rilegge e ancora e ancora finché – improvvisamente – il peso della nuova lettura è superiore al precedente: è arrivato il postino!
Se il peso della cartella aumenta, lo fa perché – si auspica – è arrivato un nuovo messaggio. In tal caso il programma, intelligentissimo, setta come valore del peso della cartella il nuovo peso, e soprattutto manda attraverso la connessione seriale aperta in precedenza un carattere, “5”.
Perché “5”? Perché sono pigro. È un carattere come un altro.

Arduino immobile attende

E arduino che fa intanto?
Arduino ha settato anche lui un po’ di cose. Commento direttaemente in codice:


#define led 13 // led connesso al pin 13
#define pulsante 12 // pulsante connesso al 12
byte rx = 0; // variabile per contenere il carattere ricevuto. Tutta questa roba l'ho copiata in rete da altri esempi. Non è che mi sono svegliato una mattina e la sapevo eh

int val=0;//questo mi sa che non serve più, ma lo tengo per ricordo
void setup()
{
Serial.begin(9600); // imposto la UART per lavorare a 9600 baud
pinMode(led, OUTPUT); // imposto il pin sul quale è collegato il led come uscita
pinMode(pulsante, INPUT); // imposto il pin su cui c'è il pulsante come ingresso. Non fate come me che me lo ero dimenticato e ci ho perso quindici minuti da brivido
Serial.flush(); // svuoto il buffer di ricezione seriale. flush è onomatopeico e rimanda a urgenze corporali non più rimandabili
}

void loop() //altro ciclo che si crede infinito
{

if (Serial.available() >0) // Controllo se il buffer di ricezione contiene qualcosa
{
rx = Serial.read(); // leggo il carattere ricevuto e lo memorizzo in rx
Serial.flush(); // svuoto il buffer di ricezione seriale
if (rx=='5') //ecco il cinque: se ricevo il 5 che python mi sta mandando capisco che è arrivato un nuovo messaggio mail, e quindi:
{
digitalWrite(led, HIGH); //che sia fatta luce!

}

}

Forte eh. Alcuni commenti li ho presi paro paro dagli esempi che si trovano in rete. Devo comprarmi un libro.
Andiamo avanti: anzi riepiloghiamo. Python controlla il peso della mia casella postale, appena vede un aumento manda un carattere (il “5”) ad Arduino che è lì in loop che legge la seriale. Appena Arduino legge il carattere “5” accende il led.
I due, Python e il C di Arduino si parlano e si dicono cose. Romantico, no?

Spegni quella maledetta luce!

A questo punto però dobbiamo spegnere la luce. Sappiamo che è arrivata posta, ma dobbiamo spegnere la luce in modo che poi si possa riaccendere se ne arriva altra. Come spegnere la luce? Abbiamo un pulsante, usiamo quello. E senti, Arduino, già che ci siamo, facciamo anche che se premo il pulsante non solo si spegne la luce, ma mi si apre anche la finestra del programma di posta, così mi leggo anche la mail.
La cosa è abbastanza semplice, dopo che l’hai fatta.

Lato Arduino

val=digitalRead(pulsante); //leggo il pulsante

if (val==LOW) //ehi, venerandi sta premendo il pulsante, fai qualcosa!
{
digitalWrite(led,LOW);//spengo la luce

Serial.write ("6\n");//e mando in scrittura seriale un carattere, il "6". Perché il "6"? Perché sono pigro, era il carattere che si trovava nel demo di spiegazione sul sito di Arduino e non ho avuto voglia di cambiarlo. Questo spiega anche perché ho usato il "5" su python.

delay(1000); //aspetto un po'. Perché? Perché siccome il mio dito è lento e Arduino è velocissimo, nel mentre che io premo il pulsante lui manda un sacco di "6" "6" "6" "6" "6" "6" "6"... a python che si mette ad aprire il programma di posta come un postino inferocito. Ne basta uno. Calma.

} //graffe. Sono belle a vedersi, perché non metterne un po'?

Lato python

premuto=ser.readline() #controllo se arriva una linea di testo via seriale, se arriva la infilo nella variabile "premuto".
if premuto=="6\n":#se mi è arrivato proprio un carattere 6 seguito da un accapo (ovvero una linea con 6 dentro) allora...
os.system("open /Applications/Mail.app")#fai una chiamata di sistema al programma Mail che si trova nella cartella applicazioni (e così facendo si apre anche la finestra)
premuto=""#questo ringiovanisce premuto, lo riporta alla sua verginità

Conclusioni

Sono certo che queste mie note saranno essenziali per un sacco di giovani programmatori. Nel caso ricordo che non disdegno offerte votive in incenso, frutta di stagione e bonifici bancari. Aggiungo anche che la luce della posta (questo il nome del marchingegno) fa colpo sulle ragazze, specie unenni con la febbre, ma ha il suo appeal anche su babysitter formose e in genere ospiti, intellettuali, uomini del folletto, testimoni di geova, etc. etc.
Ultima nota: giocare con queste cose è più divertente dei videogiochi, sorry. E c’è ancora gente che guarda la televisione.

Annunci