Teensy (post nerd e scacciafiga)

Tra i tanti progetti che porto avanti contemporaneamente, uno è quello della tastiera USB per macro universale.
Ricordate che di tanto in tanto faccio sottotitoli?
Ricordate che nel mio rozzissimo tutoriali per VSS decantavo l’utilità di una tastiera esterna con le macro?
Bene, quelle in commercio o non sono programmabili, o sono care impestate, o hanno troppi pochi tasti, o sono dispositivi per gaming troppo ingombranti.
Quindi ne ho messi in cantiere (sei mesi fa, credo, ormai) due modelli, uno molto piatto (una volta finito sarà poco più alto del circuito di comando, la cui altezza è influenzata soprattutto dalla presa USB) e uno pieghevole.
Com’è come non è (tagliare e forare il plexiglass è un lavoro di fino) il primo è rimasto indietro, ed ho terminato il secondo, più grezzo.
Sono partito da Arduino, nello sviluppo del progetto, ma ho ripiegato immediatamente su Teensy, molto più piccola, economica, e soprattutto ai tempi era l’unica a fornire una HID USB nativa.
Ne ho studiato la documentazione, ho rotto le scatole a diversi amici per un’estate sulla modificabilità di codici e librerie trovati online, ho provveduto all’acquisto.

Per la tastiera, il modello flat è una matrice di pulsanti su millefori (vedrete), per quello pieghevole, come vedete, sono quattro tastierini pseudo-telefonici acquistati su ebay collegati in matrice:

Come si può vedere, il fatto che colonne e righe avessero i pin mescolati e non in ordine non ha facilitato la cablatura.

C’è una sola vite per cerniera perché, fisicamente, l’altro occhiello andava in corrispondenza di una pista: mettere le altre quattro viti avrebbe significato danneggiare la tastiera, cosa che ho evitato per il resto del fissaggio inserendo le viti nei “montanti” plastici più esterni.

Ovviamente a lavoro finito ho rivestito il lato posteriore con una gomma antiscivolo, ho messo dei piedini alti quanto il chip+USB in modo da dare stabilità e ho lasciato una finestra trasparente per il LED e il pulsante di reboot (che serve per il caricamento del codice).

Già, il codice. Ho copiato e attinto da codice di diverse applicazioni, ho chiesto aiuto su un paio di forum quando la mia bozza non funzionava. M’hanno fatto levare gli apici dai case dello switch -boh?- e rileggendo le specifiche della libreria ho visto che dovevo togliere una colonna dal pin del LED (ebeh, RTFM).

È legnoso, ridondante, ma funziona.

#include < Keypad.h>

   int led = 11;
  const byte ROWS = 6;
  const byte COLS = 8; 
  char keys[ROWS][COLS] = {
    {38, 37, 36, 35, 14, 13, 12, 11},  
    {28, 27, 26, 25, 24, 23, 22, 21},
    {18, 17, 16, 15, 34, 33, 32, 31},
    {48, 47, 46, 45, 64, 63, 62, 61},
    {58, 57, 56, 55, 54, 53, 52, 51},
    {68, 67, 66, 65, 44, 43, 42, 41},
   
  };
  
  byte rowPins[ROWS] = {10, 12, 13, 14, 15, 16}; //connect to the row pinouts of the keypad
  byte colPins[COLS] = {1, 2, 3, 4, 5, 6, 7, 8}; //connect to the column pinouts of the keypad
  
  // Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup ()
{
  // initialize control over the keyboard:
  Keyboard.begin();
}  // end of setup

