Potenziometro digitale a controllo analogico

Questo articolo propone un circuito in grado di controllare il valore di un potenziometro digitale partendo da una semplice tensione analogica.

Il circuito proposto permette di variare la resistenza di un potenziometro digitale, utilizzando una tensione analogica esterna. Come è immediato intuire, sarà necessario convertire la tensione analogica in un valore digitale, per questo dovremo utilizzare un ADC. Poiché il potenziometro digitale preso in considerazione è dotato di un'interfaccia I2C, sarà necessario anche un microcontrollore per comandarlo. Niente di più sensato, quindi, di scegliere un microcontrollore che abbia integrato un convertitore ADC. La scelta è caduta sul PIC12F683 della Microchip. Il PIC converte la tensione analogica ottenuta dall’ADC in flusso I2C per il potenziometro digitale che è un DS1803 della Maxim.

SCHEMA ELETTRICO

Lo schema del circuito proposto è mostrato in Figura 1.

Figura 1: schema del circuito per controllare con una tensione analogica un potenziometro digitale.

Figura 1: schema del circuito per controllare con una tensione analogica un potenziometro digitale

Il microcontrollore è dotato di 6 pin, di questi, quattro sono utilizzati: due controllano le linee SDA (system-data) e SCL (system-clockline) dell’I2C, uno controlla un LED e l’ultimo accetta la tensione analogica in ingresso. Le linee SDA e SCL sono collegate direttamente al potenziometro digitale e hanno una resistenza di pull-up da 4.7 kohm verso la tensione di alimentazione. Se per caso il circuito prevede alimentazioni diverse per la parte relativa al potenziometro digitale, ovviamente le linee I2C dovranno avere i pull-up verso tale tensione.

Figura 2: schema a blocchi del PIC12F683.

Figura 2: schema a blocchi del PIC12F683

In Figura 2 è riportato lo schema a blocchi interno del PIC12F683, in particolare, in Figura 3 è possibile osservare la parte relativa all’ADC. La sorgente di segnale da portare in ingresso all’ADC può essere selezionata dai pin GP0, GP1, GP2 o GP4. Il valore di CHS decide quale segnale arriva in ingresso. La tensione di riferimento per l’ADC può provenire dall’esterno, dal pin GP1, oppure si può utilizzare la tensione di alimentazione. Il risultato della conversione è una parola a 10 bit che può essere allineata a piacere per prelevare tutti i bit o solamente gli 8 più significativi.

Figura 3: schema a blocchi dell’ADC interno al PIC12F683.

Figura 3: schema a blocchi dell’ADC interno al PIC12F683

FIRMWARE

Il firmware per il circuito è scritto in linguaggio Assembly, utilizzando il programma Microchip MPLAB IDE (versione 7.40), disponibile gratuitamente sul sito web. Il programma occupa solamente 450 Byte di Flash per il programma, e 8 byte di spazio dati in RAM. La sequenza delle operazioni prevede prima l’inizializzazione dei vari bit di configurazione per il PIC, necessari per settare correttamente l’ADC e l’oscillatore interno. L’ADC viene programmato per accettare in ingresso il segnale del pin GP1, e il clock per la conversione utilizza l’oscillatore interno programmato a 125 kHz. Il firmware successivamente esegue continuamente un ciclo che prevede la conversione del segnale analogico in ingresso, il prelievo degli 8 bit più significativi del convertitore ADC (che è a 10 bit) e il loro invio tramite il bus I2C. Il bus I2C è utilizzato per controllare il potenziometro digitale DS1803, in realtà come si può vedere dalla Figura 4 estratta dal datasheet, il DS1803 ha al suo interno due potenziometri. Il firmware li gestisce entrambi, con una piccola modifica è possibile pilotarli in maniera separata, sfruttando eventualmente due ingressi diversi sul PIC. Il programma permette all’utente di controllare il potenziometro variando la tensione sul pin GP1 in ingresso al PIC12F683. Una variazione continua della tensione su GP1 si traduce allo stesso modo in una variazione continua della resistenza del potenziometro. Si può decidere di calcolare la resistenza di uscita ROUT in funzione della tensione in ingresso. Per il DS1803 la resistenza massima è di 50 kohm, la tensione di alimentazione VCC varia da 2.7 fino a 5V, la tensione di ingresso VI, quindi, varierà tra 0 e VCC. La resistenza di uscita sarà quindi:

ROUT (kohm) = (50/VCC) x VI

Durante il normale funzionamento del circuito, il led lampeggia costantemente, nel caso rimanga acceso significa che si è verificato un errore sul bus I2C. Una volta corretto l’errore, il funzionamento del LED si ripristina. Solitamente gli errori che si possono manifestare sono relativi al corretto indirizzamento del DS1803 sul bus I2C e al corretto collegamento del bus stesso.

Figura 4: schema a blocchi interno del DS1803.

Figura 4: schema a blocchi interno del DS1803

POSSIBILI APPLICAZIONI

Il principio di questo circuito si può estendere ad altre applicazioni dove una tensione analogica controlla un dispositivo con interfaccia I2C. Per esempio, è possibile implementare una funzione di trasferimento non lineare, come la correzione di gamma, in questo caso conviene utilizzare il DS3906 come resistenza variabile e implementare la funzione di trasferimento attraverso delle tabelle di look-up in memoria. In alternativa, è possibile collegare anche un termistore in ingresso al PIC, questo piloterà un DAC controllato via I2C in risposta ai cambiamenti della temperatura ambientale (Figura 5).

Figura 5: l’uscita del DAC varia in base alla temperatura ambiente rilevata.

Figura 5: l’uscita del DAC varia in base alla temperatura ambiente rilevata

FIRMWARE

Il Listato 1 riporta un estratto del codice reperibile anche sul sito web della MAXIM IC. Il codice riportato è relativo al main loop del programma.

;MAIN LOOP THAT CHECKS THE ADC AND MAKES NECESSARY CHANGES
LOOP
 call                         DELAY_MS
 LED2HIZ
 bsf                         ADCON0,GO ;Initialize new A/D conversion
 btfsc                       ADCON0,GO ;Wait for conversion to complete
 goto                            $-1
;MAKE ADC DATA BYTE FOR SENDING USING THE TOP 8 BITS OF 10 BIT ADC
 banksel                         STATUS
 bcf                             STATUS,0
 banksel                         ADRESH
 rlf                             ADRESH,1
 rlf                             ADRESH,1
 rlf                             ADRESH,1
 rlf                             ADRESH,1
 rlf                             ADRESH,1
 rlf                             ADRESH,0
 banksel                         ADC_DATA_BYTE
 clrf                            ADC_DATA_BYTE
 iorwf                           ADC_DATA_BYTE,1
 banksel                         STATUS
 bcf                             STATUS,0
 banksel                         ADRESL
 rrf                             ADRESL,1
 banksel                         STATUS
 bcf                             STATUS,0
 banksel                         ADRESL
 rrf                             ADRESL,0
 ;xorlw                          0xC0
 banksel                         ADC_DATA_BYTE
 iorwf                           ADC_DATA_BYTE,1
I2C_ SEQUENCE
 call                           I2C_START                ;start
 I2C_ERROR_TEST                           ;Macro that tests I2C is working
or not
 movlw                          CONTROL_BYTE_W
 banksel                        I2C_WORD
 movwf                          I2C_WORD
 call                           I2C_WRITE               ;CONTROL BYTE
 I2C_ERROR_TEST                      ;Macro that tests I2C is working or not
 banksel                        COMMAND_BYTE
 movf                           COMMAND_BYTE, W
 banksel                        I2C_WORD
 movwf                          I2C_WORD
 call                           I2C_WRITE               ;COMMAND BYTE
 I2C_ERROR_TEST                      ;Macro that tests I2C is working or not
 banksel                        ADC_DATA_BYTE
 movf                           ADC_DATA_BYTE, W
 banksel                        I2C_WORD
 movwf                          I2C_WORD
 call                           I2C_WRITE               ;POT DATA
 I2C_ERROR_TEST                     ;Macro that tests I2C is working or not
 call                           I2C_STOP                ;stop
 call                           DELAY_MS
 LED2DVR
 goto                           LOOP
Listato 1
Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend