Nuova sezione libri disponibile!

Un laboratorio di Fisica con Python e Arduino - Circuito RC v2

Ludovico Russo

lettura in 7 minuti

Come premesso, ripropongo oggi l'esperimento sul circuito RCRC presentato in questo post e rivisto utilizzando l'IDE di programmazione scientifica Spyder e la libreria per sviluppare programmi Arduino in Python nanpy.

Spyder + Nanpy + RC

Per info sull'accoppiata e su come installare il tutto, rimando al mio precedente post.

Teoria sul circuito RCRC

Il circuito RCRC è un semplice circuito elettronico composto da un condensatore (di capacità CC) in serie ad una resistenza (di valore RR).

Quando un circuito RCRC inizialmente spento viene alimentato ad una tensione V∞V_\infty, si può verificare che l'andamento nel tempo della tensione ai capi del condensatore rispetta la legge

v(t)=V∞⋅(1−e−tRC)v(t) = V_\infty \cdot \left(1-e^{-\frac{t}{RC}}\right)

Il valore τ=RC\tau = RC è anche detto costante di tempo.

Tolleranze dei Componenti

Nell'esperimento che proponiamo oggi, considereremo anche le tolleranze che abbiamo sui componenti elettronici che useremo. In fisica è noto e accettato dalla comunità l'impossibilità di ottenere misure esatte. Ogni misura ottenuta si trova quindi all'interno di un insieme numerico (range di incertezza) di valori accettabili.

Similmente, riguardo ai componenti elettronici commerciali, è impossibile per i produttori creare componenti sempre uguali: per questo motivo, al valore nominale di un componente è sempre associato una tolleranza, che ne definisce il range di incertezza.

Facciamo un esempio: se prendiamo un resistore RR di valore nominale 100kΩ100k\Omega e tolleranza 5%5\%, sappiamo che la misura reale della resistenza del componente sarà all'interno del range 100Ω±5%=[95−105]Ω100\Omega\pm5\% = [95 - 105]\Omega.

Scopo dell'esperimento

Lo scopo dell'esperimento è verificare che la legge delle carica del condensatore è rispettata. Il procedimento adottato sarà il seguente:

  • Utilizziamo la legge della carica del condensatore per simulare l'andamento (considerando le tolleranze dei componenti).
  • Misuriamo la carica di un condensatore di un circuito RCRC reale.
  • Confrontiamo la simulazione con i dati reali verificando che la misura ricade all'interno del range di incertezza dei componenti.
  • Otteniamo una misura più precisa della costante di tempo τ\tau utilizzando Python.

Circuito

Il circuito sviluppato è mostrato nella figura seguente. Il materiale utilizzato è qui riportato:

  • Arduino UNO.
  • Condensatore Elettrolitico C=100μF±50%C=100\mu F \pm 50\%).
  • Resistore (nel mio caso con R=200Ω±5%R=200\Omega\pm5\%).
  • Breadboard.

Importante: dato che Arduino (specialmente quando comunica in seriale) non è capace di acquisire dati ad una frequenza molto elevata, per riuscire a prendere un numero adeguato di dati conviene scegliere valori di RR e CC abbastanza elevati, in modo da avere constanti di tempo dell'ordine di qualche di qualche decina di millisecondi. Nel mio caso, ho scelto τ=RC=0.02s\tau=RC=0.02s nominale.

RC-Scheme

Essendo il condensatore che ho utilizzato elettrolitico, i suoi terminali sono polarizzati, ossia è necessario collegare il terminale positivo (anodo) ad un punto del circuito avente potenziale più elevato rispetto al punto di collegamento del terminale negativo (catodo). Nel caso si utilizzi un condensatore ceramico, non è importante la polarità!

Colleghiamo quindi il catodo (−-) del condensatore al PIN GND di Arduino ,e l'anodo (++) tramite breadboard al pin A0A0. Colleghiamo inoltre, per mezzo di una resistenza, l'anodo del condensatore al PIN 22 di Arduino.

Simulazione

Per simulare l'andamento della tensione v(t)v(t) dobbiamo considerare il parametro τ=RC\tau = RC. Date le tolleranze dei due circuiti, possiamo stimare la costante di tempo come

τ=0.02s±55%∈[0.09,0.31]s\tau = 0.02s \pm 55\% \in [0.09, 0.31]s

Andremo, quindi, a simulare 3 curve, rappresentate dalla τ^=0.02s\hat{\tau} = 0.02s nominale, e dai valori minimo e massimo che essa può assumere: τm=0.009s\tau_m = 0.009s e τM=0.031s\tau_M = 0.031s. In questo esperimento non andremo a considerare le altre incertezze, come quella sulla tensione di carica V∞V_\infty o dell'incertezze sulle misure dei sensori.

