Progetti - PIC

 

Gadget a LED


Un LED che lampeggia per molti mesi....

Una semplice applicazione didattica che fa parte del corso PIC presentato su questo sito (Esercitazione 17A) dimostra come sia possibile realizzare con gran semplicità il classico lampeggiatore a LED che, alimentato da una pila a bottone, funziona per molti mesi. 

Utilizziamo uno dei piccoli PIC della famiglia 10F2xx, del quale sfruttiamo la modalità di sleep e il watchdog.

Possiamo realizzare un circuito basato su questi principi:

Sono necessari solamente 5 componenti:

  1. il microcontroller
  2. un condensatore sull' alimentazione (100nF)
  3. il LED
  4. la resistenza di limitazione della corrente
  5. la batteria

Il circuito è alimentato con un comune elemento a bottone tipo CR2032, a 3V: si tratta della classica pastiglia usata per sostenere la memoria CMOS nei personal computer e quindi assai diffusa e facile da recuperare, ma va benissimo qualsiasi altra batteria similare, dato che i PIC in questione possono scendere con la Vdd fino a 2V. 

Per quanto riguarda i tempi di commutazione, ricordiamo che non è possibile agire sul clock, dato che questi chip possono operare solamente con quello interno a 4MHz; quindi non è possibile avere un clock a frequenza più bassa. Se usassimo le solite waste time o con Timer0 per ottenere i tempi di on e off del LED, il chip sarebbe sempre in funzione a 4MHz e questo produrrebbe un consumo eccessivo per la nostra applicazione.

A questo si ovvia utilizzando la modalità di sleep e il watchdog WDT come timer.


Il LED viene acceso per circa 20ms una volta ogni uno o due secondi.

Nei periodi di pausa, il chip è mandato in sleep per ridurre il consumo.

Ne risulta un oscillogramma come quello a lato (base dei tempi : 1s/div).

Si nota come l’intervallo del WDT sia,in questo caso, di circa 2.4ms  (WDT non è un temporizzatore di precisione).


Per ridurre ulteriormente la corrente media, il periodo di accensione è composto da una serie di impulsi di 1ms.

Nell’ oscillogramma a lato la base dei tempi è passata a 5ms/div.

Data la rapidità, anche se non si percepisce sfarfallio e l’occhio riconosce un flash unico, l’ oscilloscopio cattura la situazione reale.

Variando la durata e la quantità degli impulsi variamo l'illuminazione del LED.

E' importante sapere che la risposta dell' occhio non è lineare e un aumento del tempo di accensione (o della corrente nel LED) oltre un certo limite non portano benefici nella intensità luminosa percepita, mentre possono aumentare sensibilmente il consumo di corrente.

Nel programma, la durata della routine di ritardo Delay1ms determina il ciclo on/off , mentre il parametro step stabilisce quante volte viene ripetuto; variandoli, si potranno sperimentare combinazioni diverse.
Con i valori attuali si hanno 10 impulsi da 1ms ciascuno.

Nel complesso, per una corrente del LED, negli istanti di accensione,superiore a 20mA, la corrente media è di circa 2.2uA! Una batteria da 200mAh dovrebbe poter durare migliaia di ore.
Con un LED ad alta luminosità, il lampeggio è ben visibile anche al sole, mentre di notte si può percepire bene a un centinaio di metri di distanza.

Come detto, il tempo di uno o due secondi circa tra un lampeggio e il successivo è prodotto non da una routine di conteggio, ma dall’ intervento del WDT sullo sleep: variando il pre divisore del watchdog sarà possibile variare il tempo di overflow. I valori utili per l' applicazione sono:

  • 1:32  che rende circa 0.6s
  • 1:64 che rende circa 1.2s
  • 1:128 che rende circa 2.4s  

Potete sperimentare diverse combinazioni di pre divisore e durata degli impulsi di accensione e scegliere quella migliore a seconda dell' applicazione. Ad esempio, se il circuito è usato come luce di avviso per una bicicletta, è probabilmente migliore un ciclo breve, 0.6s; in un giocattolo o in avvisatore andrà bene 1s. In un gadget da cui si aspetta una durata di batteria di molti mesi si ricorrerà ai 2.4s.

La resistenza in serie al LED serve a limitare la corrente. Si trova comunemente la formula di calcolo:

Rled = (Vdd – Vled) / Iled

Dove Vled è la tensione di conduzione del LED.  Se abbiamo Vdd=3V, Vled=2V e Iled=10mA:

Rled = (3 – 2) / 0.010 = 100ohm

Però, con bassi valori di tensione Vdd e alti valori di tensione di conduzione del LED, va tenuta presente anche la caduta di tensione Voh sul MOSFET dell’I/O, che non è 0V. Quindi il calcolo corretto sarà:

Rled = (Vdd – Vled – Voh) / Iled

Così, se Voh=0.4V abbiamo:

Rled = (3 – 2 – 0.4) / 0.01 = 60ohm

