.. note:: Ciao, benvenuto nella Community SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! 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**: Accedi in anticipo agli annunci dei 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_c_pi5_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 eseguire questa conversione. Un potenziometro viene utilizzato per generare una tensione variabile, che modifica la grandezza fisica. Il MCP3008 converte quindi questa tensione analogica in un valore digitale che può essere letto ed elaborato dal Raspberry Pi. Componenti necessari ------------------------------ In questo progetto sono necessari 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 - ELEMENTI IN QUESTO KIT - LINK * - Kit Raphael - 337 - |link_Raphael_kit| Puoi anche acquistarli separatamente dai link seguenti. .. 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:** Monta il circuito. .. image:: ../img/july24_2.1.7_potentiometer_mcp3008.png .. note:: Posiziona il chip seguendo la posizione corrispondente mostrata nell'immagine. Nota che le scanalature sul chip devono essere sul lato sinistro quando viene posizionato. **Passo 2:** Apri il file del codice. .. raw:: html .. code-block:: cd ~/raphael-kit/c/2.1.7-2/ **Passo 3:** Compila il codice. .. raw:: html .. code-block:: gcc 2.1.7_Potentiometer.c -lwiringPi **Passo 4:** Esegui. .. raw:: html .. code-block:: sudo ./a.out Dopo l'esecuzione del codice, ruota la manopola del potenziometro: l'intensità del LED cambierà di conseguenza. .. note:: Se non funziona dopo l'esecuzione o compare un errore del tipo: \"wiringPi.h: No such file or directory\", fai riferimento a :ref:`install_wiringpi_pi5`. **Codice** .. code-block:: c #include #include #include #include #define SPI_CHANNEL 0 // CE0 #define SPI_SPEED 1000000 // 1MHz #define LedPin 3 int readADC(int channel) { if (channel < 0 || channel > 7) return -1; unsigned char buffer[3]; buffer[0] = 1; // Bit di avvio buffer[1] = (8 + channel) << 4; // Modalità single-ended, canale buffer[2] = 0; wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3); int value = ((buffer[1] & 3) << 8) | buffer[2]; return value; } int main(void) { if (wiringPiSetup() == -1) { printf("Inizializzazione WiringPi fallita!\n"); return 1; } if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) { printf("Configurazione SPI fallita!\n"); return 1; } softPwmCreate(LedPin, 0, 100); while (1) { int analogVal = readADC(0); // CH0 printf("Valore ADC: %d\n", analogVal); int pwmVal = analogVal * 100 / 1023; // Normalizzazione a 0–100 softPwmWrite(LedPin, pwmVal); delay(100); } return 0; } **Spiegazione del codice** .. code-block:: c #define SPI_CHANNEL 0 // CE0 #define SPI_SPEED 1000000 // 1MHz #define LedPin 3 Definisce il canale SPI come CE0 (chip enable 0), imposta la velocità SPI a 1MHz e assegna GPIO3 al pin del LED. .. code-block:: c int readADC(int channel) { if (channel < 0 || channel > 7) return -1; unsigned char buffer[3]; buffer[0] = 1; // Bit di avvio buffer[1] = (8 + channel) << 4; // Modalità single-ended, canale buffer[2] = 0; wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3); int value = ((buffer[1] & 3) << 8) | buffer[2]; return value; } Questa funzione viene utilizzata per leggere i dati analogici dal MCP3008. * Controlla prima se il numero di canale è nel range valido (0–7). * Inizializza un array di 3 byte, dove: * ``buffer[0] = 1``: bit di avvio per la comunicazione MCP3008. * ``buffer[1] = (8 + channel) << 4``: costruisce il byte di configurazione per la modalità single-ended e seleziona il canale desiderato. * ``buffer[2] = 0``: byte segnaposto per ricevere il risultato. * ``wiringPiSPIDataRW`` invia e riceve dati tramite il canale SPI. * Il valore restituito viene estratto dagli ultimi due byte utilizzando operazioni bitwise per ottenere un risultato ADC a 10 bit. .. code-block:: c int main(void) { if (wiringPiSetup() == -1) { printf("Inizializzazione WiringPi fallita!\n"); return 1; } if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) { printf("Configurazione SPI fallita!\n"); return 1; } softPwmCreate(LedPin, 0, 100); while (1) { int analogVal = readADC(0); // CH0 printf("Valore ADC: %d\n", analogVal); int pwmVal = analogVal * 100 / 1023; // Normalizzazione a 0–100 softPwmWrite(LedPin, pwmVal); delay(100); } return 0; } Nella funzione principale: * ``wiringPiSetup()`` inizializza la libreria WiringPi. * ``wiringPiSPISetup()`` inizializza la comunicazione SPI sul canale 0 a 1MHz. * ``softPwmCreate()`` imposta un PWM software su GPIO3 con un ciclo di lavoro iniziale pari a 0 e un intervallo 0–100. Il programma entra in un ciclo infinito dove: * Legge il valore ADC dal canale 0 (collegato a un potenziometro). * Stampa il valore ADC nel terminale. * Converte il valore ADC a 10 bit in un ciclo PWM tra 0 e 100. * Scrive il valore PWM al LED, così la luminosità riflette la posizione del potenziometro. ``delay(100)`` mette in pausa per 100 millisecondi prima del ciclo successivo.