Per disegnare le tre curve, implementiamo una funzione in Python che calcola i valori della curva data i campioni di tempo in forma di vettore e il valore di tautau da utilizzare

def v_s(t, tau):
    return 5*(1-np.exp(-1/tau * t))

Andremo quindi ad utilizzare questa funzione all'interno di uno script in Spyder.

from pylab import *
import numpy as np

def v_s(t, tau):
    return 5*(1-np.exp(-1/tau * t))

t = arange(0,0.2,0.0001)
tau = 0.02
eps_tau = 0.55
tau_m, tau_M = tau-eps_tau*tau, tau+ eps_tau*tau

plot(t, v_s(t, tau), 'k-')
plot(t, v_s(t, tau_m),'k--')
plot(t, v_s(t, tau_M),'k--')

Il cui output sarà il seguente

Simulazione RC

Si noti che la simulazione viene fatta fino a 0.2s0.2s. Questo valore è calcolato in modo da essere molto più grande (circa 10 volte) la costante di tempo stimata.

Campionamento del Circuito RC

A questo punto, utilizziamo nanpy per campionare i dati utilizzando il seguente script


from datetime import datetime
from nanpy import ArduinoApi, SerialManager
from time import sleep

# connessione ad arduino sulla porta seriale specifica
connection = SerialManager(device='/dev/cu.usbmodem1461')
a = ArduinoApi(connection=connection)

# scarichiamo il condenatore
a.pinMode(2, a.OUTPUT)
a.digitalWrite(2, a.LOW)
sleep(2)

# carichiamo il condensatore e misuriamo l'andamento
a.digitalWrite(2, a.HIGH)
ts = datetime.now()
vm, tm = [], []
for i in range(0,50):
    vm.append(5.0*a.analogRead(14)/1023.0)
    tm.append(datetime.now())
print 'stop'

# convertiamo i dati in numpy
tm = [(i-ts).total_seconds() for i in  tm]
tm = np.array(tm)
vm = np.array(vm)

# plot
plot(tm,vm, '.')

Questo semplice script, dopo aver scaricato il condensatore, prevede a misurare la carica sul condensatore nel tempo, salvando anche i valori temporali in cui questi dati vengono campionati.

Alla fine, plotta i valori misura nel tempo, ottenendo questo risultato.

Misura RC

Come si può vedere dal grafico, l'andamento dei campioni è molto simile ad una curva esponenziale negativa.

Come sopra, abbiamo fatto in modo che il campionamento vada avanti per circa 10 volte la stima della costante di tempo. Questo viene fatto modificando il numero di campioni all'interno del ciclo for.

Verifica della legge della carica del circuito e misura sperimentale di τ\tau

Non ci resta che verificare se la legge fisica di carica del condensatore è effettivamente verificata. Per fare questo, per prima cosa è necessario verificare che i campioni siano all'interno delle due curve simulate con i valori limite di τ\tau considerando le tolleranze. Per fare questo, basta eseguire di seguito i due script ripostati sopra in modo da sovrapporre i plot, ottenendo un risultato simile a questo:

Verifica RC

In cui si può effettivamente vedere che l'andamento stimato è rispettato.

Per ultimo, verifichiamo che l'andamento dei campioni sia effettivamente ben approssimato da una curva esponenziale decrescente, e calcoliamo il tau∗tau^* che meglio approssima questi campioni.

Per far questo, possiamo utilizzare un interessante modulo chiamato from scipy.optimize ed in particolare la funzione curve_fit contenuta al suo interno.

Con le seguenti linee di codice, chiediamo alla funzione curve_fit di calcolare il miglior tau che meglio approssima i dati campionati (tm e vm), utilizzando la funzione v_s implementata prima.

from scipy.optimize import curve_fit
popt, pcov = curve_fit(v_s, tm, vm)

