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:
- il microcontroller
- un condensatore sull' alimentazione (100nF)
- il LED
- la resistenza di limitazione della corrente
- 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
|
|