Nota

Ciao, benvenuto nella community di SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! Immergiti più a fondo in Raspberry Pi, Arduino ed ESP32 con altri appassionati.

Perché unirti?

  • Supporto esperto: Risolvi i problemi post-vendita e le 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 a nuovi annunci di prodotti e anteprime.

  • Sconti speciali: Goditi sconti esclusivi sui nostri prodotti più recenti.

  • Promozioni festive e omaggi: Partecipa a omaggi e promozioni festive.

👉 Pronto a esplorare e creare con noi? Clicca su [Qui] e unisciti oggi stesso!

2.1.7 Potenziometro

Nota

../_images/mcp3008_and_adc0834.jpg

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, utilizziamo l’ADC0834 per ottenere questa funzione. Qui, implementiamo questo processo utilizzando un potenziometro. Il potenziometro cambia una grandezza fisica, ovvero la tensione, che viene convertita dalla funzione ADC.

Componenti necessari

In questo progetto abbiamo bisogno dei seguenti componenti.

../_images/list_2.1.4_potentiometer.png

È sicuramente conveniente acquistare un kit completo, ecco il link:

Nome

ELEMENTI IN QUESTO KIT

LINK

Kit Raphael

337

Raphael Kit

Puoi anche acquistarli separatamente dai link sottostanti.

INTRODUZIONE COMPONENTE

LINK PER L’ACQUISTO

Scheda di estensione GPIO

ACQUISTA

Breadboard

ACQUISTA

Cavi Jumper

ACQUISTA

Resistore

ACQUISTA

LED

ACQUISTA

Potenziometro

ACQUISTA

ADC0834

-

Schema elettrico

../_images/image311.png ../_images/image312.png

Procedure sperimentali

Passo 1: Costruisci il circuito.

../_images/image180.png

Nota

Si prega di posizionare il chip facendo riferimento alla posizione corrispondente raffigurata nell’immagine. Nota che le scanalature sul chip devono 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 sul potenziometro e l’intensità del LED cambierà di conseguenza.

Nota

Se non funziona dopo l’esecuzione o compare un messaggio di errore: "wiringPi.h: No such file or directory", consulta Installazione e verifica di 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);

    delayMicroseconds(2);
    digitalWrite(ADC_CLK,0);
    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){ //se l'inizializzazione di wiring fallisce, stampa un messaggio sullo 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. Poi 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;

    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;
}

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 a 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 prima transizione da basso ad alto del clock, imposta DIO a 1 come bit di avvio. Nei seguenti tre passaggi, 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 seconda transizione da basso ad alto del clock, 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 verificatasi 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 segnale CLK passa da basso a alto per la quarta volta, e il valore di DIO è controllato dalla variabile sel.

Con la condizione che 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 che channel=1, sel=0, odd=1 è soddisfatta, si prega di fare riferimento alla seguente tabella della logica di controllo degli indirizzi. Qui viene scelto CH1 e il bit di avvio viene spostato nella posizione iniziale del registro del multiplexer e la conversione inizia.

../_images/image313.png
digitalWrite(ADC_DIO,1);    delayMicroseconds(2);
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1);    delayMicroseconds(2);

Qui, imposta DIO a 1 due volte, ignora questo passaggio.

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 passa da alto a basso, imposta DIO in modalità input. Quindi inizia la conversione 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 è utilizzato per confrontare il valore ottenuto durante la conversione e il valore in uscita. Se sono uguali, viene emesso il valore convertito dat1; altrimenti, viene emesso 0. Qui, il flusso di lavoro di ADC0834 è completato.

softPwmCreate(LedPin,  0, 100);

La funzione serve per utilizzare il software per creare un pin PWM, LedPin, quindi l’ampiezza iniziale dell’impulso è impostata su 0 e il periodo di PWM è di 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 canale 0 che è stato collegato a un potenziometro. E memorizza il valore nella variabile analogVal, quindi scrivilo in LedPin. Ora puoi vedere la luminosità del LED cambiare in base al valore del potenziometro.

Immagine del fenomeno

../_images/image181.jpeg