Che potrà essere normalizzato al valore comunemente reperibile di 56ohm.
Va considerato anche il fatto che la tensione di batteria tende a ridursi con l’uso e quindi a ridurre la corrente nel LED; questo ridurrà leggermente la luminosità col tempo.
Dato, però, che i port possono portare nominalmente 25mA e che la corrente al LED viene erogata a impulsi, con un basso duty cycle, possiamo usare una resistenza più bassa di quella calcolata, ad esempio 33ohm, che permette il passaggio di 18mA circa. Se usiamo LED a bassa corrente (2-5mA), potrà essere attorno ai 100ohm; per un calcolo preciso del valore, potete consultare queste pagine. Comunque, la resistenza dipende essenzialmente dalle caratteristiche del LED che utilizzate, dalla luminosità che si vuole ottenere e dal consumo di corrente che possiamo accettare, ovviamente senza superare i 25mA gestibili dall’uscita digitale.

Di sicuro non è possibile accendere LED la cui tensione sia maggiore di quella di alimentazione; quindi, con la batteria scelta non possiamo pensare di usare con questo circuito LED blu o bianchi che hanno una tensione di conduzione più alta di 3V.

Il circuito può essere sperimentato sulla LPCuB con gran semplicità, aggiungendo solamente i ponticelli necessari:

Qui possiamo variare il periodo degli impulsi di accensione ed il loro numero, a seconda di quello che si vuole ottenere: minore è il tempo al di fuori dello sleep, maggiore è il consumo, ma maggiore è la luminosità ottenuta. Minore è il tempo di accensione o il duty cycle, minore è la luminosità percepita del LED, ma minore sarà il consumo e maggiore la durata della pila.
Si potrà far variare anche il tempo di intervento del WDT portandolo a 1s (variare nel programma il prescaler a 1:64), o anche meno, ottenendo una accelerazione dei lampeggi (maggiore corrente media assorbita).

La scheda di sviluppo contiene molti componenti che assorbono corrente, come il LED verde di ON e il potenziometro VR. Una volta verificato il funzionamento si potrà anche portare il tutto su un piccolo stampato per avere un oggetto finito:

Dono usati componenti comuni, per montaggio su foro, a parte il condensatore in parallelo ai pin di alimentazione del chip (0.1-4.7uF).

Il circuito prevede una presa ICSP per poter collegare il Pickit anche qui e operare modifiche al firmware senza rimuovere il chip.  Questa presa dispone di soli 5 pin per ragioni di spazio; viene escluso il pin 6 che non è utilizzato per la programmazione di questi chip:


Volendo miniaturizzare, si potrà usare il package SOT-23, montato sul lato opposto della batteria.
Anche qui possiamo prevedere comunque una presa ICSP usando il Tag-connect:

Usando una batteria più piccola ed eliminando la presa ICSP si potrà miniaturizzare alquanto il circuito.

Il lampeggiatore può essere usato come spia per apparati vari, parte di giocattoli o per individuare oggetti o ostacoli al buio o come semplice gadget; oppure, comandando più LED, può essere la base di una luce di riconoscimento per ciclisti o pedoni notturni. Data la bassa tensione disponibile, più LED potranno essere pilotati usando più pin. Con i PIC10F si hanno ancora a disposizione GP0 e GP1. E' anche possibile collegare più LED in parallelo, sempre rispettando la massima corrente in uscita (25mA).
La stessa applicazione, con le solite piccole modifiche alla definizione del processore, alla configurazione ed al setup iniziale degli I/O potrà girare su qualsiasi Baseline, e, in generale, su qualsiasi PIC, con a disposizione un numero maggiore di I/O.


Il programma

E' estremamente semplice.

Il sorgente è scritto per potersi adattare a PIC10F200/202/204/206, variando il processore dal menu del progetto MPLAB.
Le definizioni sono selezionate con statement #ifdef, mentre viene definita una label proccomp che serve nella compilazione ad adeguare le risorse di I/O per quei processori che dispongono di comparatore (che va disabilitato se si vuole utilizzare solamente la funzione di I/O digitale).

Il tempo di ripetizione tra le fasi on del LED è dato dal prescaler attribuito al WDT: con 1:64 si ha un lampeggio ogni 1.2s circa. Con prescaler 1:128 si arriva a 2.4s circa.
La variabile step indica il numero dei lampeggi a 1ms di cui è composta una fase on del LED. Questo parametro potrà essere variato a piacere a seconda dell' effetto che si vuole ottenere. Ovviamente il tempo complessivo della fase on del LED dovrà essere minore del tempo del WDT; ovvero, ad esempio, impostando wdf per un overflow a 1s, il tempo di on dovrà essere decisamente minore di 1s. Tenete presente che il WDT non è un timer di precisione e il suo clock può variare sensibilmente con la temperatura e la tensione Vdd.

