MacOS Sierra e driver CH340/41

Faccio brevemente il punto della situazione in base alla mia esperienza perché chi ha aggiornato a Sierra (come me) le sue macchine MacOS ha potuto sperimentare all’inizio una pletora di Kernel Panic ogni qual volta veniva collegata una scheda ESP8266 ai Mac.

Aggiornare ASSOLUTAMENTE i driver CH34X alla versione 1.3. Le versioni precedenti produrranno reboot continui di Sierra finché non verrà staccato il cavo USB collegato ad un ESP8266. Esistono vari link dove procurarsi l’ultima versione. Eccone ad esempio uno:

https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver

Rimuovere la versione precedente prima di installare i nuovi driver. In genere si tratta di rimuovere semplicemente da terminale il file usb.kext

Non è più necessario disabilitare la System Integrity Protection sul Mac per far sì che vengano viste le porte usb-serial di Arduino e degli ESP.

Quest’ultima è veramente una bella notizia. Si può ricominciare ad usare tranquillamente la IDE di Arduino senza abbassare la sicurezza del Sistema Operativo.

Sensore Adafruit BMP280

In genere quando si ha bisogno di un sensore barometrico, capace cioè di misurare la pressione atmosferica, si ricorre al classico BMP180, reperibile presso alcuni fornitori cinesi intorno ai 3 euro. Ci sono però in commercio versioni più precise e flessibili, come ad esempio il BMP280 messo in commercio da Adafruit, a circa 10 dollari. Se poi vogliamo anche che il modulo misuri l’umidità relativa sia Adafruit che Sparkfun hanno in catalogo il BME280, in entrambi i casi quotato sui 20 dollari. Quello Adafruit può essere alimentato sia a 5 che a 3.3V mentre lo Sparkfun solo a 3.3V. Personalmente non spenderei 20$ per avere anche la misura di umidità, ma a questo punto userei un BMP280 affiancato da un DHT22 (3-4€) risparmiando un pò ed ottenendo anche un’altra lettura di temperatura per controllo.

Comunque: cos’ha in più il BMP280 rispetto al suo predecessore BMP180? Innanzitutto è più preciso, specialmente nella lettura barometrica. Nel datasheet Bosch del BMP280, reperibile QUI, c’è anche una breve comparativa dei valori tra i due sensori, e poi nel caso del BMP280 possiamo usare sia l’interfaccia I2C che SPI.

bmp280-1

Come si nota in figura la scheda Adafruit espone ben 6 pin così indirizzati:

Volendo quindi utilizzare il BMP con il bus I2C è sufficiente collegare i pin SCK e SDI oltre all’alimentazione, mentre in SPI servono 4 connessioni più l’alimentazione. Quindi direi proprio nessun problema di convivenza anche con molti sensori di vario tipo sullo stesso controller.

E mettiamoci poi alla fine anche la qualità costruttiva e l’affidabilità dei prodotti assemblati da Adafruit.

Passiamo alla libreria di gestione: ovviamente Adafruit mette a disposizione sul suo sito una LIBRERIA per questo sensore che va utilizzata oltre a quella generica comune a tutti i sensori Adafruit.

Sugli articoli di qualche mese fa riguardanti il BMP180 avevo fatto uso della libreria Sparkfun, perché ritengo abbastanza inutile avere una funzione per l’altimetro se non si ha la possibilità di prendere una misura di pressione a 0 mt. sul livello del mare. L’altezza precisa del punto di misura (sempre fissa se costruiamo una Stazione Meteo) la possiamo ricavare meglio dal GPS di un cellulare ed usarla poi per ricavare la pressione S.L.D.M. che è direttamente confrontabile con i dati meteo pubblicati dalle fonti ufficiali. Quindi stavolta va bene la libreria di Adafruit e quest’ultima quantità ce la calcoliamo da soli.

bmp280-2

Ecco un breve sketch di esempio per Arduino utilizzabile, con le opportune modifiche di collegamenti ai pin,  anche su schede ESP8266:

Nella funzione utente leggi_BMP280() ho quindi ignorato la readAltitude() messa a disposizione dalla libreria a favore del calcolo della pressione SLDM. E’ possibile usare l’altimetro ma ricordiamoci che il parametro di input 1013.25 mBar è un valore assolutamente teorico e non garantisce precisione nel calcolo dell’altitudine. Sarebbe necessaria contemporaneamente e nello stesso luogo un’altra lettura di pressione sul livello del mare con cui “entrare” nella funzione readAltitude().

