.. note::
Ciao, benvenuto nella Community di appassionati SunFounder Raspberry Pi & Arduino & ESP32 su Facebook! Approfondisci Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.
**Perché unirti?**
- **Supporto esperto**: Risolvi problemi post-vendita e sfide tecniche con l'aiuto della nostra community e del nostro team.
- **Impara e condividi**: Scambia suggerimenti e tutorial per migliorare le tue competenze.
- **Anteprime esclusive**: Accedi in anteprima agli annunci dei nuovi prodotti e alle anticipazioni.
- **Sconti speciali**: Godi di sconti esclusivi sui nostri prodotti più recenti.
- **Promozioni festive e giveaway**: Partecipa a giveaway e promozioni festive.
👉 Pronto a esplorare e creare con noi? Clicca [|link_sf_facebook|] e unisciti oggi stesso!
.. _2.1.4_py_pi5_mcp3008:
2.1.4 Potenziometro (MCP3008)
=============================
.. note::
.. image:: ../img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
A seconda della versione del tuo kit, identifica se possiedi **ADC0834** o **MCP3008** e procedi con la sezione corrispondente.
Introduzione
------------
La funzione ADC viene utilizzata per convertire segnali analogici in valori digitali.
In questo esperimento utilizziamo il chip ADC MCP3008 per effettuare questa conversione.
Un potenziometro viene usato per generare una tensione variabile, che cambia la grandezza fisica.
L’MCP3008 converte quindi questa tensione analogica in un valore digitale che può essere letto ed elaborato dal Raspberry Pi.
Componenti necessari
--------------------
In questo progetto, abbiamo bisogno dei seguenti componenti.
.. image:: ../python_pi5/img/list2_2.1.4_potentiometer.png
Schema elettrico
----------------
.. list-table::
:widths: 30 30 30 30
:header-rows: 1
* - Nome T-Board
- Fisico
- WiringPi
- BCM
* - SPICE0
- pin24
- 10
- 8
* - SPIMOSI
- pin19
- 12
- 10
* - SPIMISO
- pin21
- 13
- 9
* - SPISCLK
- pin23
- 14
- 11
* - GPIO22
- pin15
- 3
- 22
.. image:: ../python_pi5/img/schematic_2.1.7_potentiometer_mcp3008.png
Procedura sperimentale
----------------------
**Passo 1:** Montare il circuito.
.. image:: ../python_pi5/img/july24_2.1.7_potentiometer_mcp3008.png
.. note::
Posiziona il chip facendo riferimento alla posizione mostrata nell’immagine.
Nota che le scanalature sul chip devono essere a sinistra quando viene posizionato.
**Passo 2:** Configura l’interfaccia SPI e installa la libreria ``spidev`` (vedi :ref:`spi_configuration` per le istruzioni dettagliate). Se hai già completato questi passaggi, puoi saltarli.
**Passo 3:** Apri il file del codice
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/python-pi5
**Passo 4:** Esegui.
.. raw:: html
.. code-block::
sudo python3 2.1.4-2_Potentiometer_zero.py
Dopo l’esecuzione del codice, ruota la manopola del potenziometro: l’intensità del LED cambierà di conseguenza.
.. warning::
Se appare l’errore ``RuntimeError: Cannot determine SOC peripheral base address``, fai riferimento a :ref:`faq_soc`
**Codice**
.. note::
Puoi **Modificare/Reimpostare/Copiare/Eseguire/Interrompere** il codice qui sotto. Ma prima, devi portarti nel percorso del codice sorgente, ad esempio ``davinci-kit-for-raspberry-pi/python-pi5``.
Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l’effetto.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import spidev
import time
from gpiozero import PWMLED
# Inizializza LED PWM su GPIO22
led = PWMLED(22)
# Inizializza SPI
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CS0 (CE0)
spi.max_speed_hz = 1000000
def read_adc(channel):
"""
Legge un valore analogico da MCP3008
:param channel: Canale ADC (0-7)
:return: Intero a 10 bit (0-1023)
"""
if channel < 0 or channel > 7:
return -1
# Protocollo MCP3008
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 3) << 8) | adc[2]
return value
def MAP(x, in_min, in_max, out_min, out_max):
"""
Mappa un valore da un intervallo a un altro
"""
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
try:
while True:
# Legge dal canale 0 di MCP3008
res = read_adc(0)
print('res = %d' % res)
# Mappa 0–1023 su 0–100%
R_val = MAP(res, 0, 1023, 0, 100)
# Imposta luminosità LED
led.value = R_val / 100.0
time.sleep(0.2)
except KeyboardInterrupt:
led.value = 0 # Spegne il LED
**Spiegazione del codice**
#. ``gpiozero`` per il controllo PWM del LED, ``spidev`` per la comunicazione SPI con MCP3008 e ``time`` per implementare ritardi.
.. code-block:: python
#!/usr/bin/env python3
import spidev
import time
from gpiozero import PWMLED
#. Inizializza un oggetto PWMLED collegato al pin GPIO 22 e configura la comunicazione SPI (Bus 0, CE0) con MCP3008.
.. code-block:: python
# Inizializza LED PWM su GPIO22
led = PWMLED(22)
# Inizializza SPI
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CS0 (CE0)
spi.max_speed_hz = 1000000
#. Definisce una funzione ``read_adc`` per comunicare con MCP3008 e leggere valori analogici dal canale specificato (0–7).
.. code-block:: python
def read_adc(channel):
"""
Legge un valore analogico da MCP3008
:param channel: Canale ADC (0-7)
:return: Intero a 10 bit (0-1023)
"""
if channel < 0 or channel > 7:
return -1
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 3) << 8) | adc[2]
return value
#. Definisce una funzione ``MAP`` per convertire un intervallo di valori in un altro, utile per mappare i valori ADC ai livelli di luminosità del LED.
.. code-block:: python
def MAP(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
#. Legge continuamente il valore ADC in un ciclo, mappando il valore a 10 bit (0–1023) in un livello di luminosità (0–100) per il LED.
Regola la luminosità del LED di conseguenza e attende 0,2 secondi tra una lettura e l’altra.
.. code-block:: python
try:
while True:
# Legge dal canale 0 di MCP3008
res = read_adc(0)
print('res = %d' % res)
# Mappa 0–1023 su 0–100%
R_val = MAP(res, 0, 1023, 0, 100)
# Imposta luminosità LED
led.value = R_val / 100.0
time.sleep(0.2)
except KeyboardInterrupt:
led.value = 0 # Spegne il LED