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

../_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 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.

../_images/list_2.1.4_potentiometer.png

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

Nome

COMPONENTI IN QUESTO KIT

LINK

Raphael Kit

337

Raphael Kit

Puoi anche acquistarli separatamente dai link seguenti.

INTRODUZIONE AI COMPONENTI

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

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.

../_images/image313.png
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

../_images/image181.jpeg