Un’ultima cosa: mi raccomando di non dimenticare la bmp.begin() dentro la funzione setup. Il sensore è calibrato in fabbrica e questa funzione ne chiama un’altra interna alla libreria, readCoefficients(), che acquisisce i dati di calibrazione inseriti dal produttore e memorizzati in alcuni registri interni del chip Bosch.

 

 

Arduino IDE e OS X

Sento ancora parlare di problemi di riconoscimento delle schede da parte di computer Apple con la IDE di Arduino, anche dopo aver disabilitato le protezioni messe in atto dalla casa di Cupertino da Yosemite in poi. Per mia esperienza personale devo dire che su 3 portatili che uso non ho avuto problemi provando a disabilitare la S.I.P., mentre il mio glorioso iMac fine 2009 rivitalizzato da diverso tempo con 12Gb di Ram e un disco SSD si dimostra un po’ capriccioso perfino nel riconoscere al volo le schede originali Arduino, figuriamoci i cloni e le ESP8266.

Ripeto che la soluzione migliore a mio parere rimane sempre e comunque quella di lasciare la S.I.P. (System Integrity Protection) di Apple attivata ed installare una Virtual Machine Linux sul Mac. Io personalmente utilizzo la Linux Mint su VMware Fusion,

mint_arduinoma si può tranquillamente utilizzare qualsiasi derivata Ubuntu. Ricordarsi sempre di aggiungere l’utente usato al gruppo “dialout” per garantirgli l’accesso alle porte seriali/USB virtuali create dalle schede. Come ambiente per le VM va benissimo il gratuito Virtualbox, ma ancora meglio VMware Fusion se già lo abbiamo acquistato. Altra cosa da non dimenticare una volta fatta partire la Virtual Machine è di “passare” il controllo dell’interfaccia USB a cui sono collegate le schede dall’host Apple alla VM tramite il menu “Macchina Virtuale”, altrimenti non verrà visto niente. In caso di inserzione successiva alla partenza della VM del cavo USB sarà lo stesso OS X a chiedere a chi si vuole assegnare la periferica.

Un’altra cosa molto comoda secondo me è depositare la cartella degli Sketch su una directory residente in un qualsiasi Cloud, in modo tale da avere codice e soprattutto librerie utente sempre sincronizzate in caso di accesso da più PC, qualsiasi sia il sistema operativo usato. Ovviamente questo tipo di approccio richiede l’installazione di un client per il nostro cloud che generi una cartella sincronizzata locale; l’accesso web non basta.

 

IDE Arduino 1.6.8

arduino_ide

Era da diverso tempo che usavo ancora la versione 1.6.5 della IDE di Arduino (sul Mac) soprattutto perché utilizzando adesso prevalentemente schede di tipo ESP8266 avevo trovato diversi problemi di compilazione con la successiva 1.6.6. Ho prudentemente ignorato la 1.6.7 ed ora ho voluto finalmente provare l’accoppiata 1.6.8 con il nuovo toolkit ESP v. 2.1.0.

Non uso più Windows da anni, neanche al lavoro 🙂 , quindi farò riferimento alla versione per OS X. Consiglio caldamente prima di aggiornare alla versione 1.6.8 di cancellare il contenuto della directory

Macintosh SSD -> Utenti > [NomeUtente] -> Libreria -> Arduino15

ovvero

/Users/[NomeUtente]/Library/Arduino15

per gli amanti (come me) del terminale. Non farlo può portare a problemi di riconoscimento delle schede. Fatto questo scarichiamo dal sito arduino.cc la nuova versione e la copiamo nella cartella Applicazioni al posto della precedente.

Rimettiamo di nuovo il path dove si trovano gli sketch e l’indirizzo dove prelevare i toolkit per le schede ESP2866. Quest’indirizzo si può copiare dal sito GIT

arduino_pref

Fatto questo andiamo nel menu Strumenti -> Gestore Schede ed installiamo il supporto per le ESP8266.

Ho provato a compilare una ventina di sketch diversi realizzati per questo tipo di schede e devo dire che tutto è andato regolarmente. In questi sketch ci sono molte librerie esterne, riferite a vari tipi di sensori, server e client HTTP, UDP e via dicendo. Di tutto insomma, e per fortuna non ho mai avuto problemi. Riguardo i sensori, quando possibile, cerco di preferire le librerie Adafruit, perché sono quelle che in genere mi hanno dato meno pensieri.

L’elenco di schede gestite dal supporto ESP8266 mi sembra piuttosto vasto:

schede

C’è anche l’interessantissima Wemos D1 mini di cui ha già parlato Heron sul suo BLOG. Io sto ancora aspettando pazientemente che me ne arrivi qualcuna dalla Cina , i tempi si sa sono biblici, ma quando arriveranno le proverò come nodi attivi/passivi di domotica. Simpaticissimi i mini shield 🙂

