PIC16F19197 Low-Power Touch Enabled LCD Demonstration

La Microchip mi ha inviato in anteprima una nuova demoboard munita di un display LCD custom equipaggiata con un PIC16F19197. E’ un’occasione buona per andare alla scoperta di alcune periferiche interessanti con cui sono equipaggiati molti nuovi picmicro: modulo LCD controller in primis, che ci permette di controllare i display a cristalli liquidi personalizzati (ovvero quelli non dotati di alcun controller).

La scheda è bella grande: lo dico perchè, vedendo le fotografie sul sito della Microchip, mi sembrava qualcosa di piccolo, del tipo dei classici display Oled che vediamo ogni giorno sulle varie schede di sviluppo: NO, le dimensioni sono generose: 126x144mm (per circa 315g di peso batterie comprese) che ne fanno, oltre che una interessante scheda di sviluppo, anche un bell’oggetto di arredamento.

La demoboard così come l’ho piazzata in casa sul tavolo. Per la felicità dei miei figli che hanno volentieri sacrificato qualche mattoncino Lego per una giusta causa

Da subito (vedi foto sopra) ho pensato di darle uno spazio fisso nel soggiorno montando uno stand con i Lego e vi assicuro che fa la sua bella figura e che gli amici mi dicono cose del tipo: “ma figo quell’orologio!”.

Analizziamo quindi nel dettaglio le varie sezioni che compongono l’elettronica in concomitanza con la parte software che la controlla (è disponibile il sorgente). Vi ricordo che nell’ultimo paragrafo, come sempre, ci sono tutti i riferimenti, nonchè il link alla pagina del prodotto da cui potete scaricare schema e codice sorgente con i quali proseguire nella lettura dell’articolo, dato che do anche piccole spiegazioni del programma.

Alimentazione

La scheda può essere alimentata tramite 3 batterie mini stilo (AAA – LR03) o tramite connettore micro-usb (la connessione è protetta da fusibile), si può passare da una sorgente di alimentazione all’altra mediante il deviatore posto sul retro della scheda. In caso di mancanza alimentazione (ovvero: viene disconnessa l’alimentazione USB, batterie scariche, sostituzione batterie, lasso di tempo durante lo switch da un’alimentazione all’altra), l’orario viene mantenuto grazie alla presenza di una batteria tampone CR2032 collegata al pin VBAT (RA5) del picmicro.

Dettaglio deviatore e connettore USB per l’alimentazione

Tale pin, presente sui picmicro di ultima generazione, consente all’oscillatore secondario (SOSC) e quindi al modulo RTCC (Real Time Clock Calendar) di continuare a funzionare anche in caso di mancanza della VDD e quindi indipendentemente dall CPU. Il pin VBAT è una funzione che va abilitata nella word di configurazione altrimenti il pin dedicato funziona come normale IO:

#pragma config VBATEN = ON

Il Picmicro funziona a 3.3V, la tensione prelevata dalla porta USB o dalle batterie viene scalata da un regolatore di tensione MCP1703 che ha la caratteristica di avere una bassa corrente quiescente (2.0 µA) e una tensione tipica di dropout (differenza minima di tensione tra ingresso e uscita) di 0,625V che consente quindi di sfruttare le batterie fino a che non arrivano a 3.925V (ovvero circa 1,3V per batteria).

Il display è retroilluminato con led bianchi. I led vengono pilotati da un driver MIC2287 che eleva la tensione di alimentazione a circa 15V a vuoto e circa 12V sotto carico, per poter pilotare i led collegati in serie con un segnale PWM, consentendo un minor consumo di corrente.

Personalmente ho misurato un assorbimento di circa 40mA a 5V (che salgono a 44mA con una tensione di 4.5V, quindi il consumo è di 2oomW circa):

Display -> Modulo LCD Controller

Come dicevamo sopra, il display è custom: la Microchip l’ha fatto realizzare su misura dalla Varitronix. E’ un display LCD a segmenti, senza controller: è il PIC che funge da controller.

Molti di noi sono abituati ad utilizzare display LCD già muniti di controller (per citare alcuni esempi: i classici display alfanumerici controllati dall’HD44780, il display a matrice di punti utilizzato nei vecchi cellulari Nokia e controllato da un PCD8544, i display a matrice di punti da 64×64/128×64/192×64 gestiti dal controller KS0108 e così via) per cui dialogare con essi è relativamente “facile” dato che la logica è già gestita dal controller e ci interfacciamo con esso mediante istruzioni che rendono tutto un po’ più semplice e immediato.

Nel caso di display LCD custom la logica la decidiamo noi e l’MCU che deve pilotare il display funge anche da controller. I vantaggi di questa soluzione sono essenzialmente due:

  • Possiamo farci realizzare display ad-hoc, con le nostre icone.
  • Ragionando su grandi quantità, i prezzi di un display senza controller sono più bassi.

