Cerberus + MCP4131

Richieste di supporto in merito a problemi su hardware e firmware

02/12/2012 11:27:24
Gravatar
Totale Interventi 7

Cerberus + MCP4131

Salve a tutti,

sto cercando di interfacciarmi con un MCP4131 Potenziometro digitale che supporta l'interfaccia SPI.

Riporto il codice:

Cpu.Pin _csPin = GT.Socket.GetSocket(5, true, null, null).CpuPins[6];

SPI.Configuration MCP4131_Config = new SPI.Configuration(
_csPin, false, 0, 0, false, true, 800, SPI.SPI_module.SPI1);

SPI MCP4131_SPI = new SPI(MCP4131_Config);

byte[] rx = new byte[2];

MCP4131_SPI.WriteRead(new byte[2] { 0x0F, 0xFF }, rx); //Leggo il valore attuale del potenziometro
Debug.Print(rx[0].ToString());
Thread.Sleep(200);

MCP4131_SPI.WriteRead(new byte[2] { 0x00, 0x04 }, rx); //setto un valore
Thread.Sleep(200);

MCP4131_SPI.WriteRead(new byte[2] { 0x0F, 0xFF }, rx); //Leggo il valore attuale del potenziometro
Debug.Print(rx[0].ToString());

 

L'output del codice precedente è:

0

128

Il valore 128 dovrebbe essere quello di fondo scala quando invece io ho settato "0x04".

Qualcuno ha provato ad interfacciare questo componente o sa comunque darmi una mano?

Daniele

 

02/12/2012 13:19:54
Gravatar
Totale Interventi 75

Re: Cerberus + MCP4131

Ciao.

Sì, ho lavorato con quel componente e mi sembra di poter dire che il problema sta nel protocollo, dal momento che ad esempio il "comando" di scrittura della resistenza da impostare sia ad esempio lo 0x11 e non lo 0x00 come nel tuo esempio.

Ad ogni modo la classe che ho utilizzato l'ultima volta che ci ho fatto un po' di sperimentazione è la seguente:

public class MCP41010DigiPot
    {
        SPI _spi;
        SPI.Configuration _spiConfig;
        byte _potVal = 0;

        public byte PotValue
        {
            get { return _potVal; }
            set { _potVal = value; setPotValue(value); }
        }

        public MCP41010DigiPot(SPI.Configuration spiConfig)
        {
            _spiConfig = spiConfig;
        }

        void setPotValue(byte potVal)
        {
            _spi.Write(new byte[] { 0x11, potVal });
        }

        public void Shutdown()
        {
            _spi.Write(new byte[] { 0x21, 0x0 });
        }

        public void Init()
        {
            _spi = new SPI(_spiConfig);
        }
    }

Come test puoi usare un Program.cs del tipo:

public static class Program
    {
        static MCP41010DigiPot _digiPot;

        public static void Main()
        {
            Debug.EnableGCMessages(false);

            _digiPot = new MCP41010DigiPot(new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di10, false, 0, 0, false, true, 100, SPI.SPI_module.SPI1));

            _digiPot.Init();

            byte potval = 0;

            while (true)
            {
                Debug.Print("Pot=" + potval);

                _digiPot.PotValue = potval;

                potval += 0x10;

                Thread.Sleep(2000);

                Debug.Print("Shutdown");

                _digiPot.Shutdown();

                Thread.Sleep(1000);
            }
        }
    }
02/12/2012 16:55:00
Gravatar
Totale Interventi 7

Re: Cerberus + MCP4131

Studiando il codice che hai postato ho provato a settare 100 KHz al posto dei miei 800 e qualcosa sembra cambiare!

 

usando 0x00 o 0x11 ottengo lo stesso risultato eseguendo il seguente codice:

Cpu.Pin _csPin = GT.Socket.GetSocket(5, true, null, null).CpuPins[6];

SPI.Configuration MCP4131_Config = new SPI.Configuration(
_csPin, false, 0, 0, false, true, 100, SPI.SPI_module.SPI1);

SPI MCP4131_SPI = new SPI(MCP4131_Config);

byte[] rx = new byte[2];

MCP4131_SPI.Write(new byte[] { 0x11, 0x10 });
Thread.Sleep(100);

MCP4131_SPI.WriteRead(new byte[] { 0x0F, 0xFF }, rx);
Debug.Print(rx[0].ToString() + " - " + rx[1].ToString());
Thread.Sleep(100);

MCP4131_SPI.Write(new byte[] { 0x11, 0x20 });
Thread.Sleep(100);

MCP4131_SPI.WriteRead(new byte[] { 0x0F, 0xFF }, rx);
Debug.Print(rx[0].ToString() + " - " + rx[1].ToString());
Thread.Sleep(100);

Output:

15 - 128
0 - 255 