La funzione ritorna due valori:

  • popt è un array contenente il set di parametri di v_s che meglio approssima i dati (in questo caso, dato che l'unico parametro utilizzato è τ\tau, popt conterrà un solo elemento).
  • pcov contiene l'errore di approssimazione

Possiamo quindi utilizzare questi dati per estrapolare una misura più precisa del tau reale τ∗\tau^* e quindi la curva che meglio approssima i valori ottenuti.

Otteniamo quindi

  • τ∗=0.028∈[0.09,0.31]\tau^* = 0.028 \in [0.09, 0.31] compatibile con il range di valori stimato all'inizio
  • Un errore molto piccolo ϵ=1.62⋅10−7\epsilon = 1.62\cdot 10^{-7}

Che producono la curva rossa nel seguente grafico

Stima tau RC

Codice Completo

Di seguito vi riporto il codice completo utilizzato nel tutorial

# -*- coding: utf-8 -*-

from pylab import *
import numpy as np
from nanpy import ArduinoApi, SerialManager
from time import sleep

def v_s(t, tau):
    return 5*(1-np.exp(-1/tau * t))

t = arange(0,0.2,0.0001)
tau = 0.02
eps_tau = 0.55
tau_m, tau_M = tau-eps_tau*tau, tau+ eps_tau*tau

plot(t, v_s(t, tau), 'k-')
plot(t, v_s(t, tau_m),'k--')
plot(t, v_s(t, tau_M),'k--')

connection = SerialManager(device='/dev/cu.usbmodem1461')
a = ArduinoApi(connection=connection)

a.pinMode(2, a.OUTPUT)
a.digitalWrite(2, a.LOW)
sleep(2)

print 'start'

from datetime import datetime

a.digitalWrite(2, a.HIGH)
ts = datetime.now()

vm, tm = [], []
for i in range(0,50):
    vm.append(5.0*a.analogRead(14)/1023.0)
    tm.append(datetime.now())
print 'stop'

tm = [(i-ts).total_seconds() for i in  tm]

tm = np.array(tm)
vm = np.array(vm)

plot(tm,vm, '.')

from scipy.optimize import curve_fit
popt, pcov = curve_fit(v_s, tm, vm)

tau_star = popt[0]
epsilon = pcov[0]
plot(t, v_s(t, tau_star),'r')

Conclusioni

Come potete vedere, utilizzando questi strumenti si può, in pochissimo tempo e con pochissimo materiale, sviluppare un esperimento di elettrotecnica semplice ma completo. È ovviamente possibile complicare a piacere questo esperimento aggiungendo nuovi componenti elettrici al circuito o utilizzando componenti di valori diversi.

Come al solito, gli interessati possono contattarmi sulla mia pagina facebook per commenti e/o consigli.

Ti è piaciuto questo post?

Registrati alla newsletter per rimanere sempre aggiornato!

Ci tengo alla tua privacy. Leggi di più sulla mia Privacy Policy.

Ti potrebbe anche interessare

HB Cloud Tutorial #1 - Uso dei Led
Iniziamo ad utilizzare la piattaforma di Cloud Robotics
HB Cloud Tutorial #2 - Uso dei Bottoni
Rieccomi con il secondo tutorial legato all'uso dei bottoni per il robot **DotBot-ROS**. In questo tutorial, vedremo come configurare ed utilizzare in Python un bottone attaccato ad un pin GPIO del Raspberry Pi 3.
HB Cloud Tutorial #3 - I Motori
I Motori sono una delle parti essenziali dei robot. In questo tutorial, vederemo come è possibile in modo semplice ed intuitivo implementare un programma in Python che controlla i motori in base a comandi inviati via Wifi al Robot.
Utilizzare la RaspiCam in streaming con la piattaforma Cloud
Breve tutorial che spiega come abilitare la RaspiCam su ROS e la piattaforma di Cloud Robotics
Installiamo ROS su Raspberry Pi
Un breve tutorial su come utilizzare ROS sul Raspberry Pi
Video Corso ROS Rokers - Completati i video di Introduzione
Sono disponibili online i video tutorial del corso di ROS partito dalla community Rokers
Inviare Goals alla Navigation Stack - versione nodo ROS Python
Inviare un goal all ROS navigation stack utilizzando un nodo Python
Controllare siBOT dalla piattaforma HBR
Come controllare il manipolatore siBOT utilizzando la piattaforma HBR
Sviluppare un rilevatore di fiamma con la visione artificiale
Sviluppare un rilevatore di fiamma con la visione artificiale
Scriviamo un Blog in Python e Flask
Tutorial su come implementare, a partire da zero, un blog personale utilizzando Python e Flask! Prima parte!
Un laboratorio di Fisica con Arduino e Python
Primi esperimenti con Arduino e Python per realizzare un semplice laboratorio di fisica sfruttando la potenza di Python e la versatilità di Arduino
Un IDE web Arduino sviluppato in Python e Flask
Un mio progetto dell'estate del 2015 che permette di programmare Arduino da un'interfaccia Web esposta da un Raspberry Pi
Utilizziamo Atom come editor di testo remoto su Raspberry Pi
Come usare Atom come editor di testo remoto per Raspberry Pi
Canopy: una Pythonica alternativa a Matlab
Presento questo interessante tool python che può essere considerato una buona alternativa a Matlab per l'analisi dei dati!
Spyder, un'altra alternativa in Python a Matlab
Una velocissima prova del tool interattivo Spyder per l'analisi scientifica in Python
Simuliamo il moto parabolico in Python e Spyder
Un piccolo tutorial per iniziare ad utilizzare Spyder con Python
Python + Arduino = Nanpy
Programmare Arduino in Python con Nanpy
Utilizzo di Nanpy con il sensore di temperatura/umidità della famiglia DHT
Come utilizzare Nanpy col sensore DHT di temperatura e Umidità
Pasqua al Liceo Stampacchia di Tricase: Corsi di Arduino e Stampa 3D
In occasione delle vacanze di Pasqua 2017, il Liceo G. Stampacchia organizza due corsi tenuti da me su Arduino e stampa 3D.
Breve Introduzione all'utilizzo di Spyder per il Plot dei dati a livello scientifico
Una brevissima guida che mostra come utilizzare Spyder per il plot dei dati a livello scientifico
Accendere led con Arduino e Telegram
Un bot telegram in grado di controllare Arduino realizzato da 3 ragazzi del Liceo Stampacchia
Gestire le macchine virtuali senza sforzo con Vagrant
Introduzione ed esempio di utilizzo su Vagrant, il tool che semplifica la gestione delle macchine virtuali per lo sviluppo.
Implementiamo un bot Telegram con Python
Una semplice guida per iniziare a muovere i primi passi nello sviluppo di chatbot Telegram con Python
Pillole di Python: pyscreenshot
Una semplice tutorial che mostra il funzionamento della libreria pyscreenshot
Sviluppiamo un'app in Electron per controllare la scheda Arduino - parte 2
In questo tutorial, vediamo come sviluppare un oscilloscopio con Node.js, Electron e Typescript
Python Decorators
Introduzione ai decoratori in Python
TDD con Flask e PyTest per lo sviluppo di API REST. Parte 1
Tutorial su come usare il Test Driver Development (TDD) con Flask e PyTest per sviluppare delle semplici API REST
Implementiamo un bot Telegram con Python - I Comandi
Vediamo come gestire i comandi del nostro bot in Telegram
4 (+1) Libri su Python (in Inglese) da cui imparare
Una lista di libri su Python (in Inglese) da cui ho imparato a programmare
Virtualenv: gestiamo meglio le dipendenze in Python
A cosa servono e come si utilizzano i virtualenv Python
Leggere i codici a barre con OpenCV e zbar in Python
Come usare Python per leggere i codici a barre degli alimenti e ricavarne alcune informazioni utili
TDD con Flask e PyTest per lo sviluppo di API REST. Parte 2
Tutorial su come usare il Test Driver Development (TDD) con Flask e PyTest per sviluppare delle semplici API REST
Sviluppiamo un bot Telegram che legge i codici a barre degli alimenti
Implementiamo un bot Telegram in grado di leggere ed analizzare le immagini per la lettura ed interpretazione dei codici a barre
TDD con Flask e PyTest per lo sviluppo di API REST. Parte 3
Tutorial su come usare il Test Driver Development (TDD) con Flask e PyTest per sviluppare delle semplici API REST
Divertiamoci sviluppando UI da terminale con ASCIIMATICS
Le UI da terminale fanno molto anni '80, però sono sempre diventerti da implementare. Oggi vi voglio introdurre ad una semplice libreria per creare questo tipo di applicazione.
Sviluppiamo un Robot con tecnologie Open Source
Inizio una serie di videoguide, in cui voglio introdurvi al mondo della robotica di servizio in modo pratico, facendo vedere come è possibilile, sfruttando tecnologie completamente Open Source, quali Arduino, Raspberry Pi, ROS e Docker, costruire un piccolo robot di Servizio.
Parliamo come GMaps: come creare file audio con gtts (Google Text to Speech) in Python
gtts è una libreria in Python per sfruttare le API di Google Text to Speech per generare file audio dal testo
Robot Open Source - Introduzione a Docker
È disponibile il video "Introduzione a Docker".
I chatbot possono Parlare? Sviluppiamo un bot telegram che manda messaggi vocali
Usiamo le API di sintesi vocale di google per creare un bot in grado di mandare messaggi vocali
Robot Open Source - Docker e Raspberry
È disponibile il video "Docker e Raspberry".