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.
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.
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.
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.
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).
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 |