.. note:: Ciao, benvenuto nella Community di Appassionati di SunFounder Raspberry Pi & Arduino & ESP32 su Facebook! Approfondisci le tue conoscenze su Raspberry Pi, Arduino e ESP32 insieme ad altri appassionati. **Perché unirsi a noi?** - **Supporto esperto**: Risolvi problemi tecnici e post-vendita con l'aiuto della nostra comunità e del nostro team. - **Impara e condividi**: Scambia consigli e tutorial per migliorare le tue competenze. - **Anteprime esclusive**: Accedi in anteprima agli annunci dei nuovi prodotti e dai un’occhiata ai futuri progetti. - **Sconti speciali**: Approfitta di sconti esclusivi sui nostri ultimi prodotti. - **Promozioni festive e omaggi**: Partecipa a promozioni festive e concorsi con premi. 👉 Sei pronto a esplorare e creare con noi? Clicca su [|link_sf_facebook|] e unisciti oggi stesso! 2.1.4 Potenziometro ====================== .. 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 ---------------- In questa lezione impareremo a utilizzare la funzione ADC per convertire segnali analogici in segnali digitali utilizzando l'ADC0834. In questo esperimento, utilizzeremo un potenziometro per generare una tensione variabile che sarà convertita dalla funzione ADC. Componenti -------------- .. image:: img/list_2.1.4_potentiometer.png Principio di funzionamento ---------------------------- **ADC0834** L'ADC0834 è un convertitore analogico-digitale (ADC) a 8 bit `successive approximation `__ con approssimazione successiva dotato di un multiplexer multicanale configurabile e di un input/output seriale, configurato per interfacciarsi con registri a scorrimento standard o microprocessori. .. image:: img/image309.png **Sequenza di operazione** La conversione si avvia impostando CS a livello basso, abilitando così tutti i circuiti logici. CS deve rimanere basso per tutta la durata del processo di conversione. Viene quindi ricevuto un impulso di clock dal processore. A ogni transizione del clock da basso a alto, i dati su DI vengono immessi nel registro del multiplexer. Il primo livello alto rilevato è il bit di avvio, seguito da una parola di assegnazione da 3 a 4 bit. Quando il bit di avvio raggiunge la posizione iniziale nel registro del multiplexer, viene selezionato il canale di input e la conversione inizia. L'uscita SAR (SARS) passa a livello alto per indicare che è in corso una conversione e il DI è disabilitato per tutta la durata della conversione. Viene quindi inserito automaticamente un intervallo di un periodo di clock per consentire al canale multiplexato di stabilizzarsi. L'uscita DO passa dallo stato di alta impedenza e fornisce un livello basso per un periodo di stabilizzazione. Il comparatore SAR confronta le uscite successive della scala resistiva con il segnale analogico in ingresso, determinando se l'input analogico è maggiore o minore rispetto al valore della scala resistiva. I dati di conversione vengono simultaneamente emessi dal pin DO con il bit più significativo (MSB) per primo. Dopo otto periodi di clock, la conversione è completata e l'uscita SARS si porta a livello basso. Infine, vengono trasmessi i dati dal bit meno significativo (LSB) dopo la sequenza di dati con il bit più significativo (MSB) per primo. .. image:: img/image175.png :width: 800 :align: center **Tabella di controllo indirizzo MUX ADC0834** .. image:: img/image176.png :width: 800 :align: center **Potenziometro** Il potenziometro è un componente a tre terminali il cui valore di resistenza può essere regolato. È composto da un resistore e una spazzola mobile che, muovendosi lungo il resistore, fornisce una tensione variabile in uscita. .. image:: img/image310.png :width: 300 :align: center Le funzioni del potenziometro nel circuito sono le seguenti: 1. Divisore di tensione Il potenziometro è una resistenza regolabile continuamente. Quando si regola l'albero o la manopola del potenziometro, il contatto mobile si sposta sul resistore, permettendo di ottenere una tensione in uscita variabile in base alla tensione applicata e all'angolo o distanza di spostamento del contatto. Schema Elettrico -------------------- .. image:: img/image311.png .. image:: img/image312.png Procedura Sperimentale -------------------------- **Step 1:** Montare il circuito. .. image:: img/image180.png :width: 800 .. note:: Posizionare il chip facendo riferimento alla posizione corretta illustrata nell'immagine. Assicurarsi che le scanalature sul chip siano orientate a sinistra. Per gli utenti di linguaggio C ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Step 2:** Aprire il file di codice. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/c/2.1.4/ **Step 3:** Compilare il codice. .. raw:: html .. code-block:: gcc 2.1.4_Potentiometer.c -lwiringPi **Step 4:** Eseguire. .. raw:: html .. code-block:: sudo ./a.out Dopo aver eseguito il codice, ruotando la manopola del potenziometro, l'intensità del LED cambierà di conseguenza. .. note:: Se non funziona dopo l'esecuzione o appare il messaggio di errore: \"wiringPi.h: No such file or directory", fare riferimento a :ref:`faq_c_nowork`. **Codice** .. code-block:: c #include #include #include typedef unsigned char uchar; typedef unsigned int uint; #define ADC_CS 0 #define ADC_CLK 1 #define ADC_DIO 2 #define LedPin 3 uchar get_ADC_Result(uint channel) { uchar i; uchar dat1=0, dat2=0; int sel = channel > 1 & 1; int odd = channel & 1; digitalWrite(ADC_CLK, 1); delayMicroseconds(2); digitalWrite(ADC_CLK, 0); delayMicroseconds(2); pinMode(ADC_DIO, OUTPUT); digitalWrite(ADC_CS, 0); // Bit di avvio digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,1); delayMicroseconds(2); // Modalità Single End digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,1); delayMicroseconds(2); // ODD digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,odd); delayMicroseconds(2); digitalWrite(ADC_CLK,1); delayMicroseconds(2); // Select digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,sel); delayMicroseconds(2); digitalWrite(ADC_CLK,1); digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); for(i=0;i<8;i++) { digitalWrite(ADC_CLK,1); delayMicroseconds(2); digitalWrite(ADC_CLK,0); delayMicroseconds(2); pinMode(ADC_DIO, INPUT); dat1=dat1<<1 | digitalRead(ADC_DIO); } for(i=0;i<8;i++) { dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))< 1 & 1; int odd = channel & 1; digitalWrite(ADC_CLK, 1); delayMicroseconds(2); digitalWrite(ADC_CLK, 0); delayMicroseconds(2); pinMode(ADC_DIO, OUTPUT); digitalWrite(ADC_CS, 0); // Bit di avvio digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,1); delayMicroseconds(2); // Modalità Single End digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,1); delayMicroseconds(2); // ODD digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,odd); delayMicroseconds(2); digitalWrite(ADC_CLK,1); delayMicroseconds(2); // Select digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,sel); delayMicroseconds(2); digitalWrite(ADC_CLK,1); digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); for(i=0;i<8;i++) { digitalWrite(ADC_CLK,1); delayMicroseconds(2); digitalWrite(ADC_CLK,0); delayMicroseconds(2); pinMode(ADC_DIO, INPUT); dat1=dat1<<1 | digitalRead(ADC_DIO); } for(i=0;i<8;i++) { dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))< 1 & 1; int odd = channel & 1; Con channel=1, sel=0 e odd=1, consulta la tabella di logica di controllo degli indirizzi qui sotto. Qui viene selezionato CH1, e il bit di avvio è registrato nell’indirizzo del multiplexer per avviare la conversione. .. image:: img/image313.png .. code-block:: c digitalWrite(ADC_DIO,1); delayMicroseconds(2); digitalWrite(ADC_CLK,0); digitalWrite(ADC_DIO,1); delayMicroseconds(2); Qui, imposta due volte DIO a 1, ignoralo. .. code-block:: c for(i=0;i<8;i++) { digitalWrite(ADC_CLK,1); delayMicroseconds(2); digitalWrite(ADC_CLK,0); delayMicroseconds(2); pinMode(ADC_DIO, INPUT); dat1=dat1<<1 | digitalRead(ADC_DIO); } Nel primo ciclo for(), al quinto impulso del clock che passa da alto a basso, imposta DIO in modalità input. La conversione inizia e il valore convertito è memorizzato in dat1. Dopo otto impulsi di clock, la conversione è completata. .. code-block:: c for(i=0;i<8;i++) { dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))< .. code-block:: cd ~/davinci-kit-for-raspberry-pi/python/ **Passo 3:** Esegui. .. raw:: html .. code-block:: sudo python3 2.1.4_Potentiometer.py Dopo aver eseguito il codice, ruota la manopola del potenziometro e l’intensità del LED cambierà di conseguenza. **Codice** .. note:: Puoi **Modificare/Reimpostare/Copiare/Eseguire/Arrestare** il codice qui sotto. Prima di farlo, assicurati di essere nel percorso della cartella di origine, come ``davinci-kit-for-raspberry-pi/python``. .. raw:: html .. code-block:: python import RPi.GPIO as GPIO import ADC0834 import time LedPin = 22 def setup(): global led_val # Imposta la numerazione dei pin su BCM GPIO.setmode(GPIO.BCM) # Imposta il LedPin come uscita e livello iniziale a High (3,3V) GPIO.setup(LedPin, GPIO.OUT, initial=GPIO.HIGH) ADC0834.setup() # Imposta il LED come canale PWM a frequenza 2 kHz led_val = GPIO.PWM(LedPin, 2000) # Inizia con il valore 0 led_val.start(0) def destroy(): # Ferma tutti i canali PWM led_val.stop() # Rilascia le risorse GPIO.cleanup() def loop(): while True: analogVal = ADC0834.getResult() print ('analog value = %d' % analogVal) led_val.ChangeDutyCycle(analogVal*100/255) time.sleep(0.2) if __name__ == '__main__': setup() try: loop() except KeyboardInterrupt: # Quando viene premuto 'Ctrl+C', viene eseguito il programma destroy(). destroy() **Spiegazione del Codice** .. code-block:: python import ADC0834 Importa la libreria ADC0834. Puoi controllare il contenuto della libreria utilizzando il comando nano ADC0834.py. .. code-block:: python def setup(): global led_val # Imposta la numerazione dei pin su BCM GPIO.setmode(GPIO.BCM) # Imposta LedPin come uscita e livello iniziale a High (3,3V) GPIO.setup(LedPin, GPIO.OUT, initial=GPIO.HIGH) ADC0834.setup() # Imposta il LED come canale PWM a frequenza 2 kHz led_val = GPIO.PWM(LedPin, 2000) # Inizia con il valore 0 led_val.start(0) Nella funzione setup(), imposta il metodo di numerazione su BCM, configura LedPin come canale PWM e assegna una frequenza di 2 kHz. **ADC0834.setup():** Inizializza ADC0834 e collega CS, CLK e DIO definiti di ADC0834 rispettivamente a GPIO17, GPIO18 e GPIO27. .. code-block:: python def loop(): while True: res = ADC0834.getResult() print ('res = %d' % res) R_val = MAP(res, 0, 255, 0, 100) led_val.ChangeDutyCycle(R_val) time.sleep(0.2) La funzione getResult() legge i valori analogici dei quattro canali di ADC0834. Di default legge il valore di CH0; per leggere altri canali, specifica il numero del canale tra parentesi, es. getResult(1). La funzione loop() legge il valore di CH0 e lo assegna alla variabile res. Poi chiama la funzione MAP per mappare il valore del potenziometro tra 0 e 100, usato per controllare il duty cycle di LedPin. Ora vedrai che la luminosità del LED varia in base al valore del potenziometro. Immagine del Fenomeno ------------------------- .. image:: img/image181.jpeg