Stella di Natale.. Morse

C era una volta una stellina cometa ricavata di fretta un 20 dicembre da una scatola da scarpe con dentro una breadboard, diversi LED ad alta luminosità e un Arduino. Tuttavia, tre inverni fuori su un davanzale hanno portato alla necessità di costruire qualcosa di più serio, e siccome la sto realizzando in questi giorni, ho pensato di condividerla; siamo ancora in tempo per poterla costruire ed esporre.

Sto viaggiando in tempo reale, quindi ho deciso di pubblicare le fasi man mano che le realizzo. La prima fase è la parte fisica, ovvero la stella e un contenitore che difenda quello che si trova dietro. Nella seconda fase ci sarà la parte elettronica, decisamente semplice, mentre nella terza parleremo di software.

Nota: ho deciso di togliere il vecchio Arduino UNO e sostituirlo con un ESP32, per due ragioni: 1) OTA, 2) la connettività dà la possibilità di sincronizzare il tempo (per spegnerla di giorno quando sarebbe poco visibile), ed eventualmente comandare da remoto accensioni e spegnimenti.

Cos’è?

Si tratta della sagoma di una Stella di Natale retroilluminata a LED il cui lampeggio porta un messaggio in Codice Morse, personalizzabile. Ai più appare come una stella con l’intermittenza che funziona male, e li lascio nel loro brodo. Ma per i più curiosi potrebbe esserci una ricompensa: il messaggio nella mia Stella recita: BUON NATALE E FELICE ANNO NUOVO. SE CAPISCI SCRIVI A <email>. BIRRA GRATIS AI PRIMI 5. Confesso che nessuno ha mai reclamato birra, ma do la colpa alla strada poco frequentata. Comunque non credo che anche vivendo in Corso Sempione a Milano mi sarei svenato a dar via birre.

Però l’idea è alternativa, e visto che fare la parte del nerd non mi spaventa, vai di Morse!

PS il top è quando il tuoi vicini ti chiedono ma cos’ha la tua stellina che lampeggia male?

La parte fisica

Ho scelto di fare una Stella cometa nella forma di una maschera retroilluminata, ma ovviamente non è vincolante: forme diverse non cambiano la sostanza. In questa parte descrivo come ho realizzato il contenitore con la maschera a stella cometa, ma la fantasia non ha limiti, e magari qualche trucco può tornare utile nel caso in cui uno voglia disegnare un panda. Nel caso non si vogliano realizzare forme ma basti comandare una striscia LED, questa parte si può agilmente saltare a piedi pari.

Per il contenitore ho scelto una scatola ikea (Samla 401.029.78) con la bocca da 280×380 (mm)

Siccome ci serve conservare tutta la luce possibile all interno, ho scelto di fare una Foderatio Maxima con Domopak alluminio da cucina. Non prevedo grandi livelli di umidità dentro la scatola, per cui ho utilizzato Pritt colla stick.

come si vede, non è proprio un lavoretto da manuale; ma, in realtà, più pieghe ci sono più si aggiunge caos ai pattern luminosi all interno, quindi, pieghe, benvenute!

ho quindi aggiunto una striscia LED all interno. 12V 18W, niente di spaventoso; ma, quando si accende, lì dentro praticamente si scatena l’inferno. Siccome il perimetro alla bocca è di circa 124cm, una striscia da 5m farebbe 4 giri; togliendo le deviazioni delle sporgenze varie, si ferma un pochino prima. Il connettore è nella parte che ho deciso essere in alto, dove ci sarà l’elettronica, per via di eventuale condensa. Dai miei test, con illuminazione continua la temperatura all interno raggiunge al massimo 9 gradi in più rispetto all esterno.

Ma veniamo alla stellina. La maschera è stampata 3D in 4 parti, vista la dimensione (disegni più sotto).

La stampa è in nero, per evitare riflessi all’esterno. Tuttavia siccome il nero, appunto, non è noto per riflettere bene la luce, la parte che guarda all’interno sarebbe consigliabile se fosse il più bianco possibile. Infatti, ecco la maschera:

c’è un problema di fuoco nella foto, ne sono consapevole, ma volevo rendere l’idea. Il retro della maschera è così:

si tratta infatti di due pezzi per sezione: uno nero coi bottoncini sul retro, ed uno bianco coi fori per il corretto allineamento; ecco due dei pezzi faccia a faccia:

I pezzi vengono quindi incollati tra loro. La colla non è la mia soluzione preferita, la trovo troppo definitiva, tuttavia in questo caso è necessario visto che questa parte è esposta alle intemperie. La colla che ho scelto è silicone sigillante: non ha grandi caratteristiche meccaniche, ma davanti all’acqua ed all’umidità in genere si difende egregiamente. Incollare le due parti corrispondenti estrusione di silicone e spatolata per spargerlo:

..solito fuoco bellissimo. Nota importante: occhio ai gas: se oggi riesco a scrivere questo, è solo grazie al sistema di aspirazione fumi che uso quando saldo. Vale anche se uno decide di usare il bostik. Sconsiglio l’attak perché introduce una rigidità controproducente.

Una volta fatti i sandwich/cremino, serve una base: ho scelto plexiglass da 2mm da cui ho ricavato un 280×380. Riga, taglierino, santa pazienza, quando il taglio è almeno a metà si può provare a spezzare. Togliere la plastichina di protezione procedere all incollaggio, sempre con silicone:

dopodiché una notte di riposo con un deciso incoraggiamento alle superfici affinché si convincano a rimanere belle adese:

Come si vede, anche libri come Java 1.2 e Delphi possono avere una seconda vita. Ma alla fine è il TCP che tiene su tutto. PS Giuro che non l’ho fatto apposta, lo noto solo adesso. OK se volete fare i raffinati, prima del livello fisico mancano OSI 3 e 2, lo ammetto, cercherò di fare meglio la prossima volta.

Comunque, la notte trascorre, i pesi non sono precipitati, è ora di agire sulla trasparenza: non vogliamo che da fuori si riescano a contare i LED della striscia, quindi, dopo aver rimosso la plastichina anche su questo lato:

..si va di paglietta. Ho seguito due pattern: verticale e orizzontale, per raggiungere un coacervo di zigrinature che anche Giovanni Fresnel alzerebbe il cappello in segno di rispetto. Il risultato:

OK si intravede la fonte, ma è vaga. Molto bene. Dettaglio: si vedono le fessurine tra un pannello e l’altro. Ho rimediato così:

Con mano dalla fermezza granitica e pennarello a benzina, problema risolto. Procediamo alla impermeabilizzazione: entra in campo il neoprene, strisce adesive da 10x3mm da applicare sul bordo del contenitore:

là in fondo è quasi a fuoco.

Ho appositamente lasciato un piccolo spazio in basso a destra, per equalizzazione, eventuale condensa e spurgo umidità in eccesso:

Come fissare il frontale alla scatola? Presto detto: gancetti.

Sono dimensionati per far aderire la maschera e schiacciare leggiadramente il neoprene, in modo da avere tenuta, così se piove di stravento l’interno è protetto. Il risultato finale:

La maschera è sporca di detriti e residui di colla ma andrà pulita non appena avrò finito. Non è una cosa che strappa il cuore per la sua bellezza, ma la cosa alla quale stavo puntando non era l’eleganza.

Tutti i disegni per maschera, gancetti, e piedini di sostegno, si possono trovare QUI

..totalone della maschera:

Questa sarebbe la base nera (resa in rosso che è più visibile) coi bottoncini gialli e la stella in sottrazione. Stamparla in pezzo unico, come dicevo, non è possibile con la mia stampante, per cui ho optato per 4 pezzi; questi sono dimensionati in modo strano perché non volevo che dopo la sottrazione rimanessero isole (difficili da incollare centrate): ognuna delle 4 sezioni è effettivamente un pezzo unico. Questi sono i 4 pezzi neri:

e si chiamano xmas_star_XX_black dove XX è TL: Top Left, TR: Top Right, BL: Bottom Left, BR: Bottom Right; non sono io che alla mia età scambio ancora dx e sx, è che vanno stampati a faccia in giù e ad esempio TL, nella posizione definitiva, sarà a sinistra.

Questi sono i pezzi bianchi:

con i fori corrispondenti. I disegni si chiamano xmas_star_XX_white. Nel disegno i bottoni di aggancio sono da 9.8mm mentre i fori sono da 10mm, la tolleranza della stampa li rende compatibili.

Questi pezzi sono già pronti da stampare e producono un riquadro da 380x280mm che sarà la stessa dimensione del foglio di plexiglass.