Non capisco a questo punto se i valori in scrittura sono errati o se l'operazione di lettura legge un'area differente da quella che dovrebbe leggere. Di fatto l'LCD 44780 collegato al potenziometro non cambia il contrasto! In nessuna delle prove fatte!

02/12/2012 17:21:49
Gravatar
Totale Interventi 75

Re: Cerberus + MCP4131

Ho riguardato il datasheet del componente e sulla sezione del protocollo ho visto che in effetti non è previsto alcun modo per leggere il contenuto dei registri; in altri termini è write-only (sì, è vero che ci sono sia i pin SI che SO, ma quest'ultimo serve solo per il daisy-chaining di più MCP4131) e probabilmente quello che leggi è di fatto quello che hai scritto "8 bit prima".

Ad ogni modo, se è fattibile, proverei a verificare con il tester se effettivamente la resistenza ai capi dei pin PA0-PW0 (o PW0-PB0) del potenziometro digitale cambia nel momento in cui setti i valori con le transazioni "MCP4131_SPI.Write(new byte[] { 0x11, (byte)resistenza });".

02/12/2012 20:44:40
Gravatar
Totale Interventi 7

Re: Cerberus + MCP4131

Sicuro che non ci siano?

a pagina 48 del pdf che ho io trovo tutta la tabella con i comandi, non sono questi?

Datasheet MCP4131

03/12/2012 09:11:26
Gravatar
Totale Interventi 75

Re: Cerberus + MCP4131

Effettivamente il datasheet che ho io è relativo alla versione 41XXX-42XXX del componente. Sulla scheda che ho poi ho verificato di avere un modello diverso dal tuo, il MCP41010, in effetti.

Guardando il datasheet giusto, vedo che le transazioni di lettura e scrittura sono a 16 bit, per cui se usi l'overload del metodo Write o ReadWrite che utilizza gli array di byte .NETMF non mantiene il CS "attivo" (basso in questo caso) tra il primo ed il secondo gruppo di 8 bit "cloccati" (come si vede con un analizzatore di stati logici), il che potrebbe (a seconda di come è implementato il componente) resettare lo stato interno del "digipot".

Ad ogni modo, per impostare la resistenza massima per il wiper 0 (ossia il primo "canale" del digipot) dovrebbe essere sufficiente fare una scrittura dello short 0x03FF, mentre per la minima 0x000. Per la lettura dovrebbe essere sufficiente fare una lettura/scrittura di 0x0800.

Mi fai sapere se va?

04/12/2012 11:15:14
Gravatar
Totale Interventi 7

Re: Cerberus + MCP4131

Ho provato al volo il seguente codice:

MCP4131_SPI.Write(new ushort[] { 0x03FF });

Thread.Sleep(100);

MCP4131_SPI.Write(new ushort[] { 0x0000 });

in effetti la seconda scrittura sembra funzionare in quanto il contrasto del display 44780 è massimo come se collegassi direttamente a GND. Sembra però che qualsiasi tentativo di modificare il valore 0x0000 venga ignorato.

Dal datasheet sembra che un'operazione di scrittura debba avere il seguente protocollo:

4 bit per l'area, 2 per il comando, 10 per l'informazione. 

Nel mio caso l'area è "0000" e il comando di write è "00". In teoria quindi, come da te evidenziato, un comando binario "0000 0011 1111 1111" (0x03FF) dovrebbe settare il potenziometro al valore massimo. Leggo però che il device supporta 129 (0-128) livelli settabili e quindi il valore max hex dovrebbe essere 0x080.

Cerco di fare altre prove appena possibile. 

04/12/2012 11:47:16
Gravatar
Totale Interventi 75

Re: Cerberus + MCP4131

Sì, a pagina 38 dice infatti che a seconda che il dispositivo sia a 7 o a 8 bit il valore massimo è 0x80 o 0x100, ma che valori maggiori mettono comunque a fondo scala...

Rispetto alla situazione di reset quindi vedi cambiare la resistenza quando scrivi 0x0000?

09/12/2012 13:11:41
Gravatar
Totale Interventi 7

Re: Cerberus + MCP4131

Ho fatto un po' di prove ma il risultato (il più delle volte) è che una volta resettato il sistema, qualsiasi scrittura, con qualsiasi valore, imposta il contrasto del display LCD al massimo.

Ho tentato anche con questa classe: 
http://www.tinyclr.com/codeshare/entry/344 

Ma non sembra funzionare. A questo punto potrebbe essere un problema di collegamento:

MCP4131

CS = Socket 5 pin 6
SCK = Socket 5 pin 9
SDI/SDO =  Socket 5 pin 8
Vss = GND
Vdd = +5V
P0B = +5V
P0W = out
P0A = GND 

09/12/2012 15:25:27
Gravatar
Totale Interventi 75

Re: Cerberus + MCP4131

Dove dici SDI/SDO Socket 5 Pin 8 intendi SDI->Socket 5 Pin 7 e SDO->Socket 5 Pin 8, vero?