void loop () 
  {   
   
   
  digitalWrite(led, HIGH); 
    
    
    
   byte key =  kpd.getKey();
   if (!key)
     return;
     
  switch (key)
    {
    case 11: Keyboard.set_key1(KEY_F5); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now(); break;//start -100
    case 12: Keyboard.set_key1(KEY_F6); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now(); break;//start -10
    case 13: Keyboard.set_key1(KEY_F7); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now(); break;//start +10
    case 14: Keyboard.set_key1(KEY_F8); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now(); break;//start +100
    case 15: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //70%
             Keyboard.set_key1(KEY_7); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 16: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //80%
             Keyboard.set_key1(KEY_8); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 17: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //90%
             Keyboard.set_key1(KEY_9); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 18: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //100%
             Keyboard.set_key1(KEY_0); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 21: Keyboard.set_key1(KEY_F12); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now(); break;//stop -100
    case 22: Keyboard.set_key1(KEY_F11); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now(); break;//stop -10
    case 23: Keyboard.set_key1(KEY_F10); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now(); break;//stop +10
    case 24: Keyboard.set_key1(KEY_F9); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now(); break;//stop +100
    case 25: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //show pipe
             Keyboard.set_key1(KEY_H); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 26: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //Replace from pipe
             Keyboard.set_key1(KEY_R); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 27: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //Save
             Keyboard.set_key1(KEY_S); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 28: Keyboard.set_modifier(MODIFIERKEY_ALT);  Keyboard.send_now(); //play pause VLC
             Keyboard.set_key1(KEY_TAB); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_key1(KEY_LEFT); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now();
             Keyboard.set_key1(KEY_LEFT); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now();
             Keyboard.set_key1(KEY_SPACE); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(MODIFIERKEY_ALT); Keyboard.send_now();
             Keyboard.set_key1(KEY_TAB); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 31: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //wav display left
             Keyboard.set_key1(KEY_O); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 32: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //goto
             Keyboard.set_key1(KEY_G); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 33: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //find
             Keyboard.set_key1(KEY_F); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 34: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //wav display right
             Keyboard.set_key1(KEY_P); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 35: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //delay
             Keyboard.set_key1(KEY_D); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 36: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //redo
             Keyboard.set_key1(KEY_Y); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 37: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //strip tags
             Keyboard.set_key1(KEY_T); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 38: Keyboard.set_modifier(MODIFIERKEY_ALT); Keyboard.send_now(); //È
      Keyboard.set_key1(KEYPAD_0); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
      Keyboard.set_key1(KEYPAD_2); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
      Keyboard.set_key1(KEYPAD_0); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
      Keyboard.set_key1(KEYPAD_0); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
      Keyboard.set_modifier(0);  Keyboard.send_now(); Keyboard.print(" "); break;
    case 41: Keyboard.print ("Signor"); break; 
    case 42: Keyboard.print ("Professor"); break;
    case 43: Keyboard.print ("Dottor"); break;
    case 44: Keyboard.print ("Perché "); break;
    case 45: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //pause
             Keyboard.set_key1(KEY_P); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 46: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //previous sub
             Keyboard.set_key1(KEY_B); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 47: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //next sub
             Keyboard.set_key1(KEY_N); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 48: Keyboard.set_modifier(MODIFIERKEY_ALT);  Keyboard.send_now(); // play to end
             Keyboard.set_key1(KEY_RIGHT); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 51: Keyboard.print ("signor"); break;
    case 52: Keyboard.print ("professor"); break;
    case 53: Keyboard.print ("dottor"); break;
    case 54: Keyboard.print ("perché "); break;
    case 55: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //split
             Keyboard.set_key1(KEY_S); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;Keyboard.println ("55"); break;
    case 56: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //merge with next
             Keyboard.set_key1(KEY_M); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 57: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //merge dialog
             Keyboard.set_key1(KEY_D); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 58: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //loop
             Keyboard.set_key1(KEY_L); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 61: Keyboard.set_modifier(MODIFIERKEY_CTRL );  Keyboard.send_now(); //spell check
             Keyboard.set_key1(KEY_H); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 62: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //check error
             Keyboard.set_key1(KEY_K); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 63: Keyboard.set_modifier(MODIFIERKEY_CTRL | MODIFIERKEY_ALT);  Keyboard.send_now(); //error fix
             Keyboard.set_key1(KEY_F); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 64: Keyboard.set_modifier(MODIFIERKEY_ALT);  Keyboard.send_now(); //next error
             Keyboard.set_key1(KEY_N); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 65: Keyboard.print("- "); //dialogo
             Keyboard.set_key1(KEY_ENTER);Keyboard.send_now();Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.print("- ");
             Keyboard.set_key1(KEY_UP);Keyboard.send_now();Keyboard.set_key1(0); Keyboard.send_now();
             break;
    case 66: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); // Undo   
             Keyboard.set_key1(KEY_Z); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 67: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //text in italic
             Keyboard.set_key1(KEY_I); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    case 68: Keyboard.set_modifier(MODIFIERKEY_CTRL);  Keyboard.send_now(); //add subtitle
             Keyboard.set_key1(KEY_W); Keyboard.send_now(); Keyboard.set_key1(0); Keyboard.send_now();
             Keyboard.set_modifier(0);  Keyboard.send_now(); break;
    
    
    
    
      
    } // end of switch
  } // end of loop

Questo è il risultato finito:

E funziona, pure. Ne sono tanto stupito che questo post è grossomodo per chiedere “cosa ho sbagliato due volte per farla giusta?”.

Grinch.

Ogni Natale è peggio.

Ogni Natale mi trovo meno coinvolto in una festa imposta da miti sincretici che trovo insensati in una civiltà degna di tale nome e dal consumismo. Da ateo, non è una festa. Da razionale, so che si festeggia il solstizio, il sole invitto, eccetera, come ennemila anni fa. Che culo, Galilei, non hai sprecato la tua vita.