Volendo hackerare il disegno o comunque riutilizzare qualcosa, ho allegato anche la stella per la sottrazione, sia intera che a pezzi:

gli STL si chiamano xmas_star_hole_X dove X è S: stella, T1: pezzo di coda 1, (T2, T3 si capisce), mentre whole è l’intero blocco, organizzato come si vede nell immagine.

I gancetti sono una di quelle cose che dici ma sì, banaaale, ed invece per trovare la forma giusta mi ci è voluto un pomeriggio; questi sono compatibili sia che la maschera sporga, sia che sia leggermente in dentro:

Questi sono adatti per quel tipo di scatola ikea; in xmas_box_hooks.stl ce n’è uno, in modo da poter decidere quanti stamparne; io ne ho fatti 5 per il lato lungo e 4 per quello corto che fa un totale di 18 gancetti ..che forse sono anche troppi, ma sto sperimentando man mano che procedo, li ho già stampati, e quindi li lascio.

Poi. Siccome il mio alimentatore ha la spina a 90 e non volevo alesare una voragine per farlo passare, ho optato per una femmina barrel jack.

..foro apposito

.. e connettore avvitato. Manca il maschietto barrel.

A posteriori ho pensato che potevo anche mettere una morsettiera, però in questo modo lo sgancio è più rapido: stacco i due connettori e posso togliere agevolmente il coperchio:

A questo punto ho fissato l’ESP alla basetta stampata, a “dead bug”, con fascetta di fissaggio:

le due colonne servono per fissare a scatto il piccolo hat che va dentro con un clic:

il supporto è fissato con Attak Gel: vista la superficie limitata ho pensato che forse è ancora accettabile nonostante la rigidità. La posizione è in alto, tra la stella e la coda.

Il supporto si trova sempre nei disegni 3D col nome xmas_star_electronics.stl; include anche la rondellina per la presa barrel.

Elettronica

Nella prima versione avevo alimentazione a 5V e 16 LED ad alta luminosità che avevano un Vf > 2.5 quindi non c era possibilità di fare catene: ogni LED sarebbe stato da solo, con il suo resistore. Si può fare, ma perché? Allora ho tirato in ballo due driver LED in corrente a 8 canali (TLC5917 Texas) che vanno pilotati con SPI. In pratica UCAS (Ufficio Complicazioni Affari Semplici) al massimo livello.

Per questa versione ho deciso di utilizzare una striscia LED stupida (no indirizzamenti, no colori, Solo LED con resistori e ingresso + e -) e un bel MOSFET. Questo semplifica enormemente il circuito come si vede qui:

I componenti sono:

Arduino, anche se ho utilizzato un ESP32, comunque il pin che uso è lo stesso (D13)

Resistore 1K 250mW per il MOSFET

Il MOSFET è un Infineon IRLB3813 che per bassa tensione è spettacolare: un pacco di amps, Rds nei mOhm (2.6 max con Vgs 4.5V), completamente eccitato anche a 2.35V il che lo rende ottimo anche per circuiteria con Raspberry o logica a 3V3, e ha solo un difetto: breakdown voltage è 30V, ma.. nessuno è perfetto. Datasheet nella cartella sul cloud.

Siccome forniamo solo 12V serve un regolatore di tensione per alimentare Arduino o ESP32: nell’immagine si vede un 7805 che è più che legittimo (ESP quando trasmette in WiFi assorbe 60-65mA e per il resto siamo nei 25-30) ma io preferisco usare dei DC/DC converter; stessa piedinatura, nel caso di questo l’efficienza è 96% e.. costa uguale. Anche di questo abbiamo il datasheet.

Il Cappone è un 1000uF 25V e l’ho messo perché mi avanzava, ma non è indispensabile.

Il LED è raffigurato come singolo LED per semplicità, ma deve essere una striscia con i suoi resistori, altrimenti si fa POP prima dell’ultimo dell’anno.

Il generatore di tensione è un alimentatore: ho scelto un Leicke 12V 2A; li uso in ambiente industriale (in mezzo ai macchinari) e se non scoppiano lì, vuol dire che in una casa vanno ancora meglio.

Questo è il DC/DC, piedinatura identica al 7805 (100mil distanza):

E il MOSFETtone:

che si legge anche poco, tanto per cambiare, dovrei comprare una macchina fotografica seria.