Forse qualcosa bolle in pentola anche riguardo la libreria di accesso diretto a Mysql per ESP8266, con il port di quella per Arduino. Ho trovato qualcosa e dopo aver effettuato delle prove ne parlerò. In conclusione insomma penso di poter adottare con una certa tranquillità la IDE 1.6.8 anche per le compilazioni con schede ESP8266.

ESP8266 – Quando un double è un double…..

Una ulteriore comodità messa a disposizione da queste piccole schede ESP8266 rispetto agli Arduino è che sono più flessibili e “precise” nel calcolo in virgola mobile. Mi spiego: in tutte le schede della famiglia Arduino (tranne Arduino 2) le variabili di tipo float o double sono comunque memorizzate in 4 bytes. Il che significa che hanno comunque la precisione tipica di un float (5 o 6 decimali, non di più). Se abbiamo bisogno di far girare codice che usa intensivamente variabili a doppia precisione questo può essere un problema. E’ pur vero che esiste per Arduino una libreria a precisione arbitraria chiamata BigNumber (https://github.com/nickgammon/BigNumber) ma se si ha necessità di far girare un bel po’ di codice scritto in C bisogna apportare significative modifiche al codice stesso, che perde di ogni portabilità, senza contare il degrado di prestazioni su un microcontrollore che gira a 16MHz.

L’alternativa poteva essere dotarsi di un Arduino 2 che ha le sue variabili double a 8 byte (quindi con 15-16 decimali significativi nel migliore dei casi) oppure, meglio ancora, usare un ESP8266 che ha le double a 8 byte e che “gira” a 80MHz, il che non guasta.

Se qualcuno si stesse domandando cosa ci facciamo con delle variabili double “vere” basti pensare a calcoli di fisica applicata, inseguitori solari, calcoli di sorgere e tramonto astri, e altre cose che in un progetto di controllo elettronico possono benissimo capitare. E che l’ESP8266 sembra possa gestire piuttosto bene sia come velocità di esecuzione che in termini di memoria.

 

Arduino e fotoresistori GL55XX

fotoresistenza

In precedenza ho illustrato come utilizzare il sensore TLS2561 per misure di luce in Lux di buona qualità, ma nella maggior parte dei casi possono essere utilizzati i più comuni fotoresistori della famiglia GL55 che, a fronte di una più bassa qualità costruttiva offrono tuttavia un “lavoro” più che decente oltre a costare enormemente di meno. Si tratta comunque di componenti passivi (a differenza dei fototransistor) che possono presentare variazioni dei valori caratteristici da esemplare a esemplare anche abbastanza importanti, ma se non abbiamo in mente di costruire un luxmetro di precisione ci possiamo anche accontentare. Per ottimizzare il codice che presento in seguito sarà bene tenere sott’occhio il datasheet di tutta la serie, che si può scaricare QUI, da cui andranno prelevati i valori della Dark Resistance e Light Resistance, tipici del modello. Nel mio caso, essendomi procurato dei GL5539, avrò rispettivamente come valori 5Mohm e 50Kohm.

Nel circuito ho utilizzato una resistenza di Pull-Down (o stabilizzatrice verso massa, come vogliamo chiamarla) di 10Kohm, che mi sembra un buon compromesso nel caso di una scheda Arduino generica che abbia come voltaggio di riferimento 5V. Ecco lo schema di collegamento su breadboard:

gl5539

Nello sketch andranno quindi valorizzati correttamente nella funzione di calcolo in Lux della lettura sensore i valori RD e RIF, deducendoli dal datasheet. La formula utilizzata per la conversione in Lux è decisamente migliore di quella che ho utilizzato in passato per il Keyes KY018 e ritorna un valore -1 in caso di saturazione del sensore, il che accadrà solo in presenza di forte luce solare diretta sul GL55XX. Al confronto con un Luxmetro vero le letture mi sono apparse sempre decenti, a conferma della bontà dell’algoritmo.

Ecco qui lo sketch di test. Ho utilizzato per l’output oltre l’uscita seriale anche uno dei miei LCD di cui ho parlato in precedenza, ma si può bypassare il codice sostituendo all’inizio la definizione #define LCD false a quella esistente.

SKETCH DI TEST:

 

SainSmart IIC/I2C/TWI – Display LCD seriale 2004 20×4

lcd04

Questo display prodotto dalla Sainsmart è decisamente un buon LCD, anche se mi ha fatto faticare un po’ per trovare una libreria che funzionasse con la IDE di Arduino 1.6.5. Ma andiamo per ordine. Dotato di 20 caratteri per 4 righe si presenta con un fondo blu retroilluminato e caratteri bianchi. Ne esiste anche una versione con sfondo “bianco” e caratteri neri, ad un prezzo che si aggira intorno ai 10-15 dollari, a seconda di dove si decide di acquistarlo. La grossa comodità che presenta questo LCD è che è pilotato dal bus I2C, il che significa che avremo bisogno di solo 4 connettori per gestirlo, 2 di alimentazione e i due classici SDA ed SCL. Nonostante le indicazioni del produttore la versione in commercio attualmente presenta un indirizzo I2C pari a 0x27 e non 0x34 come indicato. Se si ha qualche dubbio a riguardo dopo averlo acquistato è bene far girare, a collegamenti fatti, uno sketch contenente uno scanner I2C che ci possa indicare a quale indirizzo reperire l’LCD sul bus, in modo tale da riportarlo correttamente nella riga di configurazione. Uno sketch di questo tipo può essere reperito QUI.

Come ho accennato prima esistono alcune librerie su Internet, compresa quella indicata da Sainsmart, che sulle nuove versioni della IDE non compilano. Si tratta di codice rimasto fermo alla IDE 1.0.X, il che le rende assolutamente improponibili. C’è anche un po’ di ambiguità sul pin da utilizzare per gestire la retroilluminazione, il 13 negli schermi che ho io non funziona, va utilizzato il 3 e così via. Insomma, c’è rischio di perderci un po’ di tempo prima di vederlo funzionante e all’opera.

lcd01

Per farla breve quindi dirò che l’unica libreria che mi ha funzionato è reperibile a QUESTO indirizzo e che andando a rovistare tra il codice della stessa libreria ho ricavato tutte le funzioni disponibili per la gestione del display, che ho riportato nello sketch di test che pubblico qui di seguito.

SKETCH DI TEST:

 

Stazione Meteo 3.0 su ESP8266-12e

meteo3

Era prevedibile che portassi il nodo relativo alla Stazione Meteo da Arduino a ESP8266. La possibilità che offre questo modulo di entrare direttamente nella LAN casalinga fa sì che possa andare a scrivere direttamente i dati in un server MySql senza ricorrere ad intermediari. L’unico particolare è che non avendo ancora disponibile (per ora e per quanto ne sappia) una libreria che dallo sketch sia in grado di effettuare direttamente le INSERT nel database (cosa che per gli Arduino esiste da tempo) necessita di spedire i dati con il protocollo  HTTP ad un web server attrezzato con un interprete PHP, che potrebbe risiedere ad esempio nello stesso Raspberry dove gira MySql. Niente di complicato insomma, specialmente per chi già ha almeno conoscenze di base di questi ambienti.

Devo dire che il mercato di queste piccole schede è molto agguerrito e in continua evoluzione: già sono in commercio cloni di Arduino Uno dotati di moduli wi-fi ESP, che mantenendo lo schema di connessioni tipico di Arduino (comprese le molte porte analogiche che mancano agli ESP) abbassano notevolmente il costo della connessione wi-fi da svariate decine di euro a 5-6 euro. Un chiaro messaggio a chi riteneva che si dovessero spendere 70 euro per mettere un singolo Arduino in rete via wi-fi, francamente un’esagerazione.

Risolti i problemi di stabilità di cui ho parlato in precedenza (ora i moduli sono stabilissimi) rimaneva il problema del consumo di corrente, che è notevolmente maggiore di un Arduino Nano e che mi creava molti problemi ad alimentare la stazione con un battery pack a celle solari di quelli che si usano per ricaricare i cellulari. Il modulo può essere facilmente messo in “sleep-mode” e riportato in vita solamente per effettuare le letture diciamo ogni 5 minuti, il che abbassa drasticamente il consumo di corrente che altrimenti si manterrebbe su diverse decine di mA. Colpa ovviamente del modulo wi-fi che per collegarsi alla LAN e per rimanerci collegato, specialmente in caso di segnale basso, consuma molta energia.

Un’altra cosa interessante da sottolineare è il buon comportamento di questo modulo nei confronti del segnale wi-fi. Per la cronaca quelli che sto utilizzando ora sono i 12e venduti da BangGood a circa 6 euro, interfacciati verso la porta USB da un chip CH340 (altri produttori usano l’FTDI). Nonostante l’antenna “stampata” sulla scheda stessa non possa dare le stesse prestazioni di una esterna in termini di sensibilità devo dire che anche con un segnale di -94 o -96 dB raramente il modulo perde la connessione, e se accade si riaggancia al primo colpo al mio router. Tutto questo è documentato dal mio logger dove registro in tempo reale anche questo tipo di attività.

Lo sketch che pubblico di seguito invia i suoi dati via HTTP ad uno script PHP situato nella DocumentRoot di un server Apache che una volta letti i dati si occuperà di inviarli ad un server MySql installato, nel mio caso, sulla stessa macchina, un Raspberry Pi2.

Ecco lo script:

Esiste quindi un database con dbname = domotica e una tabella dove vengono depositati, ogni 5 minuti, i dati inviati dalla Stazione.

La tabella MySql avrà questa struttura:

Ho preferito mantenere il timestamp di ricezione dei dati in UTC, ovvero un orario di riferimento con fuso orario 0 con ottima approssimazione assimilabile al Tempo Medio di Greenwich perché non genererà date ambigue nel momento in cui si passa dall’ora solare a quella estiva, MySql permette poi in fase di interrogazione di riferirsi al fuso locale italiano (definito CET, e poi CEST quando in vigore l’ora estiva) con una query del tipo:

Qui devo fare una annotazione di tipo sistemistico: la funzione CONVERT_TZ() richiede che siano popolate alcune tabelle di sistema che generalmente sia in MySql che in MariaDB NON sono inizializzate. Per evitare che la lettura delle date ritorni dei valori NULL bisogna, da shell Linux, lanciare una utility che prelevi le informazioni relative alle timezone (tipicamente in /usr/share/zoneinfo) e le depositi nelle tabelle in questione. Il comando è:

Di seguito verrà chiesta la password dell’utente root del database. A esecuzione avvenuta si potrà andare nello schema denominato “mysql” e controllare che le tabelle [timezone_*], credo siano 4 se non ricordo male, siano popolate.

In poche parole la tabella nella sua forma originale si presenta in questo modo:

Schermata 2016-01-22 alle 21.56.33

E letta dalla query che ho indicato con le conversioni delle date in quest’altro modo:

Schermata 2016-01-22 alle 21.56.48

Ma passiamo ai collegamenti fisici: ho sostituito il “vecchio” lettore di luce KY018 con un più preciso e flessibile TSL2561 di Adafruit, digitale, che mi ha permesso di non scontrarmi con la poca flessibilità delle schede ESP con i sensori analogici.

“Solita” resistenza di pull-up sul sensore DHT22 (4.7Kohm o 10Kohm) e, cosa fondamentale un “ponte” possibilmente interrompibile tra il pin GPIO16 (D0) e il pin RST per far sì che funzioni il codice di Deep-Sleep del modulo. Questo circuito va chiuso durante l’esecuzione dello sketch e va aperto quando c’è da fare l’upload di uno sketch modificato. Mi raccomando, poiché con i due PIN cortocircuitati l’upload del codice dà errore e non funziona. Il Deep-Sleep fa risparmiare molta corrente, l’ESP quando è “dormiente” consuma pochi micro ampère  e quando viene risvegliato riesegue da capo lo sketch comprensivo della funzione setup(). Il che significa ovviamente che si riconnetterà di nuovo al wi-fi dopo esserne uscito per “addormentarsi”.

La mia Stazione è ormai da circa 24 ore in questa condizione di funzionamento e non ho rilevato comportamenti anomali o scorretti da parte del modulo.

Per quanto riguarda le librerie esterne, sono le stesse che ho già indicato in post precedenti relative agli stessi sensori. Adafruit per quanto riguarda i sensori DHT22 e TSL2561 e la SFE_BMP180 per il sensore barometrico.

Ecco quindi lo sketch che pilota il tutto:

Sostituire i valori della propria LAN nelle rispettive righe:

const char* ssid = “**********************”;
const char* password = “******************”;

nonché l’indirizzo IP del server HTTP:

String url = “http://192.168.3.100/insert_meteo.php?”;

e il nome del file php che si occupa della ricezione, che io ho chiamato “inserti_meteo.php”

La gestione del modo Deep-Sleep avviene in pratica sostituendo la classica delay() con questo codice:

uint32_t sleepTimeSec = 300;  // 300 secondi, ovvero 5 minuti
uint32_t sleep = (sleepTimeSec * 1000000);

ESP.deepSleep(sleep, RF_DEFAULT);

Trascorso il tempo indicato il modulo effettuerà un wake-up, in pratica un SOFT RESET, che NON rimetterà in esecuzione il codice dal punto in cui lo abbiamo lasciato, ma procederà ad una riesecuzione da capo della funzione setup() e poi loop().