.. note:: Ciao, benvenuto nella Community Facebook di appassionati SunFounder Raspberry Pi & Arduino & ESP32! Approfondisci Raspberry Pi, Arduino ed ESP32 con altri appassionati. **Perché unirsi?** - **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**: Ottieni accesso anticipato agli annunci di nuovi prodotti e alle anteprime. - **Sconti speciali**: Goditi 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.7_py_pi5_mcp3008: 2.1.7 Potenziometro (MCP3008) ============================= .. note:: .. image:: ../img/mcp3008_and_adc0834.jpg :width: 25% :align: left A seconda della versione del kit, identifica se hai **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 eseguire questa conversione. Un potenziometro viene utilizzato per generare una tensione variabile, che cambia la quantità fisica. Il MCP3008 converte quindi questa tensione analogica in un valore digitale che può essere letto ed elaborato dal Raspberry Pi. Componenti richiesti ------------------------------ In questo progetto, abbiamo bisogno dei seguenti componenti. .. image:: ../python_pi5/img/list2_2.1.4_potentiometer.png È sicuramente comodo acquistare un kit completo, ecco il link: .. list-table:: :widths: 20 20 20 :header-rows: 1 * - Nome - ARTICOLI IN QUESTO KIT - LINK * - Raphael Kit - 337 - |link_Raphael_kit| Puoi anche acquistarli separatamente dai link sottostanti. .. list-table:: :widths: 30 20 :header-rows: 1 * - INTRODUZIONE COMPONENTE - LINK DI ACQUISTO * - :ref:`cpn_gpio_extension_board` - |link_gpio_board_buy| * - :ref:`cpn_breadboard` - |link_breadboard_buy| * - :ref:`cpn_wires` - |link_wires_buy| * - :ref:`cpn_resistor` - |link_resistor_buy| * - :ref:`cpn_led` - |link_led_buy| * - :ref:`cpn_potentiometer` - |link_potentiometer_buy| * - :ref:`cpn_mcp3008` - \- 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 Procedure sperimentali ----------------------- **Passo 1:** Costruisci il circuito. .. image:: ../python_pi5/img/july24_2.1.7_potentiometer_mcp3008.png .. note:: Posiziona il chip seguendo la posizione corrispondente mostrata nell'immagine. Nota che la scanalatura del chip deve essere rivolta verso sinistra quando viene posizionato. **Passo 2:** Configura l'interfaccia SPI e installa la libreria ``spidev`` (vedi :ref:`spi_configuration` per istruzioni dettagliate). Se hai già completato questi passaggi, puoi saltarli. **Passo 3:** Apri il file del codice .. raw:: html .. code-block:: cd ~/raphael-kit/python-pi5 **Passo 4:** Esegui. .. raw:: html .. code-block:: sudo python3 2.1.7-2_Potentiometer_zero.py Dopo l'esecuzione del codice, ruota la manopola del potenziometro: l'intensità del LED cambierà di conseguenza. .. warning:: Se compare il messaggio di errore ``RuntimeError: Cannot determine SOC peripheral base address``, fai riferimento a :ref:`faq_soc` **Codice** .. note:: Puoi **Modificare/Resettare/Copiare/Eseguire/Fermare** il codice qui sotto. Prima, però, devi andare al percorso del codice sorgente, ad esempio ``raphael-kit/python-pi5``. Dopo aver modificato il codice, puoi eseguirlo direttamente per vederne 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): """ Leggi il valore analogico dal 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 def MAP(x, in_min, in_max, out_min, out_max): """ Converte un valore da un intervallo ad un altro """ return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min try: while True: # Leggi dal canale 0 del MCP3008 res = read_adc(0) print('res = %d' % res) # Converte 0–1023 in 0–100% R_val = MAP(res, 0, 1023, 0, 100) # Imposta la luminosità del LED led.value = R_val / 100.0 time.sleep(0.2) except KeyboardInterrupt: led.value = 0 # Spegni il LED **Spiegazione del codice** #. ``gpiozero`` per il controllo del LED PWM, ``spidev`` per la comunicazione SPI con MCP3008 e ``time`` per implementare ritardi. .. code-block:: python 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 led = PWMLED(22) spi = spidev.SpiDev() spi.open(0, 0) 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): 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 al livello 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 ADC a 10 bit (0–1023) a un livello di luminosità (0–100) per il LED. Regola di conseguenza la luminosità del LED e attende 0,2 secondi tra ogni lettura. .. code-block:: python try: while True: res = read_adc(0) print('res = %d' % res) R_val = MAP(res, 0, 1023, 0, 100) led.value = R_val / 100.0 time.sleep(0.2) except KeyboardInterrupt: led.value = 0 # Spegni il LED