Nota
Ciao, benvenuto nella community di SunFounder Raspberry Pi & Arduino & ESP32 su Facebook! Approfondisci le tue conoscenze su Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.
Perché unirti a noi?
Supporto Esperto: Risolvi i problemi post-vendita e le sfide tecniche con l’aiuto della nostra comunità e del nostro team.
Impara e Condividi: Scambia suggerimenti e tutorial per migliorare le tue competenze.
Anteprime Esclusive: Ottieni accesso anticipato ai nuovi annunci di prodotti e alle anteprime.
Sconti Speciali: Approfitta di sconti esclusivi sui nostri prodotti più recenti.
Promozioni Festive e Giveaway: Partecipa a concorsi e promozioni festive.
👉 Pronto a esplorare e creare con noi? Clicca su [Qui] e unisciti subito!
2.1.7 Potenziometro
Nota
A seconda della versione del tuo kit, identifica se hai ADC0834 o MCP3008 e procedi con la sezione corrispondente.
Introduzione
La funzione ADC può essere utilizzata per convertire segnali analogici in segnali digitali, e in questo esperimento viene utilizzato ADC0834 per ottenere tale funzione. Qui, implementiamo questo processo utilizzando un potenziometro. Il potenziometro cambia la quantità fisica, cioè la tensione, che viene convertita dalla funzione ADC.
Componenti Necessari
In questo progetto, abbiamo bisogno dei seguenti componenti.
È sicuramente conveniente acquistare un kit completo, ecco il link:
Nome |
COMPONENTI IN QUESTO KIT |
LINK |
|---|---|---|
Raphael Kit |
337 |
Puoi anche acquistarli separatamente dai link seguenti.
INTRODUZIONE AI COMPONENTI |
LINK PER L’ACQUISTO |
|---|---|
- |
Schema Elettrico
Procedure Sperimentali
Passo 1: Costruisci il circuito.
Nota
Posiziona il chip facendo riferimento alla posizione corrispondente raffigurata nell’immagine. Nota che le scanalature sul chip dovrebbero essere a sinistra quando viene posizionato.
Passo 2: Apri il file del codice.
cd ~/raphael-kit/c/2.1.7/
Passo 3: Compila il codice.
gcc 2.1.7_Potentiometer.c -lwiringPi
Passo 4: Esegui.
sudo ./a.out
Dopo l’esecuzione del codice, ruota la manopola del potenziometro e l’intensità dell’LED cambierà di conseguenza.
Nota
Se non funziona dopo l’esecuzione o appare un errore come: "wiringPi.h: No such file or directory", fai riferimento a Installa e Controlla wiringPi.
Codice
#include <wiringPi.h>
#include <stdio.h>
#include <softPwm.h>
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);
// Start bit
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
// Single End mode
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))<<i);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
}
digitalWrite(ADC_CS,1);
pinMode(ADC_DIO, OUTPUT);
return(dat1==dat2) ? dat1 : 0;
}
int main(void)
{
uchar analogVal;
if(wiringPiSetup() == -1){ //quando l'inizializzazione wiring fallisce, stampa messaggio a schermo
printf("setup wiringPi failed !");
return 1;
}
softPwmCreate(LedPin, 0, 100);
pinMode(ADC_CS, OUTPUT);
pinMode(ADC_CLK, OUTPUT);
while(1){
analogVal = get_ADC_Result(0);
printf("Current analogVal : %d\n", analogVal);
softPwmWrite(LedPin, analogVal);
delay(100);
}
return 0;
}
Spiegazione del Codice
#define ADC_CS 0
#define ADC_CLK 1
#define ADC_DIO 2
#define LedPin 3
Definisci CS, CLK, DIO di ADC0834 e collegali rispettivamente a GPIO0, GPIO1 e GPIO2. Quindi collega il LED a GPIO3.
uchar get_ADC_Result(uint channel)
{
uchar i;
uchar dat1=0, dat2=0;
int sel = channel > 1 & 1;
int odd = channel & 1;
pinMode(ADC_DIO, OUTPUT);
digitalWrite(ADC_CS, 0);
// Start bit
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
// Single End mode
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))<<i);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
}
digitalWrite(ADC_CS,1);
pinMode(ADC_DIO, OUTPUT);
return(dat1==dat2) ? dat1 : 0;
}
Esiste una funzione di ADC0834 per ottenere la conversione da analogico a digitale. Il flusso di lavoro specifico è il seguente:
digitalWrite(ADC_CS, 0);
Imposta CS a livello basso e inizia ad abilitare la conversione AD.
// Start bit
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
Quando si verifica la transizione da basso ad alto dell’input del clock per la prima volta, imposta DIO a 1 come bit di avvio. Nei tre passaggi successivi, ci sono 3 parole di assegnazione.
// Single End mode
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
Non appena si verifica la transizione da basso ad alto dell’input del clock per la seconda volta, imposta DIO a 1 e scegli la modalità SGL.
// ODD
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,odd); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
Una volta che si verifica per la terza volta, il valore di DIO è controllato dalla variabile odd.
// Select
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,sel); delayMicroseconds(2);
digitalWrite(ADC_CLK,1);
Il quarto impulso di CLK convertito da livello basso a livello alto, il valore di DIO è controllato dalla variabile sel.
- Nella condizione in cui channel=0, sel=0, odd=0, le formule operative riguardanti
sel e odd sono le seguenti:
int sel = channel > 1 & 1;
int odd = channel & 1;
Quando la condizione channel=1, sel=0, odd=1 è soddisfatta, fai riferimento alla seguente tabella di logica del controllo degli indirizzi. Qui viene scelto CH1, e il bit di avvio viene spostato nella posizione iniziale del registro multiplexer e la conversione inizia.
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
Qui, imposta due volte DIO a 1, ignoralo.
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(), non appena il quinto impulso di CLK viene convertito da alto a basso livello, imposta DIO in modalità di input. Quindi la conversione inizia e il valore convertito viene memorizzato nella variabile dat1. Dopo otto periodi di clock, la conversione è completata.
for(i=0;i<8;i++)
{
dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))<<i);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
}
Nel secondo ciclo for(), i valori convertiti vengono emessi tramite DO dopo altri otto periodi di clock e memorizzati nella variabile dat2.
digitalWrite(ADC_CS,1);
pinMode(ADC_DIO, OUTPUT);
return(dat1==dat2) ? dat1 : 0;
return(dat1==dat2) ? dat1 : 0 viene utilizzato per confrontare il valore ottenuto durante la conversione e il valore in uscita. Se sono uguali tra loro, emette il valore convertito dat1; altrimenti emette 0. Qui, il flusso di lavoro di ADC0834 è completato.
softPwmCreate(LedPin, 0, 100);
La funzione è quella di utilizzare il software per creare un pin PWM, LedPin, quindi la larghezza dell’impulso iniziale è impostata a 0, e il periodo del PWM è 100 x 100us.
while(1){
analogVal = get_ADC_Result(0);
printf("Current analogVal : %d\n", analogVal);
softPwmWrite(LedPin, analogVal);
delay(100);
}
Nel programma principale, leggi il valore del channel 0 che è stato collegato a un potenziometro. Memorizza il valore nella variabile analogVal e quindi scrivilo in LedPin. Ora puoi vedere la luminosità dell’LED cambiare con il valore del potenziometro.
Immagine del Fenomeno