Potenciómetro Digital con MCP41010 por SPI

En muchas ocasiones necesitamos controlar algún dispositivo analógico mediante resistencias variables como los potenciómetros, un potenciómetro de carbón como los que habituamos consta de una traza calibrada de carbón donde tendremos los dos extremos y un cursor móvil que sera el que moveremos para variar la resistencia, en algunos casos se moverá de forma rotativa y en otros casos de forma lineal, pero el funcionamiento es siempre el mismo.
Los potenciómetros analógicos poseen algunos problemas como el desgaste por el uso, la suciedad que puede generar ruido en el potenciómetro, muchas veces escuchamos en los controles de volumen un poco de ruido cuando giramos el potenciómetro, en la mayor parte de los casos se debe a la suciedad del mismo.
En cuanto al audio es algo no tan critico, pero si estamos controlando algún dispositivo de instrumentación o de sintonizador de radio, tener ruido en el potenciómetro es algo que nos juega en contra.
En esta nota veremos como reemplazar un potenciómetro analógico por uno digital que tendrá que ser controlado desde un microcontrolador ya que el mismo requiere un bus SPI para su control.
Existen otros potenciómetro digitales que no necesitan de un MCU, sino que tienen pines dedicados a pulsadores para hacer Up y Down (por ejemplo DS1669).
Elegir un potenciómetro con SPI en lugar de uno como el DS1669, tiene dos aspectos, el primero debería ser el funcional ya que controlar el mismo desde un MCU nos proporciona mas opciones ya que podremos controlar mas factores aparte del potenciómetro, y también el costo, en este caso un DS1669 es mucho mas costoso que el MCP41010 + un MCU.

Existen otros métodos para hacer un potenciómetro digital en base a resistencias y multiplexores, eligiendo distintos valores de resistencia en función del canal seleccionado del multiplexor, pero es un método un poco ruidoso e inexacto.

El potenciómetro digital tiene algunas limitaciones respecto del convencional, por ejemplo la tensión que podremos hacer circular por el mismo.
Recordemos que la corriente tanto en el digital como en el analógico debe estar calculada y limitada ya que podríamos romper el potenciómetro ya sea este digital o uno analógico convencional.
Pero la tensión en uno analógico podría ser muy elevada sin problemas.
En el digital tendremos un arreglo de mosfet en su interior que serán los que hacen las veces de resistencia, esto quiere decir que tendremos limitaciones eléctricas para su uso. 
En el caso del MCP41010 tendremos una tensión máxima a aplicar en el potenciómetro que sera igual a la VDD de alimentación.
Claramente son solo 5V, pero en la mayoría de las aplicaciones donde pondremos un potenciómetro de este estilo utilizaremos menos de 5V.

Una aplicación muy común de este potenciómetro es la de controlar la ganancia de realimentacion de un amplificador operacional, es decir, RF (Resistencia de Feedback) podrá ser controlada por el MCP41010 y así podremos variar la ganancia, luego el amplificador esta donde ustedes requieran.
También podríamos utilizar este potenciómetro digital para variar la tensión de offset de un operacional y así modificara de forma digital o automática.
Podríamos realizar un AGC (control automático de ganancia) usando una entrada del ADC del MCU mas la salida de este potenciómetro podríamos controlar la ganancia de un sistema.
También podemos controlar la polarizacion de un DiodoVaricap que podría estar en configuración Tanque con un oscilador y asi sintonizar un transmisor o receptor de radio.
Claramente hay muchas aplicaciones que dependerán de lo que ustedes requieran y en estos ejemplos nunca llegamos a los 5V.

El MCP41010 es un potenciómetro simple digital de 10k aunque también los hay de 50k y de 100k, tendremos que elegir el que necesitemos para nuestro proyecto.
También existe la seria MCP42XXX que serán dos potenciómetros en el mismo encapsulado.



Este potenciómetro tendrá 256 niveles de resistencia, es decir, setearemos entre 0 y 255, en el caso del potenciómetro de 10k serán saltos de 39 Ohms, Pero hay que tener en cuenta que hay un margen de error para este, en mi caso mide de 100Ohms hasta unos 9k, por ende los saltos serán diferentes.




El integrado posee en su interior una memoria EEPROM que servirá para almacenar la ultima posición del potenciómetro, es decir si apagamos nuestro dispositivo y lo encendemos nuevamente, tendrá que mantener el ultimo nivel de resistencia seteado.

El mismo posee con tres pines de datos para el Bus SPI que serán CS, SCK y SI, luego los pines de alimentación VSS y VDD (entre 2.7V y 5.5V) y por ultimo los del potenciómetro que serán PA0, PW0 y PB0, siendo PA0 y PB0 los extremos del potenciómetro y PW0 el cursor o toma central del mismo.