Esaurita la fase on, il processore è mandato in sleep, dal quale si risveglia (wake up) all'overflow del WDT.
Per come è scritto il programma, il WDT inizia a contare dopo il primo clrwdt (che azzera counter e prescaler del watchdog); contemporaneamente si esegue la fase on del LED, per cui il tempo residuo di off è pari al tempo del WDT meno quello della fase on.
Decommentando le righe prima dello sleep si prolungherà il tempo di lampeggio, azzerando counter e prescaler a quel punto.
 

;********************************************************************
; 17A_10F.asm
;--------------------------------------------------------------------
;
; Titolo :  Corso Assembly & C - Esercitazione 17A
;           Lampeggia un LED collegato a GP2.
;           ton=20ms toff=2,3s in sleep per basso consumo.

; PIC      : 10F200/2/4/6
; Supporto : MPASM
; Versione : 1.01
; Data     : 01-05-2013
; Autore   : afg
;
;
; Impiego pin :
; ----------------
; 10F200/2/4/6 @ 8 pin DIP 10F200/2/4/6 @ 6 pin SOT-23
;
;        |¯¯\/¯¯|              *¯¯¯¯¯¯|
;   NC  -|1    8|- GP3    GP0 -|1    6|- GP3
;   Vdd -|2    7|- Vss    Vss -|2    5|- Vdd
;   GP2 -|3    6|- NC     GP1 -|3    4|- GP2
;   GP1 -|4    5|- GP0         |______|
;        |______|
;
;                       DIP  SOT
; NC                     1:
; Vdd                    2:  5: +
; GP2/T0CKI/FOSC4/[COUT] 3:  4: Out LED alla Vss
; GP1/[CIN-]/ICSPCLK     4:  3:
; GP0/[CIN+]/ICSPDAT     5:  1:
; NC                     6:
; Vss                    7:  2: -
; GP3/MCLR/VPP           8:  6:
;
; [] solo 204/6
;
;********************************************************************
; DEFINIZIONE DI IMPIEGO DEI PORT
; GPIO map
; | 3  |  2 |  1 |  0 |
; |----|----|----|----|
; | in | LED|    |    |
;
;#define    GPIO,GP0  ;
;#define    GPIO,GP1  ;
#define LED GPIO,GP2  ; LED tra pin e Vss
;#define    GPIO,GP3  ;
;
;####################################################################
; Definizione del processore
 #ifdef __10F200
   LIST p=10F200 , r=DEC
   #include <p10F200.inc>
 #endif
 #ifdef __10F202
   LIST p=10F202 , r=DEC
   #include <p10F202.inc>
 #endif
 #ifdef __10F204
   LIST p=10F204 , r=DEC
   #include <p10F204.inc>
#define proccomp
 #endif
 #ifdef __10F206
   LIST p=10F206 , r=DEC
   #include <p10F206.inc>
#define proccomp
 #endif

;####################################################################
; CONFIGURAZIONE
;
; WDT, no CP, pin4=GP3;
  __config _CP_OFF & _MCLRE_OFF & _WDT_ON
 
;####################################################################
; RAM
    CBLOCK 0x10
    d1,d2,d3      ; counter per temporizzazione
    ENDC

step EQU .10      ; ripetizioni lampeggio

;####################################################################
; RESET ENTRY
;
; Reset Vector
RESET_VECTOR ORG 0x00

       clrwdt

; calibrazione oscillatore interno
       andlw 0xFE
       movwf OSCCAL

; disabilita T0CKI per avere GP2 libero
; prescaler 1:128 al WDT
; Portare il prescaler a 1:64 se si vuole una cadenza di
; lampeggio di 1,2s circa
; OPTION def  '11111111'
;              1------- GPWU disabilitato
;              -1------ GPPU disabilitato
;              --0----- clock interno (no T0CKI)
;              ---1---- done
;              ----1--- prescaler al WDT
;              -----111 1:128 2.4s circa
       movlw b'11011111'
       OPTION

 #ifdef proccomp        ; solo per 10F204/6
; disabilita comparatore
       movlw b'11110111'
       movwf CMCON0
 #endif

; GP2 out
       movlw  b'11111011'
       tris   GPIO

; Fase on del LED.
; Crea una serie di impulsi da 1ms nella fase on del LED.
; Il tempo complessivo degli impulsi deve essere
; < del tempo di wdt
       movlw  step      ; numero impulsi
       movwf  d3
ll     bsf    LED
       call   Delay1ms
       bcf    LED
       call   Delay1ms
       decfsz d3
        goto  ll

; eventuale reinizializzazione del WDT
      ;clrwdt
      ;nop
      ;nop
   
       sleep            ; fine fase on - vai in sleep

; subroutines
Delay1ms
       movlw  0xC6
       movwf  d1
       movlw  0x01
       movwf  d2
Delay1ms_0
       decfsz d1, f
        goto  $+2
       decfsz d2, f
        goto  Delay1ms_0
       goto   $+1
       nop
       retlw  0

;********************************************************************
;                              THE END
    END

 


 


 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 25/03/15.