Come dicevo mi sono indirizzato verso l’ESP32, nella fattispecie il 38pin di cui ne ho una valigia:

ed ho fatto un mini-hat; questo è l’assieme:

Ci sono due connettori femmina da 6, di cui solo quello di destra è utilizzato; quello di sinistra è per ragioni di stabilità meccanica.

L’ingresso 12V è per il barrel jack standard 5.5×2.1 mentre l’uscita è una morsettiera con una codina con un plug maschio, stessa dimensione.

Nei datasheet si trova anche la piedinatura dell’ESP32 a 38 pin.

Software

Ci sono due versioni di software, da cui è possibile fare dei fork, e non escludo di farne io, ci sono tanti giorni prima di arrivare a Natale..

La parte interessante dal punto di vista analitico è rappresentata da come viene fatto l’encoding di ogni lettera/simbolo: per uniformare e ridurre il più possibile la dimensione del messaggio ho utilizzato una tattica astuta degna di Richelieu così che ogni carattere del messaggio pesi solo 1 byte, il che specialmente per la RAM dell Arduino è una gran cosa.

Non mi dilungherò qui sui dettagli, nell’header del sorgente è illustrato in modo esauriente e con esempi.

Siccome i dati vengono inseriti nel sorgente già pre-digeriti, nella cartella util si può trovare un foglio di calcolo (morse_code_array_encoding_r02.ods) che, dato il messaggio desiderato, genera l’array di byte già pronto da copia/incollare nel sorgente. Una volta digitata la stringa desiderata appare l’array con la sua lunghezza in caratteri; inoltre, volendo aggiungere la durata di un dit (il punto Morse) e la quantità di dit di pausa finale, prevede quale sarà la durata della trasmissione.

Vale per entrambe le versioni di software.

Arduino Standalone

La prima versione è per Arduino, vale anche per ESP, ed è senza collegamento WiFi. Si può trovare nel cloud nella cartella software, col nome xmas_star_ardu_r02. Non è niente di complicato, sostanzialmente è un “Blink.ino” on steroids, dove la tempistica/durata degli impulsi è programmata anziché essere fissa come nell originale.

ESP32 con OTA

La versione con OTA permette di fare update del firmware via WiFi.

Prevede delle parti fisse da non modificare e da posizionare esattamente dove si trovano; presuppone la presenza di un collegamento WiFi attivo. Tutte le parti necessaria (sono 3 in totale) sono evidenziate con un commento che recita “for OTA”.

OTA pone un problema: il listener deve essere sempre a disposizione, ovvero, deve essere chiamato con notevole frequenza per evitare che dall’altra parte (IDE) l’upload vada in timeout.

Mentre alcuni saranno già abituati a scrivere codice in questo modo, per altri potrebbe semprare ostico, ma lo spiegherò con un problema semplice: quello del blink.ino

Questo è il codice originale (più o meno):

void loop()
{
  digitalWrite(led_pin, HIGH);
  delay(1000);
  digitalWrite(led_pin, LOW);
  delay(1000);
}

il che significa che tutte le volte che siamo bloccati in un delay() sono occasioni perse per poter ricevere un aggiornamento di firmware. in questo caso il processore è dedicato ad un solo processo e non ha la possibilità di fare nient’altro.

L’altro approccio, che non è proprio multitasking ma è time-sharing, è questo:

byte led_status = 0;
byte led_pin = 13;
unsigned long change_last = 0;
unsigned long change_timeout = 1000;

void loop()
{

  // sottraiamo dal tempo attuale quello dell'ultima azione
  // a forza di dai e dai, passando di qui diventerà >= al timeout
  // e sarà ora di cambiare stato al LED di nuovo
  //
  if((millis() - change_last) >= change_timeout)
  {
    // memorizza l'ultima azione
    //
    change_last = millis();
    
    // cambia il led_status
    // se era già 1 lo riportiamo a zero
    //
    led_status++;
    if(led_status > 1)
      led_status = 0;
    
    // accendi o spegni i LED
    //
    digitalWrite(led_pin, led_status);

  }
  
  // e qui siamo liberi di fare tutto quello che vogliamo:
  // se non mettiamo nessun delay, da qui ci passiamo decine di
  // migliaia di volte al secondo: sarebbero tutti cicli buttati,
  // peccato non usarli
  //
  // infatti, usando lo stesso trucco, possiamo infilarci
  // diverse altre azioni, anche con tempi diversi: una al minuto,
  // una ogni 100ms, a seconda delle necessità
  //

}