L’unico svantaggio di soluzioni simili è che dobbiamo realizzare noi, soprattutto via software, un sistema per pilotare questi tipi di display, che hanno gli elementi luminosi (i pixel, le icone, i punti) arrangiati in una griglia organizzata in Segmenti (righe) e Comuni (colonne) e chiaramente è necessaria una MCU con un elevato numero di IO e di rampe di tensione di polarizzazione specifiche, ma in questo ci vengono appunto incontro i PIC dotati di modulo LCD Controller.

Sui datasheet, purtroppo, spesso il termine “segmento” viene utilizzato sia per identificare la riga, sia per identificare il singolo elemento da accendere (il pixel, l’icona, ecc).

Il display sulla demoboard ha una corona formata da 60 segmenti, che vengono utilizzati per illustrare graficamente l’andamento dei secondi. C’è una parte centrale formata da una matrice di pixel quadrati delle dimensioni di 7×28 pixels che viene utilizzata dalla demo per mostrare orario/cronometro e una scritta scorrevole. Negli angoli superiori sinistro e destro sono presenti 2 icone : Microchip e Varitronix. Sotto la matrice di punti sono presenti altre 2 icone circolari di una freccia rivolta verso destra e di un simbolo di check. Sopra la matrice sono presenti infine altre 4 icone: bussola, cronometro, orologio e batteria scarica (la prima e l’ultima icona non sono utilizzate dalla demo nella versione attuale: v2).

Icone sul display. Ogni icona è un elemento luminoso a se stante.

In totale abbiamo quindi 60+(7×28)+2+2+4 = 264 elementi arrangiati in una matrice di 33×8 (33 segmenti x 8 comuni). Questo tipo di display è chiamato 1/8 Multiplex.

Come dicevamo, il PIC utilizzato sulla demoboard ha un modulo dedicato appositamente al pilotaggio di LCD (LCD Controller Module) in grado di controllare fino a 368 punti (46 segmenti x 8 comuni), ed è munito di una pompa di carica che serve per innalzare la tensione di alimentazione alla tensione richiesta dai segmenti per poterli illuminare (5V nel nostro caso). 

Per il funzionamento della pompa di carica è richiesto un condensatore tra due pin (RH2 e RH3). Il PIC genera inoltre da sè le rampe di tensione di polarizzazione mediante una rete resistiva interna per la quale sono necessari altri 3 condensatori da collegare ai pin contrassegnati come VLCD1/2/3.

Sul datasheet potete notare che molti pin hanno anche l’identificazione COMx (Comune X, dove x va da 0 a 7) e altri SEGx (Segmento/Riga x, dove x va da 0 a 45): tutti questi pin servono appunto per controllare righe e colonne.

Per utilizzare il modulo LCD è necessario innanzitutto abilitare la pompa di carica nella word di configurazione:

#pragma config LCDPEN = ON

E’ necessario quindi configurare i vari registri. In particolare è necessario specificare il numero di comuni:

LCDCONbits.LMUX = 0b1000;

Abilitare le funzionalità della pompa di carica nel registro LCDVCON1:

//LCDVCON1
LCDVCON1bits.LPEN = 1;  // la pompa di carica lavora in modalità bassa corrente
LCDVCON1bits.EN5V = 1; // viene abilitato il range di 5V
LCDVCON1bits.BIAS = 0b111;  // la tensione di uscita della pompa di carica viene impostata a 5.1V

e delle tensioni di polarizzazione nel registro LCDVCON2:

//LCDVCON2
LCDVCON2bits.CPWDT = 0; // disabilita il watchdog timer del modulo LCD
LCDVCON2bits.LCDVSRC = 0b0110; // le rampe sono generate esclusivamente dalla rete resistiva interna, quindi sui pin VLCD1/2/3 andranno solo posti dei condensatori

Altre impostazioni sono presenti nella funzione LCD_Initialize() in lcd.c. In LCD.h sono contenute le definizioni dei singoli segmenti (punti luminosi). Esempio:

#define S1 S19C7 // T1
#define S2 S41C7 // T2
#define S3 S27C7 // T3

S19C7, ad esempio, indica Segmento (riga) 19, Comune (colonna) 7 ed è un nome mnemonico già definito nell’header del pic (pic16f19197.h).

L’header si trova in un percorso del tipo C:\Program Files (x86)\Microchip\xc8\v1.43\include\ 
dove v.143 è la versione del compilatore XC8, attualmente 1.43 è l’ultima

I defines da S1 a S60 fanno riferimento ai trattini che compongono la corona dei secondi, le icone sono definite con il loro nome in chiaro (ARROW, CHECK, MICROCHIP, VARITRONIX ecc). I punti della matrice centrale sono chiamati XnCn dove n va da 1 a 7 ed identifica la riga della matrice (la 1 è in alto) e C è la colonna che va da 1 a 28.

