Come usare Arduino per pilotare un potenziometro digitale
Molte applicazioni richiedono la variazione continua di alcuni parametri, come ad esempio un alimentatore, un amplificatore audio, un termostato o un varilight che solitamente impiegano un potenziometro analogico e l’intervento manuale di una persona per effettuare queste variazioni.
Possiamo digitalizzare questi sistemi impiegando lo stesso principio di regolazione basato su potenziometro ma invece di agire fisicamente sulla manopola di regolazione possiamo utilizzare dei comandi software per incrementare decrementare il valore resistivo del potenziometro.
Il componente che andremmo ad usare è l’integrato MCP4131-103 prodotto dalla Microchip. E’ un integrato a 8 pin che possiamo comandare tramite il protocollo seriale SPI.
Al suo interno troviamo un potenziometro da 10Kohm.
Il potenziometro è composto da una rete resistiva composta da 128 elementi il cui valore totale è, nel nostro modello, di 10Kohm. Tramite software possiamo spostare la posizione dello Wiper, che corrisponde al contatto strisciante di un potenziometro meccanico. Gli spostamenti dello Wiper vengono definiti steps e vanno dalla posizione 00H (Wiper collegato al pin P0A) alla posizione 80H(Wiper collegato al pin P0B).
Il potenziometro digitale MCP4131 permette un massimo di 129 steps.
Il datasheet è comune a diversi potenziometri digitali quindi per poter capire quale siano i comandi corretti per pilotare il nostro modello dobbiamo esaminare le parti che ci interessano. La prima sezione riguarda le Caratteristiche del dispositivo (Device Features)
Da questa tabella deduciamo che il dispositivo ha un singolo potenziometro, che i valori della posizione dello Wiper sono memorizzati in RAM (piuttosto che sulla EEPROM). L’interfaccia di comunicazione è SPI, i numeri di Steps sono 129 e il range con cui possiamo alimentare l’integrato va da 1.8Vdc a 5.5Vdc.
L’MCP4131 supporta comandi a 8 bit e a 16 bit. Il comando a 8 bit permette di incrementare o decrementare il valore dello Wiper di uno steps per volta mentre il comando a 16 bit permette di scrivere direttamente sulla RAM il valore della posizione dello Wiper.
Nella figura il comando a 8 bit è composto da 2 bit di dati (che non vengono utilizzati), 2 bit di comando (incremento – decremento) e 4 bit che definiscono l’indirizzo di memoria che vogliamo usare (indirizzo dello Wiper 00h).
Nella figura del comando a 16 bit la prima parte è identica a quella a 8 bit con la differenza che nei 2 bit di comando possiamo specificare se scrivere o leggere dall’area di memoria del dispositivo, i restanti 8 bit compongono il Data Byte che ci permette di indicare direttamente il valore dello Wiper.
Gli indirizzi di memoria disponibili sono i seguenti:
I bit di commando invece sono i seguenti:
Passando alla pratica, se volessi inviare un comando di incremento al Wiper dell’MCP4131, usando la modalità a 8bit, invierei tramite SPI il valore decimale 4
Per decrementare il valore corrente dello Wiper bisogna spedire via SPI il valore decimale 8:
Se volessi spostare il Wiper al centro della sua corsa, utilizzerei la modalità a 16 bit, inviando per primo il dato contenente l’indirizzo di memoria che vogliamo usare e il comando di scrittura
Seguito dal valore della posizione dove vogliamo spostare lo Wiper, in questo esempio il valore 64 decimale (128/2) corrisponde a metà corsa.
Ora che conosciamo come utilizzare il chip possiamo passare alla pratica collegando la porta SPI dell’Arduino all’MCP4131. Nel mio caso ho utilizzato un Arduino Leonardo (la porta SPI è disponibile sui pin dell’header ICSP). Lo schema è il seguente:
L’uscita W è collegata all’ingresso analogico A0 della Leonardo, in questo modo posso misurare il valore di tensione disponibile su tale piedino.
Il Pin B dell’MCP4131, corrispondente alla posizione 00H è collegato a massa mentre il pin A corrispondente alla posizione 80H è collegato alla 5Vdc.
Il codice seguente posiziona lo Wiper nella posizione 00H, ottenendo cosi una tensione pressochè nulla sul pin W (poiche internamente il pin W è collegato con il pin B).
[c]
#include <SPI.h>
void setup()
{
//Definisco il pin come uscita
//il pin 2 viene usato per selezionare il
//chip all’interno di un collegamento SPI
pinMode (2, OUTPUT);
//Inizializzo la libreria SPI
SPI.begin();
//Inizializzo la porta seriale
Serial.begin(9600);
//metto alta la linea CS per
//deselezionare il chip MCP4131
digitalWrite(2, HIGH);
}
void loop()
{
//Inizializzo la posizione dello Wiper
byte Posizione = 0;
//Per selezionare l’MCP4131
//metto basso la linea CS del
//potenziometro digitale
digitalWrite(2, LOW);
//Invio il primo byte per eseguire una scrittura
//sul registro Wiper
SPI.transfer(0);
//Invio il valore della posizione dello Wiper
//valori da 00H a 80H (0-128 in decimale)
SPI.transfer(Posizione);
//metto alta la linea CS per
//deselezionare il chip MCP4131
digitalWrite(2, HIGH);
//eseguo la lettura sul pin analogico A0
//in questo pin è collegato il pin Wiper
//del potenziometro digitale
int Data = analogRead(0);
//spedisco il dato letto al serial Monitor
//Valori da 0 a 1023
Serial.println(Data);
//ritardo di mezzo secondo
delay(500);
}
[/c]
Aprendo il serial monitor otterremmo dei valori prossimi allo zero poichè la tensione in ingresso del pin A0 sarà nulla. Questo è ciò che avviene all’interno dell’MCP4131:
Per posizionare lo Wiper verso il pin A, collegato alla 5Vdc, dobbiamo scrivere sull’indirizzo 00H il valore 80H, come descritto nel codice seguente:
[c]
#include <SPI.h>
void setup()
{
//Definisco il pin come uscita
//il pin 2 viene usato per selezionare il
//chip all’interno di un collegamento SPI
pinMode (2, OUTPUT);
//Inizializzo la libreria SPI
SPI.begin();
//Inizializzo la porta seriale
Serial.begin(9600);
//metto alta la linea CS per
//deselezionare il chip MCP4131
digitalWrite(2, HIGH);
}
void loop()
{
//Inizializzo la posizione dello Wiper
byte Posizione = 128;
//Per selezionare l’MCP4131
//metto basso la linea CS del
//potenziometro digitale
digitalWrite(2, LOW);
//Invio il primo byte per eseguire una scrittura
//sul registro Wiper
SPI.transfer(0);
//Invio il valore della posizione dello Wiper
//valori da 00H a 80H (0-128 in decimale)
SPI.transfer(Posizione);
//metto alta la linea CS per
//deselezionare il chip MCP4131
digitalWrite(2, HIGH);
//eseguo la lettura sul pin analogico A0
//in questo pin è collegato il pin Wiper
//del potenziometro digitale
int Data = analogRead(0);
//spedisco il dato letto al serial Monitor
//Valori da 0 a 1023
Serial.println(Data);
//ritardo di mezzo secondo
delay(500);
}
[/c]
In questo caso aprendo il serial monitor leggeremmo dei valori prossimi a 1023 in quanto sul pin analogico A0 sarà presente la tensione di 5Vdc.
Internamente otterremo questo risultato:
Di conseguenza per avere tutti gli altri valori intermedi potremmo cambiare il valore della variabile Posizione assegnandole valori tra 0 e 128.
Related posts
1 Comment
Lascia un commento Annulla risposta
Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.
Articoli popolari
Sorry. No data so far.
.Net micro framework Arduino Arduino Webserver Domotica Flyport I2C IOT Netduino OpenPicus raspberry RTC Speed Test
Io sto usando l’MCP 4131 da 5k e non funziona, ne ho provati 8 e nessuno funziona.
L’icrementale ed il decrementale non funzionano.
Con lo Sketch che hai pubblicato il potenziometro funziona solamente se imposti nel “data” numeri che in binario hanno tutti “1” esempio se metti 63 (111111) funziona se imposti 62 o 64 il potenziometro non sale e non scende.
Quindi se metti il tester e imposti una scala ad incremento da 0 a 255 vedrai la resistenza che va su a saltoni, lineare fino a 60 ohm circa, poi 1,2k, poi 2,4k e infine 4,8k