Para manejar el Bus SPI tendremos dos opciones, utilizamos el SPI por hardware que trae el microcontrolador o realizamos BitBanging (el protocolo a mano por software).
En mi caso he optado por la segunda opción ya que hace el código mas portable para otras plataformas.

Circuitos de aplicación de la hoja de datos:







Ahora tendremos que analizar la trama SPI que necesitamos para controlar este dispositivo.
A diferencia del I2C que este tiene solo dos hilos, donde uno sera el Clock SCL y el otro el Dato SDA, pero tanto el maestro como el esclavo deben comunicarse, esperar los ACK de comunicaciones, poner pines como entrada/salida según demanda, etc...
Aquí tenemos un hilo mas que nos facilita los datos, ya que tenemos uno de entrada uno de salida y uno de clock, MISO, MOSI y SCLK. (También tenemos un pin SS de selección pero que podremos obviarlo en algunas aplicaciones).

La trama es básicamente habilitar el bus, para eso pondremos a nivel bajo CS del MCP41010, luego enviaremos los bits de forma serial (en este caso serán 2 byte, uno para la dirección y otro para el valor) cada envió serie sera acompañado de un clock (sube y baja) y una vez terminado pondremos a nivel alto la habilitación del bus CS del MCP41010 para terminar la transacción.

Tendremos dos direcciones para el MCP41010, la 0x11 que sera para poner el dato en el potenciometro y la 0x21 que sera la dirección de la EEPROM interna para guardar el dato. Si guardamos el dato lo podremos recuperar cada vez que apeguemos y prendamos el circuito. En mi ejemplo no lo he utilizado pero podrían implementarlo sencillamente.




El programa:


  1. #include <16F883.h>
  2. #FUSES HS
  3. #FUSES MCLR
  4. #use delay(clock=4000000)
  5. #use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, parity=N)
  6. #define CS   PIN_B2
  7. #define SCLK PIN_B1
  8. #define SI   PIN_B0
  9. void setPote(int valor)
  10. {
  11.    int8 i;
  12.    int8 palabra[2];
  13.    palabra[0]=valor;
  14.    palabra[1]=0x11;        //Posicion 0x11 asigna el valor, 0x21 guarda el valor
  15.    output_low(SCLK);
  16.    output_low(CS);
  17.    for(i=1;i<=16;++i) {
  18.       output_bit(SI, shift_left(palabra,2,0));
  19.       output_high(SCLK);
  20.       output_low(SCLK);
  21.    }
  22.    output_high(CS);
  23. }
  24. int8 valPote=0;
  25. void main()
  26. {
  27.    printf("Listo!\r");
  28.    while(true){
  29.       if(input(PIN_C0)==1)
  30.       {
  31.          if(valPote<255)
  32.          {
  33.             valPote++;
  34.             setPote(valPote);
  35.             printf("valPote: %3u \r",valPote);
  36.          }
  37.       }
  38.       if(input(PIN_C1)==1)
  39.       {
  40.          if(valPote>0)
  41.          {  
  42.             valPote--;
  43.             setPote(valPote);
  44.             printf("valPote: %3u \r",valPote);
  45.          }
  46.       }
  47.    }
  48. }

En el programa he agregado la comunicación UART para poder ver el valor en el terminal a medida que lo vamos modificando.
Todo lo correspondiente al bus SPI lo hace la función setPote() que se ha definido en el principio del programa donde utilizamos un vector de dos posiciones que alojara la dirección del MCP41010 (en este caso 0x11) y el valor a enviar al potenciómetro de forma dinámica.
Luego ponemos a LOW el Clock y la Habilitación.
Realizamos la iteración de los 2 Byte a enviar (las 16 iteraciónes), por cada iteración se moverá el dato hacia la izquierda realizando un shitregister que saldrá bit a bit por la salida de Datos.
Por cada iteración también tendremos que realizar un ciclo de Clock por ello ponemos a HIGH y luego a LOW el Clock.
Una vez finalizada las 16 iteración ponemos a nivel HIGH la habilitación y retornamos de la función.
Luego el programa principal realiza polling de dos pulsadores para para hacer un Up y un Down del potenciómetro mediante valPote-- y valPote++.

El circuito de prueba:








6 comentarios:

  1. Buenas tardes. Muy buen aporte. Me ayudaría saber como puedo recoger el valor en el cual se encuentra el digipot. Ese valor que se supone guarda en la emprom. Cuando lo enciendo.... Como puedo leer esto?. Gracias

    ResponderBorrar
  2. calidad muchas gracias. pero hay seis imagenes que no se ven.

    ResponderBorrar
  3. me gustaría tener el diagrama del circuito

    ResponderBorrar
  4. Me gustaría tener el programa para arduino por favor. Gracias y buen video.

    ResponderBorrar
  5. PARA UNA FUENTE REGULADA 30V 10A CUALS ERIA EL INTEGRADO IDEAL (POTENCIOMETRO)

    ResponderBorrar