Ad esempio, per far comparire il disegnino dello space invader (a meno dell’ultima parte delle antenne, per cui ci sarebbe voluta un’altra riga sul display) ho scritto:

void SpaceInvaderIcon(void)
{
X4C10=1; X5C10=1; X6C10=1;
X3C11=1; X4C11=1;
X2C12=1; X3C12=1; X4C12=1; X5C12=1; X6C12=1;
X1C13=1; X2C13=1; X4C13=1; X5C13=1; X7C13=1;
X2C14=1; X3C14=1; X4C14=1; X5C14=1; X7C14=1;
X2C15=1; X3C15=1; X4C15=1; X5C15=1;
X2C16=1; X3C16=1; X4C16=1; X5C16=1; X7C16=1;
X1C17=1; X2C17=1; X4C17=1; X5C17=1; X7C17=1;
X2C18=1; X3C18=1; X4C18=1; X5C18=1; X6C18=1;
X3C19=1; X4C19=1;
X4C20=1; X5C20=1; X6C20=1;
}

Per il banner (la scritta scorrevole al centro), è stata creata una funzione apposita: fate riferimento ai file banner.h e banner.c. In banner_strings.h potete anche cambiare la scritta rispettando le specifiche (max 10 linee, max 70 caratteri per linea, non pià di 450 caratteri int totale).

// Max number of character per line should be less than 70,
// up to 10 lines, and no more than 450 characters total
const char* stringArray[10] = {

Touch-Screen -> Modulo ADC con CVD + Framework mTouch

Il display è sormontato da un vetro che funge da touch screen capacitivo. Non è un touch screen di come quelli che si trovano sui cellulari, in cui è possibile rilevare la pressione su qualsiasi punto della superficie dello schermo (2D) ma è del tipo 1D: ci sono soltanto alcuni “spot” (sensori) in cui è possibile rilevare la pressione. In particolare su questo display ci sono 8 sensori: due sono collocati al di sopra delle icone Freccia e Check e 6 sono disposti intorno alla corona circolare a formare una “ruota capacitiva” (wheel).

Principio di funzionamento del touch screen capacitivo: toccando l’area sensibile, il corpo introduce una capacità aggiuntiva a quella di riferimento.

Per la gestione dei Touch Screen 1D la Microchip ha realizzato un Framework apposito chiamato mTouch™ (che, tra l’altro, è anche possibile includere nei propri progetti mediante il Code Configurator integrato in MPLAB X IDE). La libreria gestisce Pulsanti (spot singolo), Sliders (movimento del dito in avanti e indietro lungo una linea/sensore) e Wheels (movimento circolare in senso orario / antiorario su più sensori disposti a cerchio). Di base la libreria utilizza semplicemente il modulo A/D per cui in teoria sarebbe possibile utilizzarla su qualsiasi MCU dotata di questo modulo ma in realtà la gestione del touch è una cosa davvero complessa da implementare a causa dei numerosi disturbi che è possibile captare, per cui avere a disposizione un modulo hardware dedicato a questo specifico compito semplifica di molto il lavoro.

Molti Picmicro hanno delle periferiche specializzate per il touch e queste sono il CTMU (Charge Time Measurement Unit) e il modulo A/D con CVD Hardware (Capacitance Voltage Divider, indicato anche come HCVD, dove la H sta per Hardware).

Dato che ora gli AVR fanno parte del gruppo Microchip, aggiungo che anche alcuni AVR hanno una periferica dedicata alla gestione del touch, che si chiama PTC (Peripheral Touch Controller).

Il PIC sulla demoboard ha il modulo HCVD che si basa sul principio del partitore di tensione capacitivo: due condensatori (quello di riferimento, interno al pic, e la capacità aggiuntiva creata dalla pressione del dito sul sensore) messi in serie accumulano la stessa quantità di carica, ma la tensione ai loro capi è in funzione della capacità (maggiori informazioni sul funzionamento del modulo CVD si trovano nel datasheet a pagina 289).

Nel software sono definiti 8 pulsanti collegati ognuno ad un sensore touch del vetro e identificati con numeri da 1 a 8. I pulsanti 7 e 8 sono collegati rispettivamente alla porta analogica RA2 e RB0 e sono rappresentati dai pulsanti freccia e check. I pulsanti da 1 a 6 (RA7, RA6, RA3, RA1, RA0, RA4) sono rappresentati da pad disposti a cerchio intorno alla corona e vengono gestiti dal codice in maniera leggermente diversa per poter rilevare il senso di scorrimento del dito.

Layout disposizione pad capacitivi. Grazie a Xiang Gao della Microchip

Le operazioni della funzionalità mTouch vengono scandite dal Timer4 che genera un interrupt ogni 5mS circa. Il timer4 viene configurato per utilizzare come sorgente di clock LFINTOSC (Oscillatore Interno a bassa frequenza, che vale 31KHz). Pre e Post scaler sono impostati a 1:1 e il registro T4PR (Timer 4 Period) è impostato a 154 per avere un interrupt ogni 5mS circa:

T4CLKCONbits.CS = 0b0100; // sorgente di clock: LFINTOSC (31KHz)
T4RST = 0x00; // Timer 4 resettato dal suo stesso interrupt
T4PR = 0x9A; // Timer 4 Period: 154

Utilizzando il clock a 31KHz (periodo: circa 32µS), il contatore del timer incrementa ogni 32µS, ad ogni colpo di clock viene confrontato il valore del contatore con quello impostato nel registro T4PR, per cui si avrà match dei due valori ogni 32µS*154 = 4967µS ≅ 5mS. Se viene abilitato l’interrupt, si alzerà il flag relativo, il Timer4 si resetterà in automatico grazie all’impostazione del registro T4RST.

Gestione del cicalino

Il Pic utilizza il clock interno a 8MHz (OSCFRQ settato nella funzione OSCILLATOR_initialize in Hardware.c)

Il cicalino è di tipo passivo, quindi è necessario che venga comandato da un’onda quadra. Anzichè generare un’onda quadra via software alternando lo stato di uscita di una porta, viene comandato dal modulo PWM3 configurato per avere l’uscita su RC4 (RC4PPS=0x0B, pag. 448 datasheet). Il PWM3 viene impostato per essere alimentato dal Timer2. Nella configurazione il prescaler è impostato a 1:4, come sorgente di clock viene selezionato Fosc/4 e il periodo (registro PR2) viene impostato al valore 79. Il periodo PWM è dato dalla formula:

Tpwm = (PR2 + 1)*4*Tosc*Ps

Dove Tosc=1/Fosc=1/8000000 e Ps è il valore di Prescaler (4). Il periodo è quindi di 0,00016sec che corrisponde a 6.25KHz. In pratica per far suonare il cicalino viene attivato il Timer2 per 100mS in modo che si attivi il PWM, e quindi spento.

Modulo RTCC

Il modulo RTCC (Real Time Clock Calendar) è quello che si occupa della gestione automatica dello scorrere del tempo e viene alimentato dall’oscillatore secondario (SOSC), esterno, rappresentato dal quarzo da 32.768KHz.

La cosa bella di questo modulo su questo pic è che, se non vogliamo utilizzare il quarzo esterno, può anche essere utilizzata l’onda sinusoidale di rete a 50Hz o 60Hz (con le opportune precauzioni!) impostando un circuito interno di zero cross detect.

SOSC e modulo RTCC continuano a funzionare anche in assenza di alimentazione grazie alla batteria tampone collegata sul pin VBat. Il modulo ha in pratica registri separati per anno, mese, giorno, giorno della settimana (lunedi, martedi…), ore, minuti e secondi che si incrementano in automatico gestendo anche l’anno bisestile. Sono presenti corrispondenti registri di tempo per poter impostare un allarme. In particolare viene impostato il registro Alarm per fare in modo che ci sia un’allarme (interrupt) ogni secondo:

ALRMCONbits.AMASK = 0b0001;

Nella routine di interrupt lanciata dall’allarme viene gestito lo spegnimento dei segmenti della corona per mimare il passaggio della lancetta dei secondi.

Funzionamento della demo

Appena accesa la board viene mostrata la scritta scorrevole.

Premendo l’icona di freccia a destra, viene mostrato l’orologio: si accende l’icona dell’orologio, la corona dei secondi si accende e un segmento alla volta si spegne per mimare il passaggio della lancetta dei secondi. E’ possibile passare dalla modalità 12H alla 24H premendo il pulsante Check. Premendo contemporaneamente Freccia e Check si regola l’orario: passando il dito sulla corona dei secondi in senso orario/antiorario si incrementa/decrementa il valore delle ore o dei minuti, si passa dall’ora ai minuti premendo la freccia. Premendo check si conferma e si esce.

In modalità orologio, premendo la freccia a destra, si accede al cronometro. Premendo check si fa lo start/stop, premendo contemporaneamente freccia e check si azzera. In questa modalità la corona dei secondi non scorre di continuo ma viene divisa in gruppi di 15 secondi: in pratica la corona viene divisa in 4.

Galleria

Collegamenti esterni

 

Se questo articolo ti è piaciuto, condividilo su un social:
Se l'articolo ti è piaciuto o ti è stato utile, potresti dedicare un minuto a leggere questa pagina, dove ho elencato alcune cose che potrebbero farmi contento? Grazie :)