.. note:: Ciao, benvenuto nella Community Facebook di appassionati di 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 l'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_mcp3008: 2.1.7 Potenziometro (MCP3008) ============================= .. note:: .. image:: ../img/mcp3008_and_adc0834.jpg :width: 25% :align: left A seconda della versione del tuo 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 effettuare 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, ci servono i seguenti componenti. .. image:: ../img/list2_2.1.4_potentiometer.png È sicuramente conveniente 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:: ../img/schematic_2.1.7_potentiometer_mcp3008.png Procedure sperimentali ----------------------- **Passo 1:** Costruisci il circuito. .. image:: ../img/july24_2.1.7_potentiometer_mcp3008.png .. note:: Posiziona il chip facendo riferimento alla posizione corrispondente mostrata nell'immagine. Nota che le scanalature sul chip devono essere rivolte a 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 di codice .. raw:: html .. code-block:: cd ~/raphael-kit/python **Passo 4:** Esegui. .. raw:: html .. code-block:: sudo python3 2.1.7-2_Potentiometer.py Dopo l'esecuzione del codice, ruota la manopola del potenziometro, l'intensità del LED cambierà di conseguenza. .. warning:: Se compare l'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. Ma prima devi andare al percorso del codice sorgente come ``raphael-kit/python``. 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 import RPi.GPIO as GPIO # Pin GPIO per uscita PWM PWM_PIN = 22 # Configurazione GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(PWM_PIN, GPIO.OUT) # Inizializza PWM su GPIO22 a 1000Hz pwm = GPIO.PWM(PWM_PIN, 1000) pwm.start(0) # Avvia con duty cycle 0% # Inizializza SPI spi = spidev.SpiDev() spi.open(0, 0) # Bus 0, CE0 spi.max_speed_hz = 1000000 def read_adc(channel): """ Legge il valore analogico da MCP3008 :param channel: canale ADC (0-7) :return: valore 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): """ 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: # Leggi valore analogico da CH0 res = read_adc(0) print('res = %d' % res) # Converte in duty cycle 0–100% duty_cycle = MAP(res, 0, 1023, 0, 100) # Aggiorna duty cycle PWM pwm.ChangeDutyCycle(duty_cycle) time.sleep(0.2) except KeyboardInterrupt: pass finally: pwm.stop() GPIO.cleanup() spi.close() **Spiegazione del codice** #. ``RPi.GPIO`` viene utilizzato per generare segnali PWM per controllare un LED. ``spidev`` viene utilizzato per la comunicazione SPI con MCP3008. ``time`` viene utilizzato per aggiungere ritardi nel ciclo. .. code-block:: python #!/usr/bin/env python3 import spidev import time import RPi.GPIO as GPIO #. Configura il pin GPIO 22 per l'uscita PWM usando ``RPi.GPIO``. Imposta la comunicazione SPI con MCP3008 (Bus 0, CE0) a 1 MHz. .. code-block:: python PWM_PIN = 22 GPIO.setmode(GPIO.BCM) GPIO.setup(PWM_PIN, GPIO.OUT) pwm = GPIO.PWM(PWM_PIN, 1000) # frequenza 1kHz pwm.start(0) # Avvia con duty cycle 0% spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1000000 #. Questa funzione legge i dati analogici dal MCP3008 sul canale specificato (0–7) usando il protocollo SPI. Il risultato è un intero a 10 bit compreso tra 0 e 1023. .. 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 #. Questa funzione mappa un valore da un intervallo numerico a un altro. Viene utilizzata per scalare i valori ADC in percentuali di duty cycle PWM. .. 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 #. Nel ciclo principale, il programma legge continuamente i dati analogici dal canale 0 del MCP3008, mappa il valore su un intervallo PWM (0–100) e imposta di conseguenza la luminosità del LED. Il ciclo si aggiorna ogni 0,2 secondi. Se interrotto (ad esempio con Ctrl+C), il programma ferma il segnale PWM e ripristina la configurazione GPIO. .. code-block:: python try: while True: res = read_adc(0) print('res = %d' % res) duty_cycle = MAP(res, 0, 1023, 0, 100) pwm.ChangeDutyCycle(duty_cycle) time.sleep(0.2) except KeyboardInterrupt: pass finally: pwm.stop() GPIO.cleanup() spi.close()