Arduino e carica/scarica condensatore

Transcript

Arduino e carica/scarica condensatore
Arduino e carica/scarica condensatore
[email protected]; http://www.df.unipi.it/∼fuso/dida
(Dated: version 4 - Lara Palla e Francesco Fuso, 26 febbraio 2015)
Queste nota ha un duplice scopo: in primo luogo essa descrive l'esperienza di misura del tempo
caratteristico di carica e scarica in un circuito RC fatta con Arduino. Inoltre essa intende presentare alcune generalità sulle modalità di impiego di Arduino tenendo conto di obiettivi, esigenze e
limitazioni tipiche per le esperienze di laboratorio, con riferimento in particolare alla registrazione
di fenomeni transienti, cioè segnali dipendenti dal tempo.
I. INTRODUZIONE
processo (dipende per esempio dal tempo di risposta dell'operatore, cioè dalla sincronia tra l'attivazione di uno
La semplicità concettuale dell'esperienza di carica e
scarica in un circuito RC permette di concentrarsi sulla discussione delle modalità di impiego della scheda
Arduino in misure di laboratorio, in cui essa serve sostanzialmente per acquisire dei dati, cioè dei segnali
(d.d.p.) dipendenti dal tempo, nell'ambito di un processo
automatizzato.
Nell'esperienza si vuole registrare l'andamento temporale della d.d.p.
ai capi di un condensatore che viene
caricato e scaricato attraverso un resistore esterno, di
resistenza
R
conosciuta.
L'andamento atteso segue le
leggi, ben note e semplicissime da determinare,
V0 (1 − exp(−t/τ ))
e
V (t) = V0 exp(−t/τ )
V (t) =
per le fasi ri-
spettivamente di carica e scarica (nelle equazioni abbiamo posto
τ = RC ,
abbiamo indicato con
con
V0
C
capacità del condensatore,
la d.d.p. fornita dal generato-
re che esegue la carica, e abbiamo supposto che l'istante
iniziale fosse
t=0
per entrambi le fasi).
Concettualmente, un'esperienza del genere può essere
interpretata come una forma di misura di
C
a partire
da quella, tipicamente compiuta con buona accuratezza
attraverso un multimetro, di
no altri modi per determinare
switch e di un cronometro). Alternativamente, nel regime opposto di
τ
sucientemente breve (per esempio mil-
lisecondi, o anche meno), è possibile simulare il processo
di carica e scarica del condensatore usando l'onda quadra prodotta dal generatore di funzioni e determinando il
valore di
τ
direttamente da un'osservazione all'oscillosco-
pio. Questo è quello che si è in pratica realizzato (anche
se misure speciche non sono state fatte) nell'esperienza
della pinna di squalo, cioè dell'integratore RC alimentato con un'onda quadra. Anche in questo caso i limiti
dell'approccio in termini di accuratezza sono evidenti.
L'uso di Arduino consente invece di registrare per punti e
in modo automatico le curve V (t) di carica e scarica.
Anche qui esistono delle limitazioni, legate fondamentalmente alla relativa lentezza di operazione di Arduino, cioè
al suo rate di campionamento limitato (dell'ordine della
decina di kHz), che impedisce la registrazione di fenomeni che avvengano con un tempo caratteristico troppo
breve: come chiariremo nel seguito, nella congurazione
impiegata i risultati migliori si ottengono per
τ ∼ 5 − 50
R e C.
ms, ottenibili con opportune scelte dei valori di
R. Naturalmente esistoC , per esempio attraverso
II. CONFIGURAZIONE DI MISURA
l'acquisizione della curva di risposta del ltro RC corrispondente (passa-basso o passa-alto), oppure la misura
dell'impedenza (modulo e sfasamento) in funzione della
La congurazione concettuale di misura è rappresenta-
frequenza, o ancora tramite confronto con una capaci-
ta in Fig. 1(a): a un dato istante lo switch viene commu-
tà di riferimento in un ponte di de Sauty.
tato sulla posizione 1 e il condensatore
Tuttavia la
C,
che supponia-
registrazione diretta delle curve di carica e scarica è si-
mo precedentemente scarico, viene caricato dal generato-
curamente interessante, dato che rappresenta l'evidenza
re attraverso la resistenza
sperimentale della soluzione di una classe di famose equa-
suoi capi cresce esponenzialmente nel tempo, secondo
zioni dierenziali, e fa sempre piacere vericare quanto le
la funzione
previsioni matematiche siano ben riprodotte dalla realtà
un valore asintotico pari a
sperimentale.
il commutatore passa sulla posizione 2 e il condensato-
L'andamento temporale del segnale
V (t) può in genera-
le essere determinato sperimentalmente in vari modi. Per
esempio, nel caso
τ
sia sucientemente lungo (decine di
R;
di conseguenza, la d.d.p. ai
V (t) = V0 (1 − exp(−t/τ )), no a giungere a
V0 . A un altro dato istante,
re, caricato nella fase precedente, si scarica attraverso la
resistenza
R;
di conseguenza, la d.d.p. ai suoi capi dimi-
nuisce esponenzialmente nel tempo, secondo la funzione
secondi) da consentire una misura a occhio, come si può
V (t) = V0 exp(−t/τ ),
fare in laboratorio in un'esperienza parallela, è possibile
zero.
no a giungere asintoticamente a
costruire a mano una tabella usando il tester analogico,
Come sapete, Arduino può fare un sacco di cose (più o
che ha una prontezza adeguata per questi scopi, e un cro-
meno bene). Sicuramente esso è in grado di eseguire delle
nometro. È chiaro il carattere artigianale di un simile
misure di d.d.p. intervallate nel tempo e di registrarne il
approccio, che comporta signicative barre d'errore so-
valore e, altrettanto sicuramente, esso è in grado di pro-
prattutto per la determinazione dell'istante iniziale del
durre una d.d.p. costante a partire da un dato istante,
2
e spegnerla a un altro dato istante. Per la misura della
resistenza interna è stata rappresentata nello schema),
d.d.p. deve essere usata una
mentre nella realtà il generatore costituito dalla porta
porta analogica,
conguradeve
digitale di Arduino ha una resistenza interna non ne-
(in grado di fornire una
cessariamente trascurabile. Questa potrebbe far aumen-
d.d.p. nulla o pari a un certo valore, su cui poi discute-
tare la costante tempo caratteristica, che diventerebbe
remo), congurata come uscita. La Fig. 1(b) mostra lo
τ = (rhigh + R)C ,
schema di massima delle connessioni da realizzare con la
parte, nella fase di scarica vorremmo che la serie RC fos-
scheda Arduino: la porta indicata con
ta come ingresso; per la generazione della d.d.p.
essere usata una
porta digitale
A0
con
rhigh
resistenza interna. D'altra
(boccola blu)
se una maglia, come si realizza commutando lo switch di
è l'ingresso analogico prescelto per l'esperienza, la porta
Fig. 1(a) nella posizione 2. Invece tutto quello che pos-
indicata con
siamo fare con Arduino è di porre l'uscita digitale
per
zero. In elettronica, avere un potenziale nullo non impli-
7 (boccola rossa) è l'uscita digitale prescelta
l'esperienza, GND (boccola nera) indica la connessio-
7
a
ne di massa, che è ovviamente necessario eettuare per
ca necessariamente un collegamento reale (sico) con
riferire i potenziali in modo corretto allo stesso zero, cioè
la linea di massa. In altre parole, tra l'uscita digitale
alla stessa linea di massa.
posta a potenziale nullo e la massa potrebbe trovarsi una
Nell'esperienza pratica si farà in modo, secondo quanto descritto nel seguito, di accendere a un dato istante
l'uscita digitale e, contemporaneamente (vedi dopo per il
signicato da dare a questo avverbio), di avviare l'acquisizione temporizzata (a intervalli regolari
∆t
- di nuovo
vedi dopo per ulteriori chiarimenti) della d.d.p. sull'ingresso analogico.
Quindi, trascorso un certo tempo, si
farà in modo di spegnere la porta digitale, e si ricomincerà l'acquisizione temporizzata sull'ingresso analogico per
seguire la fase di scarica.
resistenza interna
sa da
rhigh .
7
rlow incognita e presumibilmente diver-
Potremo vericare a posteriori se e quanto
queste resistenze interne giocano un ruolo, estraendo tramite best-t i tempi caratteristici
τ
di carica e scarica e
confrontandoli tra loro.
Inoltre è evidente che la resistenza interna
rint
della
porta analogica di Arduino potrebbe anche inuenzare
i risultati:
infatti il suo carico si trova in parallelo al
condensatore
C,
e dunque alla resistenza
R
(supponendo
trascurabili le resistenze interne della porta digitale). La
resistenza di ingresso delle porte analogiche non è nota
Prima di procedere, è bene sottolineare da subito un
con precisione:
tuttavia, vista la tecnologia impiegata,
paio di dierenze tra quanto ci proponiamo di fare e
essa è attesa essere molto elevata (oltre 1 Mohm), quindi
quanto, invece, è schematizzato nell'esperimento concet-
tale da produrre eetti trascurabili. In questo caso, una
tuale [Fig. 1(a)]:
prova sperimentale indiretta sarà trovata nella prossima
concettualmente abbiamo implicita-
mente supposto di avere un generatore ideale (nessuna
III. FILOSOFIA DI OPERAZIONE DEGLI
ESPERIMENTI CON ARDUINO
esperienza.
un ambiente interattivo (detto IDE) specico, cioè un
programma che si chiama, generalmente, Arduino, Arduino IDE, o Arduino Programming, e che è rilasciato
Discutiamo ora alcuni aspetti molto generali che vanno
presi in considerazione nel progettare e realizzare esperienze con Arduino. Partiamo con il ricordare che il cuore di Arduino è un microcontroller (modello ATmega328
per la scheda Arduino UNO), dotato, tra le altre funzioni,
di digitalizzatori che possono campionare segnali (d.d.p.)
analogici e convertirli in interi con una dinamica di 10
bit, corrispondenti a
210 = 1024
livelli distinti. Salvo le
ulteriori precisazioni che discuteremo in seguito, questi
livelli corrispondono all'intervallo di d.d.p. tra zero e un
valore massimo, o di riferimento, tipicamente
Vref ' 5 V
(per le nostre esperienze).
Concettualmente il microcontroller riproduce, in forma ridotta e parziale, il processore (CPU) di un qualsiasi
computer e quindi come questo ha bisogno in primo luogo di essere istruito sulle operazioni che vogliamo che
compia. In un normale computer questo è, grosso modo
e senza entrare nei dettagli, quanto viene eseguito dalla
combinazione di programma e sistema operativo.
Con Arduino le istruzioni possono essere date scrivendo un semplice programmino, detto
sketch, all'interno di
per tutti i principali sistemi operativi. Questo ambiente
interattivo è presente nei computer del laboratorio. Lo
sketch, che è composto di parti distinte, tutte funzionali e necessarie, è scritto con una sintassi che ricorda
molto da vicino quella del linguaggio C (più precisamente si tratta di una sorta di sotto-insieme del C, implementato nel sotto-insieme di un ambiente/linguaggio che
si chiama Processing).
Naturalmente lo sketch contie-
ne delle istruzioni speciche per controllare Arduino, per
esempio quelle che stabiliscono se le varie porte devono
essere considerate come ingressi e uscite, quelle che eseguono la lettura di una porta analogica o la scrittura
(determinazione di stato alto o basso) per una porta digitale. Fortunatamente, la sintassi di queste istruzioni è
abbastanza ben comprensibile e in molti casi addirittura
auto-esplicativa.
Il programma Arduino IDE presente sul computer
provvede, una volta terminata la redazione ed eseguiti
con successo alcuni test preliminari sulla sintassi, a fare
l'upload, cioè trasferire con un apposito comando (una
freccina) il contenuto dello sketch, debitamente compila-
3
Figura 1. Schema concettuale dell'esperienza (a) e sua realizzazione con Arduino (b). Nel pannello (b) è rappresentata una
visione molto schematica e non in scala della scheda Arduino UNO rev. 3 SMD edition usata nell'esperienza. Ci sono cinque
collegamenti a altrettanti pin della scheda che terminano con boccole volanti di diverso colore, secondo quanto indicato in
gura: solo tre boccole devono essere collegate (NC signica non collegato).
to, in una memoria non volatile (ash) di cui è dotato
Questo può essere fatto via hardware, per esempio usan-
il microcontroller. Il trasferimento avviene sfruttando la
do un pulsante opportunamente collegato alle porte di-
comunicazione seriale USB tra computer e scheda Ardui-
gitali della scheda.
no. Purtroppo le dimensioni della memoria non volatile
cui stiamo trattando, il controllo può essere eseguito via
sono piccoline (32 kB), per cui lo sketch deve necessa-
software.
riamente essere semplice e breve.
Una volta trasferito
lo sketch compilato, le istruzioni diventano
residenti
Oppure, come per l'esperienza di
A questo scopo si utilizza ancora la comunicazione se-
nel
riale USB, però, per praticità, in questo caso facciamo
microcontroller, che dunque le eseguirà nché non ver-
uso di un semplice script di Python. Infatti Python, co-
rà in qualche modo resettato, per esempio sovrascriven-
me tantissimi altri linguaggi o ambienti, ha la possibilità
do lo sketch con uno nuovo. Normalmente nella fase di
di inviare e ricevere istruzioni via porta seriale. Il van-
trasferimento del programma dal computer ad Arduino
taggio pratico è quello di integrare in un unico script la
alcuni led presenti sulla scheda si accendono e si spengo-
funzione di controllo (in seguito vedremo che c'è anche
no a mostrare che c'è una comunicazione in corso con il
un'altra piccola utile funzione) con quella di lettura dei
computer.
dati.
In genere è consigliabile avere una qualche forma di
Infatti lo scopo dell'esperienza è quello di registrare il
controllo sulla partenza delle operazioni compiute da Ar-
valore di una d.d.p. che varia nel tempo. Questa registra-
duino (per esempio, nel nostro caso, l'accensione della
zione avviene all'interno dello stesso microcontroller, che
porta digitale che provvede a caricare il condensatore).
per questo sfrutta una piccolissima sezione di memoria (2
4
kB, di tipo SRAM). Se i dati rimanessero in questa memoria non sapremmo cosa farcene: l'esperienza prevede
infatti di analizzarli, cioè di farci un best-t e di trarre
qualche conclusione sica.
È quindi necessario che essi
vengano trasferiti dalla scheda di Arduino al computer.
Questo trasferimento dati, che dà luogo alla scrittura di
les sul disco rigido del computer, avviene appunto grazie
allo script di Python.
Il diagramma logico che sta alla base dell'impiego di
Arduino nelle nostre esperienze è quello mostrato molto
schematicamente in Fig. 2:
1. si scrive uno sketch nell'ambiente Arduino (IDE,
o Programming) che contiene, in un formato opportuno e con una sintassi simil-C, le istruzioni da
impartire al microcontroller (naturalmente questo
sketch lo troverete già presente nei computer di laboratorio, ma potrete eventualmente modicarlo e
migliorarlo);
Figura 2. Diagramma logico di massima di una tipica
esperienza con uso di Arduino.
2. lo sketch viene trasferito (upload) a Arduino tramite comunicazione seriale USB e caricato nella
memoria del microcontroller (una sola volta);
3. si scrive uno script di Python che serve per controllare la partenza delle operazioni compiute da
Arduino e per permettere il trasferimento e la lettura dei dati acquisiti (anche in questo caso lo
script lo troverete già nei computer, e siete liberi
di migliorarlo);
simbolo B, è una sequenza di 8 bits: poiché
28 = 256,
un
byte permette di specicare un valore intero compreso
tra 0 e 255.
Per ragioni storiche, qualche volta si dà a
un singolo byte il nome di
parola digitale,
che, secondo
le regole, dovrebbe essere invece attribuito a una sequenza di (almeno) 2 bytes. Altrettanto per ragioni storiche,
a un singolo byte si dà spesso il nome di
carattere:
il
motivo è che esiste tuttora una vecchia convenzione, che
4. si lancia lo script di Python, naturalmente dopo
risale ai tempi delle telescriventi (servivano per i telex,
aver collegato in modo corretto i componenti ne-
ovvero telegrammi), in cui un gruppo di 256 caratteri,
cessari per l'esperienza, si aspetta un po' e, quando
comprendenti lettere dell'alfabeto esteso, numeri da 0 a
segnalato dalla console di Python, si sa che i dati
9, caratteri speciali e marzianetti vari, era codicato ap-
sono stati registrati su un le;
punto in valori numerici interi compresi tra 0 e 255. Il
5. il le è allora pronto per essere riaperto con un altro
script di Python da fare ex-novo, che permetterà
l'analisi dei dati (graci, t, etc.); tutta l'operazione di misura può essere eseguita più volte, per
esempio per vericare la presenza di uttuazioni o
per testare il comportamento con altre scelte dei
parametri del circuito (valori di
R
e
C ).
codice di riferimento si chiama
codice ASCII
e lo potete
facilmente trovare in rete.
Vale la pena di sottolineare che, in tempi di globalizzazione, fare riferimento a un codice in grado di identicare
i soli caratteri alfabetici latini, e poco più, si è reso presto insuciente.
Sono quindi state sviluppate ulteriori
codiche, tra cui quella denominata
unicode, che inizial-
mente si basava su parole di 2 byte, ovvero 16 bits, e
che ora è estesa, potenzialmente, su ben 21 bits.
IV. BIT, BYTE, PAROLE E CARATTERI
Que-
sta precisazione è funzionale ai nostri scopi considerando
che la versione attuale di Python (la 3.x) tratta caratteri unicode, mentre la precedente (la 2.x, che è anche
Questa breve sezione è dedicata a chiarire un po' di
quella installata nei computer di laboratorio), era basa-
nomenclatura di cui faremo brevemente uso nei commen-
ta su caratteri ASCII. Questa circostanza comporta dei
ti allo sketch e allo script.
L'argomento di riferimento,
dettagli di sintassi che saranno evidenziati nel seguito (in
quello delle grandezze numeriche nella programmazione,
ogni caso le istruzioni relative di Python 3.x dovrebbero
è molto complesso e non sempre (quasi mai) ben denito,
essere compatibili con tutte le versioni in uso comune di
per cui sicuramente non è questa la sede per arontar-
Python 2.x).
lo compiutamente. Ci limiteremo a dare alcune (poche)
La comunicazione seriale usata per parlare con Ar-
informazioni strettamente utili, anche se talvolta incom-
duino sfrutta, normalmente, proprio dei bytes, nel senso
plete e non del tutto corrette, per capire qualche dettaglio
che bytes vengono inviati e ricevuti tramite porta seriale
delle istruzioni usate.
USB. La natura seriale di questo protocollo di comuni-
bit è un numero che può asUn byte, indicato spesso con il
Tutti sappiamo che un
sumere i valori 0 o 1.
cazione implica che i bytes, ovvero i caratteri, vengano
inviati e ricevuti uno alla volta.
In altre parole, non è
5
possibile inviare via porta seriale un valore numerico arbi-
in cui si riconosce bene la concatenazione attraverso il
trariamente grande, o una parola composta di un numero
punto in uso con Python) un carattere di tipo ASCII (il
qualsiasi di caratteri, in un colpo solo.
Questo aspetto
non è rilevante per l'upload dello sketch, che è gestito
b
da Arduino IDE, ma può essere importante quando si
progetta lo script di Python.
dell'istruzione, che a rigore non serve usando Python
2.x) costituito dal carattere '5'.
Come sarà discusso in seguito, l'invio di questo carattere ha la duplice funzione di far partire l'acquisizione
da parte di Arduino e di indicargli quanto deve valere
l'intervallo temporale
V. LO SCRIPT DI PYTHON
nominale ∆t
tra una presa dati e
la successiva. L'unità di misura è 100
µs,
per cui il '5'
signica che i dati saranno campionati con intervalli di
Anche se la logica suggerirebbe di partire dalle istruzioni dello sketch di Arduino, iniziamo con il commento
allo script di Python.
circa 5 × 100 µs = 500 µs.
sperimentali, cioè, per esempio, della scelta di
Lo script richiede di importare due pacchetti che nora
non abbiamo mai usato: il pacchetto
serial,
che serve
per gestire (al meglio) la comunicazione seriale USB, e
il pacchetto
time,
che permette di eseguire dei cicli di
attesa con un tempo controllato. Nello script compaiono
infatti delle istruzioni del tipo
time.sleep(2) che produ-
cono un'attesa di 2 s (il valore può essere ovviamente modicato, l'unità di misura è secondi), precauzionalmente
necessaria per evitare di avere problemi di intasamento
della comunicazione seriale.
Dopo aver inizializzato la porta seriale, cioè attribuito alla variabile
ard
Il valore riportato nello script
può, e deve, essere aggiustato sulla base delle esigenze
un valore identicativo della porta
USB a cui la scheda Arduino è collegata (la sintassi è
peculiare e dipendente dal sistema operativo) e specicato che la comunicazione avverrà alla velocità di 9600
Baud (nella comunicazione usata, un Baud dovrebbe cor-
Quindi lo script crea due nomi per due
R
e
distinti
C.
les,
contenenti rispettivamente i dati relativi alla carica (il
_C.txt) e alla scarica (il nome
_S.txt) del condensatore. Ognuno
nome del le termina con
del le termina con
dei les è composto da 200
punti sperimentali,
coppie di valori, nell'ordine tempo, espresso in
letta dalla porta analogica
A0,
ovvero
µs, e d.d.p.
espressa in unità intere di
digitalizzazione.
Lo
la
script
porta
prevede
allora
seriale:
un
ciclo
l'istruzione
ard.readline().decode(),
dove
di
lettura
del-
corrispondente
l'ultima
è
specica
è sempre legata alla necessità di convertire la lettura
in caratteri (il
.decode()
in Python 2.x).
dovrebbe essere superuo
Le prime 200 coppie di dati vengono
registrate in un le, le altre 200 nell'altro.
rispondere a 1 B/s), non molto elevata ma sicuramente
Inne, dopo le opportune operazioni di chiusura dei
adeguata agli scopi, lo script scrive sulla porta seriale un
les e della porta seriale, lo script segnala di essere
determinato valore.
terminato scrivendo
esempio,
L'istruzione corrispondente è, per
ard.write(b'5')
seriale corrispondente alla variabile
ard
(sarebbe il no-
stro Arduino) viene inviato in scrittura (.write, sintassi
end
sulla console (terminale).
Lo script, debitamente commentato, è riportato qui
che signica che alla porta
di
seguito;
esso
si
trova
caricascarica_v1.py.
in
rete
sotto
il
nome
import serial # libreria per gestione porta seriale (USB)
import time # libreria per temporizzazione
print(' opening serial port ')
ard=serial.Serial('/dev/ttyACM0',9600) # apre porta seriale (occhio alla sintassi, dipende
# dal sistema operativo!)
time.sleep(2) # aspetta due secondi per evitare casini
print(' start ')
ard.write(b'5') # scrive il carattere per l'intervallo di campionamento
# in unita' di 100 us <<<< DA CAMBIARE A SECONDA DEI GUSTI
# l'istruzione b indica che e' un byte (carattere ASCII)
time.sleep(2) # aspetta due secondi per evitare casini
print(' reading data ')
Directory='../dati_arduino/'
# nome directory dat # << DA CAMBIARE SECONDO NECESSITA'
FileName='pippo' # parte comune nome file << DA CAMBIARE SECONDO NECESSITA'
FileNameC=(Directory+FileName+'_C.txt') # crea nome file dati carica
FileNameS=(Directory+FileName+'_S.txt') # crea nome file dati scarica
di
6
outputFileC = open(FileNameC, "w" ) # apre file dati carica per scrittura
outputFileS = open(FileNameS, "w" ) # apre file dati scarica per scrittura
# loop lettura dati da seriale (400, di cui 200 per carica e 200 per scarica)
for i in range (0,400):
data = ard.readline().decode() # legge il dato e lo decodifica
if data:
if i<200:
outputFileC.write(data) # scrive i primi 200 in file di carica
else:
outputFileS.write(data) # scrive i secondi 200 in file di scarica
outputFileC.close() # chiude il file dei dati di carica
outputFileS.close() # chiude il file dei dati di scarica
ard.close() # chiude la comunicazione seriale con Arduino
print('end') # scrive sulla console che ha finito
VI. LO SKETCH DI ARDUINO
o array (vettori), intere (segnate o meno, eventualmente
lunghe) o reali (eventualmente a doppia precisione).
Lo sketch di Arduino è scritto in un linguaggio che
somiglia molto al C. In questo linguaggio si fa uso molto
spesso di pseudo-funzioni, cioè gruppi di istruzioni che
non restituiscono un valore numerico. A queste funzioni
si fa riferimento con l'istruzione
void { }
(le parentesi
grae comprendono le istruzioni associate alla pseudofunzione). Notate che tutte le singole istruzioni contenute
tra le parentesi grae devono necessariamente terminare
con un punto e virgola.
Nei casi semplici, a cui fortunatamente appartiene il
nostro sketch, Arduino richiede che lo sketch stesso sia
suddiviso in diverse parti.
Il nostro sketch è di fat-
to suddiviso in tre sezioni: (i) denizione delle variabili; (ii) inizializzazione del microcontroller; (iii) istruzioni
necessarie per le speciche operazioni previste.
Vediamo e commentiamo brevemente il contenuto di
queste tre parti.
A seconda della tipologia di denizione, cambia la
quantità di memoria allocata per la variabile. Vista l'eseguità dello spazio di memoria disponibile nel microcontroller, è sempre consigliabile denire le variabili per quello che eettivamente serve. Per esempio, un intero standard (int o
unsigned int,
a seconda che debba o non
debba assumere valori negativi) occupa 2 bytes, cioè due
caratteri, e permette quindi di individuare
valori interi dierenti; un intero
long
28+8 = 216
richiede invece 4
bytes. Anche se non espressamente indispensabile nella
maggior parte dei casi, la variabile
StartTime, che, come
vedremo, riporta una misura di tempo rispetto all'istante in cui Arduino è stato acceso (ovvero il programma è
stato lanciato la prima volta) è denita come
ché tale misura è in
µs,
e il
long.
Poi-
numero di µs può facilmente
diventare molto grande, occorre usare una variabile in
grado di supportare correttamente i grandi numeri interi. Inoltre, dato che gli elementi dell'array
t risultano da
operazioni matematiche con quella variabile, anche essi
devono essere di tipo
A. Denizione delle variabili
long.
Il resto di questa sezione dello sketch, che è riportata
qui nel seguito, è piuttosto auto-esplicativa: notate che
La denizione delle variabili è necessaria (in C, non in
analogPin e chargePin sono le variabili che contengono i
Python, come sapete) anché esse possano essere corret-
numeri (puntatori) delle porte impiegate rispettivamente
tamente interpretate nel programma. Si possono denire
per la lettura (analogica) e per la carica, cioè le porte
delle variabili vere e proprie, oppure delle
e
costanti,
cioè
7
della scheda.
ag:
Inne la variabile intera
start
A0
serve
delle grandezze che non verranno mai modicate dal pro-
come
gramma. A seconda di quello che devono rappresentare,
a partire quando questa variabile diventerà diversa da
nel seguito dello sketch ci sarà un ciclo pronto
esse saranno identicate come variabili secche (scalari)
zero.
// Blocco definizioni
const unsigned int analogPin=0; // Definisice la porta A0 per la lettura
const unsigned int chargePin=7; // Definisce la porta 7 per la carica
int i; // Definisice la variabile intera i (contatore)
int delays; // Definisce la variabile intera delays
7
int V[200]; // Definisce l'array intero V
long t[200]; // Definisice l'array t
unsigned long StartTime; // Definisce il valore StartTime
int start=0; // Definisce il valore start (flag)
B. Inizializzazione
buer (Serial.flush();, di denire di uscita la porta
indicata dalla variabile
Le istruzioni di inizializzazione di Arduino devono essere incluse nella pseudo-funzione chiamata
Pertanto esse iniziano con
void setup()
setup().
e le istruzioni
L'inizializzazione
preparandola
richiede
a
(Serial.begin(9600);),
di
aprire
la
funzionare
a
di
per
pulirne
e di porla a livello
Notate che non è necessario
denire la porta analogica come input, che è di fatto
l'unica
possibilità
(essa
non
può
agire
da
output).
Inoltre sono presenti delle istruzioni, sul cui signicato
relative sono contenute tra parentesi grae.
riale
chargePin
basso (potenziale nullo).
porta
9600
se-
Baud
sicurezza
il
non entriamo nei dettagli, che aiutano a ottimizzare i
tempi di campionamento della scheda.
La parte di sketch è la seguente:
// Istruzioni di inizializzazione
void setup()
{
Serial.begin(9600); // Inizializza la porta seriale a 9600 baud
Serial.flush(); // Pulisce il buffer della porta seriale
pinMode(chargePin,OUTPUT); // Definisce ChargePin come output
digitalWrite(chargePin,LOW); // e lo pone a valore low
bitClear(ADCSRA,ADPS0); // Istruzioni necessarie per velocizzare
bitClear(ADCSRA,ADPS2); // il rate di acquisizione analogica
}
C. Il loop
sono codicati ASCII in ordine nell'intervallo compreso
tra il decimale 48, corrispondente al carattere
Le istruzioni vere e proprie del programma sono inserite in una pseudo-funzione che prevede un ciclo ed è
pertanto denominata
void loop().
Questo ciclo inizia con un'istruzione di monitoraggio
della porta seriale, necessario perché, dopo aver caricato
lo sketch nel microcontroller, esso aspetta di ricevere via
seriale USB l'istruzione prodotta dallo script di Python
prima di partire con le operazioni vere e proprie.
Serial.available(),
57, corrispondente al carattere
'9'.
'0',
e il
Di conseguenza la
decodica, per esempio, del carattere '5' dà luogo al numero intero 53. Dunque sottrarre lo '0 ', che è codicato
con il decimale 48, come fatto nello sketch, consente di
ricavare il numero originario (53
− 48 = 5),
che poi va,
come detto, moltiplicato per 100.
Di seguito, dopo aver svuotato il buer della porta se-
Al-
riale, la variabile
start
viene posta a 1 e l'acquisizione
che
comincia. Per garantirsi ragionevolmente che il conden-
restituisce un valore diverso da zero quando qualcosa si
satore sia inizialmente scarico, si esegue un ciclo di attesa
viene a trovare sulla porta seriale.
di 2 s attraverso il comando
lo scopo provvede il comando
Il qualcosa in questione è il singolo carattere (byte)
inviato dallo script di Python. Ricordiamo che esso contiene, in origine, un numero intero che, moltiplicato per
approssimativo in µs tra due istanti
campionamento. Il numero di µs di que-
100, dà l'intervallo
successivi di
sto intervallo è contenuto nella variabile
delays
che è
costruita dalla lettura della porta seriale sfruttando un
trucchettino. Infatti quello che originariamente, nelle nostre intenzioni, era un numero intero, è stato necessa-
delay(2000) (l'unità di mi-
sura è qui ms). Quindi la porta indicata dalla variabile
chargePin (la 7 nel nostro esempio) viene posta a livello
alto, cioè a un potenziale positivo che corrisponde al massimo che può essere fornito e la variabile
StartTime viene
posta pari alla lettura dell'orologio interno di Arduino,
eseguita con il comando
micros().
In questo modo, i
tempi in cui verranno acquisiti i punti sperimentali sono
nominalmente riferiti all'istante iniziale, quello in cui la
porta digitale è stata commutata al suo livello alto.
riamente convertito in un byte, ovvero in un carattere
A questo punto dovrebbe iniziare il ciclo di campio-
ASCII, prima di essere inviato attraverso porta seriale
namento nella fase di carica. Tuttavia, per evitare pro-
dal computer a Arduino.
Per essere riconvertito in in-
blemi, è bene inizialmente eseguire un ciclo singolo di
tero esso deve essere decodicato, operazione che viene
lettura della porta analogica. Il motivo principale è che,
eettuata con l'istruzione
nell'istante in cui la porta digitale viene posta a livello
Serial.read.
I numeri interi
8
alto, si crea un impulso che passa rapidamente da zero al
facilmente essere letti da Python. I dati sono organizzati
valore massimo di d.d.p., circa 5 V. Questo impulso può
in righe che riportano, nell'ordine, la variabile tempo, un
perturbare il microcontroller; per esempio, esso può pro-
po' di spazi vuoti come separatore, e la variabile corri-
durre una lettura iniziale erronea della porta analogica
spondente alla lettura della d.d.p. (al termine di questa
dovuta all'accumulo di carica elettrica spuria sulla porta
si va a capo per iniziare una nuova riga).
stessa.
Il ciclo risolve il problema, scaricando la por-
ta attraverso la singola lettura iniziale, che, ovviamente,
non viene registrata essendo, appunto, erronea.
Comincia quindi il ciclo dedicato al campionamento dei valori (200 punti sperimentali) relativi alla fase di carica,
che vanno a popolare gli array
V
e
t.
Fra un passo del ciclo e il successivo, si impone un'attesa
pari,
nominalmente,
mento prescelto;
all'intervallo
di
campiona-
questo è realizzato con il comando
delayMicroseconds(delays);.
Terminata l'acquisizione dei 200 punti sperimentali re-
Quindi, dopo un'attesa ssata in 1 s nel quale, presumibilmente, il processo di carica si completa praticamente, se questo non è già avvenuto (dipende, ovviamente,
da
R e C scelti), la porta digitale indicata dalla variachargePin (la 7 nel nostro esempio) passa a livel-
bile
lo basso, cioè a potenziale nullo rispetto a massa entro
l'errore, e, dopo una singola lettura della porta analogica utile per evitare registrazioni erronee, ricominciano i
cicli, destinati stavolta a raccogliere i dati relativi alla
scarica.
lativi alla carica comincia il ciclo di scrittura dei dati
La corrispondente sezione di sketch è riportata nel
sulla porta seriale. Il modo con cui essi sono scritti non è
seguito (l'intero sketch si trova in rete sotto il nome
molto elegante, ma garantisce di avere dati che possono
carich.ino):
// Istruzioni del programma
void loop()
{
if (Serial.available() >0) // Controlla se il buffer seriale ha qualcosa
{
delays = (Serial.read()-'0')*100; // Legge il byte e lo interpreta come ritardo
Serial.flush(); // Svuota la seriale
start=1; // Pone il flag start a uno
}
if(!start) return // Se il flag è start=0 non esegue le operazioni qui di seguito
// altrimenti le fa partire (quindi aspetta di ricevere l'istruzione
// di partenza
delay(2000); // Aspetta 2000 ms per permettere di partire con condensatore scarico
digitalWrite(chargePin,HIGH); // Pone chargePin a livello alto per la carica
StartTime=micros(); // Misura il tempo iniziale con l'orologio interno
for(i=0;i<1;i++) // Fa un ciclo di una sola lettura per "scaricare" l'analogPin
{
V[i]=analogRead(analogPin);
}
for(i=0;i<200;i++) // Loop per la carica
{
t[i]=micros()-StartTime; // Legge il timestamp e lo mette in array t
V[i]=analogRead(analogPin); // Legge analogPin e lo mette in array V
delayMicroseconds(delays); // Aspetta tot us
}
for(i=0;i<200;i++) // Loop per la scrittura su porta seriale
{
Serial.print(t[i]); // Scrive t[i]
Serial.print(" "); // Mette uno spazio
Serial.println(V[i]); // Scrive V[i] e va a capo
}
delay(1000); // Aspetta 1000 ms per completare la carica
digitalWrite(chargePin,LOW); // Pone chargePin a livello basso per la scarica
StartTime=micros(); // Misura il nuovo tempo iniziale
for(i=0;i<1;i++) // Fa un ciclo di una sola lettura per "scaricare" l'analogPin
{
V[i]=analogRead(analogPin);
9
}
}
for(i=0;i<200;i++) // Loop per la scarica
{
t[i]=micros()-StartTime;
V[i]=analogRead(analogPin);
delayMicroseconds(delays);
}
for(i=0;i<200;i++) // Loop per la scrittura su porta seriale
{
Serial.print(t[i]);
Serial.print(" ");
Serial.println(V[i]);
}
start=0; // Annulla il flag
Serial.flush(); // Pulsice il buffer della porta seriale (si sa mai)
VII. DATI ACQUISITI
di computer, ha dei
tempi di latenza, cioè degli interval-
li di tempo indeterminati nei quali, invece di occuparsi
La cinematica dell'operazione dovrebbe ora essere
abbastanza chiara.
Occorre però tornare indietro alla
sica del processo di campionamento e digitalizzazione
per capire bene cosa rappresentano i dati che sono stati scritti nei les nel corso dell'operazione e individuare
l'incertezza da attribuire alle misure.
del programma che deve far girare, fa altro (controlla il
proprio stato di salute, controlla se il campionamento è
terminato, vede se c'è qualcosa di nuovo nella memoria,
verica che non ci siano errori nel proprio calcolo, e chissà quante altre operazioni più o meno nascoste). Notate
anche che il programma prevede che le varie istruzioni siano eseguite
in sequenza:
questo comporta che, per esem-
pio, la lettura dell'orologio per determinare il valore di
t
non possa essere perfettamente contemporanea a quella
A. Misura del tempo
relativa alla lettura di
V (t).
Uno dei principali limiti nell'impiego di Arduino come scheda di acquisizione dati è la scarsa capacità di
denire con precisione i tempi di campionamento.
Ci sono almeno due metodi per attribuire un'incertezza
Si
sensata alle nostre misure, cioè per mettere una ragione-
può intanto denire una sorta di limite fondamentale per
vole barra di errore sulla misura dei tempi. Il primo, più
l'accuratezza sui tempi, legato alla precisione dell'orolo-
corretto dal punto di vista concettuale, prevede di ripe-
gio interno di Arduino.
Questo orologio si basa su un
tere tante volte la stessa misura e di estrarre lo scarto
oscillatore a cristallo di quarzo da 16.000 MHz (nomina-
quadratico medio dalla dispersione dei dati sperimentali.
li), ben visibile sulla scheda, a cui possiamo attribuire
Questo approccio, di fatto, è non semplice da mettere in
un'incertezza statistica pari a un periodo di oscillazione
pratica, a meno di non preparare un bello script di Py-
∆tclock ∼ 1/16
thon che lo esegua in maniera pressoché automatica (e
−1
MHz
' 60
ns. Occorre poi tenere con-
to del tempo minimo necessario per portare a termine
non intendiamo farlo).
l'operazione di campionamento del segnale, che è molto
maggiore rispetto alla durata del singolo ciclo di clock, essendo, secondo le speciche, dell'ordine di qualche decina
di
Il secondo, che è consigliato per la sua semplicità, con-
µs.
siste nel porre una barra di errore secca per tutte le misu-
Queste limitazioni non dovrebbero essere rilevanti nel
re di tempo, corrispondente al valore nominale del cam-
nostro esperimento, visto che l'intervallo di campionamento
∆t
µs.
pionamento (100, 200, 300
µs,
o quello che è stato scel-
impostabile dall'utente è compreso tra 100 e
to). È evidente che stimare l'incertezza con l'intervallo
Tuttavia, come potrete facilmente vedere ispe-
di campionamento costituisce una sovrastima grossolana
zionando il le dei dati sperimentali, la successione degli
dell'eettivo errore con cui si valutano i tempi; tuttavia,
istanti di campionamento non è precisamente equispazia-
questo può essere ritenuto compatibile con le ambizioni
900
t
è non necessariamente
della misura e, inoltre, non rischia di condurre a sotto-
Il motivo può essere compreso molto fa-
stime dell'incertezza dovuta all'eettivo tempo necessa-
cilmente: nello sketch la temporizzazione è data dall'i-
rio ad Arduino per portare a termine un campionamento
struzione
che è inserita
e liberarsi per un successivo campionamento, che, nella
dentro un ciclo di programma. Il programma viene fat-
modalità di misura qui impiegata, è dell'ordine di diverse
to girare dal microcontroller, che, come ogni processore
decine di
ta, cioè l'errore sulla misura di
trascurabile.
delayMicroseconds(delays);
µs.
10
B. Misura della d.d.p.
non dovrebbe entrare nella determinazione di
τ
tramite
best-t.
Anche la misura della d.d.p.
V (t),
eseguita per cam-
pionamento dalla porta analogica di Arduino, merita diversi commenti. Il primo, di carattere più formale che sostanziale, si applica ogni volta che si eseguono misure di
campionamento a istanti diversi, a prescindere dallo strumento hardware utilizzato. Nei graci che rappresentano
i dati sperimentali si fa in genere uso di punti corredati
delle debite barre di errore. A rigore, il graco non dovrebbe essere per punti, ma piuttosto dovrebbe trattarsi
di un
istogramma.
Infatti, a causa del rate nito di cam-
pionamento, il valore campionato non si riferisce a un
Dunque è formalmente corretto presentare i dati di
V (t) in unità arbitrarie di digitalizzazione, pari evidentemente a V0 /1024 (ovvero Vref /1024). Qualora, tuttavia,
voleste esprimere V (t) in unità siche (V), potreste facilmente misurare V0 , per esempio collegando l'oscilloscopio
(ovviamente accoppiato in DC e debitamente congurato
per misure di ampiezza) alla porta digitale 7: quando il
programma viene eseguito, su questa porta si ritrova per
un certo tempo, quello di carica del condensatore, proprio il valore
V0 ,
che l'oscilloscopio permette di leggere
facilmente con la sua incertezza.
preciso istante temporale (con la propria incertezza), ma
Inne anche per le misure di d.d.p. è necessario indi-
all'intervallo di tempo fra due campionamenti successivi.
viduare la barra di errore da attribuire ai dati acqui-
Nella nostra esperienza questo aspetto formale produce
siti.
eetti del tutto trascurabili, data la densità dei punti
co) legato all'eventuale non linearità del digitalizzatore,
sperimentali acquisiti. Tuttavia se ne può facilmente te-
che è attesa essere molto piccola, dunque trascurabile,
nere conto in fase di analisi, cioè nella realizzazione dei
la barra di errore che attribuiamo alle misure è pari a
graci.
un bit di campionamento, cioè a un'unità arbitraria di
Infatti è suciente aggiungere alla misura dei
tempi un valore costante pari a metà dell'intervallo di
Trascurando l'errore (presumibilmente sistemati-
digitalizzazione.
campionamento.
L'altro aspetto molto importante è che i valori acquisiti
per
V (t) sono, come potrete facilmente vericare ispezio-
C. Alcuni problemi (vari ed eventuali)
nando il le di dati (oppure la sintassi dello sketch di
Arduino), dei
numeri interi
rigorosamente compresi tra
Quando si esegue una lettura automatizzata di dati
0 e 1023. Questo discende dalla natura stessa dell'ope-
sperimentali è sempre bene sapere che non si ha mai un
razione di digitalizzazione compiuta dal microcontroller:
controllo completo di quello che sta succedendo. Facendo
infatti l'elemento chiave della digitalizzazione sta nel ri-
una misura manuale, per esempio osservando lo schermo
condurre le misure a delle operazioni di
di un oscilloscopio, ci si può facilmente rendere conto di
conteggio,
il cui
esito è ovviamente un numero intero.
qualcosa che non va. Per esempio, un rumore che com-
È evidente che una lettura pari a 0 indica che la d.d.p.
pare come un impulso (uno
spike,
in gergo), può essere
letta è nulla entro l'incertezza, e una lettura pari a 1023
facilmente rilevato e la misura corrispondente può essere
indica che essa ha raggiunto il massimo livello possibi-
immediatamente scartata.
le entro l'incertezza.
Questo massimo livello possibile
è legato alla tensione di riferimento
Vref
Rumori, soprattutto di tipo impulsivo, o in generale
che nel nostro
ad alta frequenza, sovrapposti al segnale che si vuole
caso è dipendente dalla tensione di alimentazione della
misurare, sono sempre possibili specie quando si impie-
scheda.
gano microcontroller e, in generale, computers.
Nella nostra esperienza la scheda Arduino vie-
Infatti
ne alimentata con la d.d.p. disponibile sulla porta USB,
all'interno di questi dispositivi esistono oscillatori che la-
dunque tramite il computer, e questa d.d.p., tipicamente
vorano a frequenze relativamente alte e possono quindi
attorno a 5 V, viene usata come riferimento.
In appli-
perturbare in modo sensibile la misura (un esempio è
cazioni un po' più ranate si può, tra le altre opzioni,
stato citato prima a proposito della lettura eseguita su-
decidere di impiegare un'altra tensione di riferimento da
bito dopo l'accensione della porta digitale). Nella pratica
applicare a un apposito pin della scheda (AREF). Notate
sperimentale esistono diverse precauzioni per limitare gli
che usare una specica tensione di riferimento permette
eetti dei rumori impulsivi, come l'uso di cavi scherma-
di gestire al meglio la risoluzione della misura di d.d.p.,
ti o coassiali, la schermatura dell'area di lavoro, l'uso
adeguandola alle necessità dell'esperimento.
di opportuni ltri passa-basso, etc.
Nessuna di queste
Per le nalità dell'esperienza qui discussa, non occorre
precauzioni viene presa nelle nostre esperienze, per cui è
V (t) in unità siche (V), ma è suciente impie-
sicuramente possibile che nel set di dati registrato alcuni
cioè gli interi
punti siano completamente fuori dalle aspettative. Come
compresi tra 0 e 1023. Infatti le espressioni esponenzia-
in ogni realtà sperimentale, occorre vericare la signica-
li che servono per descrivere i risultati dell'esperimento
tività statistica di questi eventuali punti, cioè valutare,
V0 , che in denitiva è proprio
Vref . Dunque la bontà dell'a-
ripetendo le misure più volte, se essi hanno carattere spo-
nalisi dei dati, in particolare l'estrazione tramite best-
nascondono eetti non ricompresi nel modello utilizzato.
esprimere
gare le
unità arbitrarie di digitalizzazione,
dipendono linearmente da
la tensione di riferimento
τ,
radico (di rumore), cioè sono
artefatti della misura, o se
non dipende dall'eettivo
Un esempio importante di artefatto che si riscontra
Inoltre la sua valutazione può essere af-
nella pratica è nel comportamento di Arduino quando il
fetta da errore sistematico, ma questo errore sistematico
valore da digitalizzare corrisponde a determinati conteg-
t del tempo caratteristico
valore di
V0 .
11
gi (tipicamente intorno a 256, 512, 768, cioè a multipli
di
28 ).
L'errore di campionamento, che è normalmen-
Tabella I. Risultati dei best-t dei dati di Fig. 3.
te di una unità (la deviazione standard di migliaia di
misure, tutte della stessa d.d.p., è dell'ordine dell'unità),
Carica
Scarica
199
199
τ [ms] 3.406± 8 3.369± 7
χ2
850
490
diventa sensibilmente maggiore quando il valore da misurare si avvicina a questi valori magici, probabilmente a
ndof
causa del comportamento dei digitalizzatori in cascata
presenti nel microcontroller. Gli eetti di questo artefatto possono essere ridotti escludendo dall'analisi i punti
sperimentali corrispondenti.
I risultati dei best-t sono riportati in Tab. I: i tempi caratteristici ottenuti sono sicuramente in accordo
VIII. ESEMPI DI MISURE
con le attese e permettono di dedurre un valore
(1.01 ± 0.01) µF.
La Fig. 3 mostra un esempio di misura eseguita con
l'apparato sperimentale descritto in questa nota. Per la
misura è stato scelto un capacitore di capacità nominale
C = 1 µF
e tolleranza 10% e un resistore di resisten-
za nominale
R = 3.3
kohm e tolleranza 5%: la misura
R = (3278 ± 27) ohm.
V0 ' 5 V, si ha che la cor-
con il multimetro digitale fornisce
Notiamo che, supponendo
rente massima che deve essere erogata dal generatore,
cioè che deve uscire dalla porta digitale
vale
Imax ∼ V0 /R ≤ 2
7
di Arduino,
mA, un valore ben tollerato dalla
scheda.
Il tempo caratteristico atteso per questo circuito RC è
τ ' 3.3
ms, con un'incertezza dominata dalla tolleranza
della capacità.
C =
L'incertezza associata è molto bassa
grazie all'uso dei best-t, che sono ragionevolmente adabili visto il basso valore del
a misure per
V (t) ' 768
χ2rid
(i punti corrispondenti
arb.un. non sono stati esclusi
dall'analisi; escludendoli, il
χ2
si riduce sensibilmente).
Andando un po' più nel dettaglio, si nota come la fase
di carica sia descritta dal best-t in maniera comparativamente meno accurata, forse a causa dell'assenza di
punti sperimentali a tempi molto brevi.
Inoltre si no-
ta che i tempi caratteristici ottenuti per le due fasi non
sono comparabili: il tempo di carica risulta infatti maggiore di quello di scarica, probabilmente a causa delle
resistenze interne del microcontroller, come anticipato in
precedenza.
Tenendo conto che sono disponibili 200
punti sperimentali per la fase di carica e altrettanti per
quella di scarica, l'intervallo di campionamento da 100
µs
nominali costituisce una scelta opportuna, dato che
∼ 6τ ,
permette di registrare valori no a tempi
quan-
do le condizioni asintotiche sono state presumibilmente
ben raggiunte.
Pertanto l'acquisizione è stata eseguita
scegliendo un intervallo di campionamento
∆t = 100 µs,
ovvero nello script di Python è stata usata l'istruzione
ard.write(b'1').
Le barre di errore che compaiono nel graco sono state
determinate in accordo con quanto descritto sopra, cioè
si è posto 1 arb.un. come incertezza per
come incertezza per
t.
V
e
∆t = 100 µs
Come si vede l'andamento qua-
litativo rispecchia le aspettative sia per la fase di carica
(gracata in nero) che per quella di scarica (gracata in
rosso). Si osserva l'artefatto di campionamento descritto
in precedenza, che comporta una specie di discontinuità
nei dati per
V (t) ' 768
arb.un..
I dati sperimentali di tutte e due le fasi sono stati sottoposti a best-t secondo le funzioni esponenziali scritte
precedentemente; nel best-t è stato lasciato libero solo il
parametro
τ , tenendo sso V0 = 1023.
Osservate che, con
questa scelta, si forza l'istante iniziale di entrambi i processi a
t0 = 0 .
Figura 3. Esempio di misura eseguita con la scelta dei valori
R e C indicati; i punti, corredati delle barre di errore, rappresentano dati sperimentali, le linee continue le curve ottenute
secondo i best-t descritti nel testo; il colore nero si riferisce
alla fase di carica, il rosso a quella di scarica. Le misure di
V (t) sono riportate in unità arbitrarie di digitalizzazione, essendo il massimo valore pari a V0 = (4.91 ± 0.03) V e ogni bit
pari a V0 /1024 ' 4.9 mV.
Nell'incertezza sperimentale da usare nel
best-t si è tenuto conto, sommando in quadratura, sia
dell'incertezza su
V
che su
t,
il cui eetto è stato debita-
mente propagato sulla misura di
V (t).
Le curve ottenute
La Fig. 4 mostra in scala semi-logaritmica gli stessi dati
di Fig. 3, limitatamente alla fase di scarica e no al tempo
t = 20 ms,
per evitare di considerare valori
V (t) = 0,
che
con i best-t sono rappresentate con linee continue so-
non possono essere rappresentati in questa scala. Si os-
vrapposte ai dati: si osserva un accordo apparentemente
serva come il best-t sia correttamente rappresentato da
molto buono.
una retta (l'esponenziale decrescente diventa una retta
12
in carta semi-logaritmica): l'accordo con i dati nella regione di massima sensibilità del graco, cioè per piccoli
valori di
V (t),
appare solo discreto, forse a causa della
sottostima dell'incertezza per letture prossime a zero.
Figura 4. Analogo di Fig. 3 in rappresentazione semilogaritmica per la sola fase di scarica no a t = 20
ms.
Da ultimo, la Fig. 5 mostra qualche altro esempio di
misure ottenute con diverse scelte dei valori di
R
e
C,
come indicato nei vari pannelli. L'accordo con i best-t
è sempre piuttosto buono e i risultati (qui non riportati per brevità) sono compatibili con le aspettative.
Si
vede come, aggiustando opportunamente la durata dell'intervallo di campionamento tra 100 e 900
µs (vedi scala
orizzontale, i punti sono sempre 200 per tutte le misure),
sia possibile ricostruire le curve di carica e scarica per
circuiti con costanti tempo diverse fra loro per oltre un
ordine di grandezza.
13
Figura 5. Analogo di Fig. 3 per diverse scelte dei valori di
R e C , come indicato sopra ai graci. Le misure sono state
eseguite regolando opportunamente l'intervallo di campionamento, come si può facilmente dedurre osservando la scala
orizzontale dei graci.