Utilizzando questo trucco infatti, il software esegue le seguenti azioni:

  • verifica stato connessione WiFi
  • verifica stato connessione al server MQTT
  • invio di pacchetti MQTT keepalive
  • riallineamento ora reale via NTP server
  • verifica ora per eventuale spegnimento durante le ore diurne
  • ..ed ovviamente la funzione principale: gestire il pin di output

Tutte le funzioni, a parte il WiFi, sono opzionali e si possono disabilitare indipendentemente; ma senza l allineamento ora reale, la disattivazione nelle ore diurne non funzionerà.

A causa della necessità di eliminare tutti i delay(), anche le accensioni e spegnimenti dell’output vengono gestite allo stesso modo: quando è ora di accendere i LED il piedino sale e viene fissato il “timeout” per quando si dovrà spegnere: se è un punto Morse saranno 100-200ms, se è una linea 3 volte tanto; lo stesso vale per le pause successive allo spegnimento.

In 100ms un ESP32 con codice minimale fa 70K cicli: così appesantito, se nessun timeout scatta, me ne aspetto almeno 20-30K. Ma siccome non voglio farlo sudare ho messo un delay(1) nel main loop perché 1K cicli al secondo mi piace già abbastanza.

La parametrizzazione di questo software è decisamente più ampia della versione per Arduino, e prevede, tra le altre cose:

  • il messaggio da mandare, nel formato pre-digerito prodotto dallo spreadsheet
  • la durata del dit (il punto Morse) che è la base per la tempificazione del resto
  • la durata della pausa finale, prima di ricominciare
  • timer vari (WiFi, MQTT, time sync e controllo orario)
  • i dati di accesso obbligatori per il WiFi
  • i dati di accesso al broker MQTT
  • orari di fine e inizio broadcasting se si vuole interrompere di giorno
  • più tutti i flag per abilitare/disabilitare funzioni che non interessano

qualora MQTT sia abilitato, sul canale specificato si leggeranno i seguenti messaggi:

  • reboot
  • reconnect (in caso di riconnessione dopo una disconnessione)
  • keepalive ogni nn secondi (impostati nei settaggi)
  • quando si è spento e riacceso se lo spegnimento diurno è previsto
  • se c’è stato un problema durante la connessione NTP

Inoltre è prevista una parte per ricevere istruzioni via MQTT: il dispositivo è in ascolto sul canale specificato, e di solito lo uso per mandare parametri che alterano il funzionamento, ma in questo caso non ne ho previsti. In caso qualcuno sia interessato, posso condividere codice di altri dispositivi che lo fanno.

Importante: per far funzionare OTA:

Come prima cosa è necessario caricare il software via seriale. A questo punto l’ESP si può staccare e mettere in posizione definitiva, o fare un collaudo collegandolo ad un caricatore telefono; nell’IDE di Arduino, selezionando la Porta, apparirà una entry come questa:

C’è il MAC Address e l’IP. Se ce n’è uno solo tutti i santi aiutano, se è più di uno, occhio a centrare quello giusto. Io li tengo in DHCP ma ad ogni MAC assegno un IP, per essere sicuro.

Ma soprattutto occhio a una cosa: il software che si va ad installare DEVE contenere le parti per OTA: se faccio l’upload di blink.ino, la IDE non me lo impedisce, ma da quel momento quell’ESP non sarà più raggiungibile: al che è necessario andare, smontare, collegare alla seriale, ri-installare il firmware giusto, rimontare, il tutto contornato da esclamazioni non sempre gradevoli.

Finalmente ho finito di assemblare; posizionato sulla finestra, devo dire che probabilmente a un miglio nautico si vede ancora 😀

Nella cartella cloud c è un paio di video dimostrativi.

EDIT: ho identificato un possibile bug che si è verificato dopo due giorni di funzionamento: con questa architettura, dove più funzioni si palleggiano una situazione durante cicli diversi, scovare un buggo non è facile, specialmente se succede con cadenza di ore o giorni; ho già aggiunto il debug via MQTT ed installato il software su un altro paio di ESP di prova, ma attendo per avere più indizi; non appena scopro il problema faccio un upload della versione aggiornata.

Commenti e suggerimenti @freeant

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.