E poi, ‘sta cagata dello shopping natalizio, che tu provi a tornare a casa e ti trovi le locuste per strada a spolpare le vetrine, e preghi, quest’anno come da quando eri bambino, di trovare sotto l’albero un’apocalisse zombie.

Non pigliamoci per il culo, il mio affetto non lo comprate con un regalo dell’ultimo minuto. Non fatemene.
Lo stesso, non proverò a comprarvi io.
Se voglio farvi un regalo, ve lo faccio durante l’anno. Il mio affetto, la mia stima, provo a dimostrarvela senza guardare il calendario.
Se mi conoscete ne siete accorti. Non aspetto che sia il vostro compleanno, oppure che si sia prossimi alla festa che ha rubato la data al solstizio d’inverno: se vedo qualcosa che piace a me e che vi piacerebbe/vi servirebbe, ve la regalo.
Alla mi’moglie arrivano spesso pacchetti inaspettati -bischeratine, eh, niente mazzi di rose da 144-, a qualche amico è arrivato qualche gadget elettronico, o anche solo un attrezzo che ho trovato utile per me.
Ho sul cazzo i pranzi “volemosebbene”, di gente che se può ti scansa come la merda sul marciapiede per tutto l’anno, e per Natale invece “Su, dai, ci sono tutti i parenti/colleghi/compagni di squadra”.
Non capisco il babbaleismo di preziosa corrente sprecata -per non parlare degli alberi segati- per far lampeggiare lampadine.
Non capisco nemmeno a chi, maggiore di otto anni e cresciuto fuori da un cargo cult, possano piacere i fuochi artificiali, ma è un altro discorso. Anzi no, che ‘sto “cosa fai l’ultimo dell’anno?” l’ho sempre visto come “cosa fai mercoledì pomeriggio?”.
Non ho tredici anni, ormai il divertimento è andare a letto presto. Son vecchio, fatevene una ragione, avanza una fetta di pandoro -son pure a dieta- e una bicchierata di spumante, godeteveli. Non pensate a me che ho il giramento di palle perché tanto, anche se mi chiudessi in bagno durante il pranzo di Natale a lappare l’acqua dalla cassetta del water, troverei il modo di ingrassare ANCORA solo per osmosi gassosa. (Qui apro una parentesi: duecento, cento, cinquant’anni fa, il mangiare ipercalorico durante l’inverno era una necessità, che il freddo, il cibo scarso, eccetera. Ora che cazzo di bisogno c’è di ingollare cotechini, brodi di tacchino, farinate di castagne, al giorno d’oggi? E soprattutto, maledette le papille, c’è bisogno che siano così buoni?)

Vabbe’, sono vecchio E rompicoglioni, puntualizziamolo pure.

Però mi mantengo lucido nel cuore se non in testa.
Mi spaventano l’ipocrisia del “ti faccio un regalo anche se mi stai sul cazzo”, e, peggio, chi si fa coinvolgere dal clima natalizio, figlio delle agenzie pubblicitarie e dei servizi di Studio Aperto, e davvero ci crede, che siamo tutti più buoni.
Vi do una brutta notizia: anche se la incarti e ci metti il fiocco dorato, siamo sempre gli stessi pezzi di merda.
Siamo i pezzi di merda che la mattina del venticinque contano i regali ricevuti e dicono “Valfredo quest’anno non m’ha regalato nulla perché l’anno scorso gli ho riciclato il Risiko che non volevo, l’anno prossimo neppure io a lui faccio niente”, capaci di tenere a memoria tutto l’inventario di H&M per sapere quanto vale il golfino che t’ha regalato la zia, quanto vale quello che ha ricevuto tua cugina, e soppesare il presunto affetto relativo al centesimo.
Siamo i pezzi di merda che dicono “io alla cena ci vengo, però mettimi lontano da Valfredo, che nel ’67 m’è passato davanti in fila alla Posta”.
(Siamo tutti un po’ Valfredo, è per quello che non ci sopportiamo l’uno con l’altro, diciamocelo. Ma diciamocelo tutto l’anno, per carità.)

Insomma: io quest’anno non farò regali (come tutti i vecchi sono pure tirchio, se volete pensatela così) se non a moglie-genitori-suoceri perché tutto quello che VOLEVO regalare, i regali sentiti, ve li ho fatti durante l’anno.
Se non vi ho regalato niente, è perché non ne ho avuto l’occasione, non ho trovato niente adatto a voi.
E se l’occasione l’ho avuta, fatevi delle domande. Mi dispiace, le pillole dorate le ho messe tutte sull’abete dell’Ikea.