Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

Controle um potenciômetro digital via SPI

Neste tutorial, você aprende como controlar o potenciômetro digital AD5206 via SPI. Para uma explicação sobre a SPI, consulte o tutorial da EEPROM SPI. Os potenciômetros digitais são úteis para quando é necessário variar a resistência elétrica em um circuito de forma eletrônica e não manual. Exemplos de aplicações que se utilizam disso são o controle do brilho de LEDs, o condicionamento de sinal de áudio e a geração de tons. Neste exemplo, usamos um potenciômetro digital de seis canais para controlar o brilho de seis LEDs. Os passos dados para implementar a comunicação SPI podem ser modificados para o uso com outros dispositivos SPI.

Materiais necessários

    * Potenciômetro digital AD5206
    * Placa Arduino
    * 6 LEDs
    * Fios

Introdução ao potenciômetro digital AD5206

Descrição da pinagem do AD5206
Núm. PinoNomeDescrição
1A6Terminal A do pot. 6
2W6Cursor do pot. 6, endereço b101
3B6Terminal B do pot. 6
4GNDTerra
5/CSChip Select, ativo em LOW. Quando o /CS retorna HIGH, os dados no registrador de entrada serial é decodificado com base nos bits de endereçamento e carregado no latch do pot. correspondente
6VDDAlimentação, pode ser em 5 V ou 3 V (obs.: |VDD| + |VSS| < 5,5 V)
7SDIEntrada de dados seriais. Bit mais significativo primeiro
8CLKClock, dados amostrados na subida
9VSSAlimentação negativa, pode ser em 0 V ou -2,7 V (obs.: |VDD| + |VSS| < 5,5 V)
10B5Terminal B do pot. 5
11W5Cursor do pot. 5, endereço b100
12A5Terminal A do pot. 5
13B3Terminal B do pot. 3
14W3Cursor do pot. 3, endereço b010
15A3Terminal A do pot. 3
16B1Terminal B do pot. 1
17W1Cursor do pot. 1, endereço b000
18A1Terminal A do pot. 1
19A2Terminal A do pot. 2
20W2Cursor do pot. 2, endereço b001
21B2Terminal B do pot. 2
22A4Terminal A do pot. 4
23W4Cursor do pot. 4, endereço b011
24B4Terminal B do pot. 4

O AD5206 é um potenciômetro digital de 6 canais. Isso significa que possui seis resistores variáveis (potenciômetros) com controle eletrônico individual. Há três pinos no chip para cada um dos seis resistores variáveis e podem ser interfaceados da mesma maneira que você faria com um potenciômetro mecânico. Os pinos de cada um desses resistores variáveis têm o nome Ax, Bx e Wx, p. ex. A1, B1 e W1.

Neste tutorial usamos cada resistor variável como um divisor de tensão, isto é, põe-se um dos pinos (pino B) em HIGH, o outro pino (pino A) em LOW e toma-se uma tensão de saída variável no pino cursor (W).

O AD5206 é controlado digitalmente por meio da SPI. O dispositivo é habilitado quando se aplica LOW no pino Chip Select (CS). Instruções são enviadas a ele na forma de opcodes com 11 bits, sendo que os três bits mais significativos (11-9) definem o endereço do potenciômetro a ajustar-se, enquanto que os oito bits menos significativos (8-1) definem qual o valor a ajustar o potenciômetro (de 0 a 255). Os dados são enfileirados com o bit mais significativo primeiro e são amostrados na borda de subida do clock. Quando em LOW, o clock está parado.

Prepare a protoboard

Insira o chip AD5206 na protoboard. Conecte a alimentação de 5 V e o terra na protoboard e à placa Arduino. Conecte os pinos 3, 6, 10, 13, 16, 21 e 24 do AD5206 aos 5 V e os pinos 1, 4, 9, 12, 15, 18, 19 e 22 ao terra. Fazemos isso para criar seis divisores de tensão.

Conecte o pino 5 do AD5206 ao pino 10 do Arduino (Slave Select - SS), o pino 7 do AD5206 ao 11 do Arduino (Master Out Slave In - MOSI) e o pino 8 do AD5206 ao 13 do Arduino (Serial Clock - SCK).

Finalmente, conecte um LED entre cada pino de cursor (pinos 2, 11, 14, 17, 20 e 23 do AD5206) e o terra, de maneira que o terminal mais longo do LED conecte-se ao pino de cursor e o terminal mais curto do LED ao terra.

Programe o Arduino

Agora escrevemos o código que habilita o controle do AD5206 por SPI. Este programa acende cada LED e então diminui gradualmente seu brilho. Fazemos isso no loop(), mudando as resistências individuais de cada potenciômetro de totalmente desligado para totalmente ligado, ao longo de toda a sua escala de 255 passos. Acompanhe os comentários ao longo do programa.

Definimos os pinos a usar-se para a conexão SPI: DATAOUT, DATAIN, SPICLOCK e SLAVESELECT. Embora não leiamos nenhum dado vindo do AD5206 neste programa, o pino 12 vai ligado ao SPI embutido no Arduino, de forma que é melhor não usá-lo para outras funções, para evitar qualquer erro:

#define DATAOUT     11  // MOSI
#define DATAIN      12  // MISO - não usado, mas faz parte do SPI embutido
#define SPICLOCK    13 // SCK
#define SLAVESELECT 10 // SS


Em seguida, alocamos espaço para as variáveis a guardar os valores de resistência e os valores de endereçamento para os potenciômetros:

byte pot = 0;
byte resistance = 0;


Primeiro ajustamos os modos dos pinos de entrada e saída e configuramos a linha SLAVESELECT para HIGH, para des-selecionar o dispositivo e evitar transmissões falsas de mensagens devidas aos ruído na linha:

void setup()
{
  byte clr;
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); // desabilita dispositivo


Agora dispomos o valor binário 01010000 dentro do registrador SPI Control (SPCR). No registrador de controle, cada bit faz o ajuste de uma funcionalidade diferente. O 8o. bit desabilita interrupções SPI, o 7o. bit habilita a SPI, o 6o. bit diz que bits mais significativos serão enviados primeiro, o 5o. bit põe o Arduino em modo mestre, o 4o. bit comanda que o clock é pausado em nível LOW, o 3o. bit ajusta a SPI para fazer amostragens de dados à subida do clock e os 2o. e 1o. bits ajustam a velocidade da SPI para (mesma do sistema / 4) (que é a mais rápida). Depois de ajustar o registrador de controle, inserimos o valor nos registradores SPI Status (SPSR) e SPI Data (SPDR) dentro da variável clr, para limpar qualquer informação espúria:

  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);

Concluímos o setup() com o ajuste de todos os potenciômetros para resistência máxima e, assim, desligando os LEDs:

  for (i=0;i<6;i++)
  {
    write_pot(i,255);
  }
}

No loop(), iteramos cada valor de resistência (0-255) para cada endereço de potenciômetro (0-5). Pausa-se por 10 milissegundos a cada iteração para que a gradação de brilho seja visível. Isto faz com que os LEDs, sequencialmente, brilhem forte e então desvaneçam-se lentamente:

void loop()
{
     write_pot(pot, resistance);
     delay(10);
     resistance++;
     if (resistance==255)
     {
       pot++;
     }
     if (pot==6)
     {
       pot=0;
     }
}

A função spi_transfer() carrega os dados de saída dentro do registrador de transmissão de dados, o que causa o início da transmissão SPI. Ela vigia, com uma máscara de bits, um bit do registrador SPI Status (SPSR) para detectar se a transmissão foi completada. Uma explicação sobre máscaras de bits pode ser vista aqui?. Em seguida, retorna qualquer dado que tiver chegado a partir do AD5206:

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Começa transmissão
  while (!(SPSR & (1<<SPIF)))     // Espera finalizar
  {
  };
  return SPDR;                    // Retorna o byte chegador
}

A função write_pot() permite-nos controlar os potenciômetros individuais. Ajustamos a linha SLAVESELECT para LOW, para habilitar o dispositivo. Depois, transferimos o byte de endereçamento, seguido por um byte com o valor de resistência. No fim, ajustamos a linha SLAVSELECT de novo a HIGH, para liberar o chip e sinalizar o fim da transmissão:

byte write_pot(int address, int value)
{
  digitalWrite(SLAVESELECT,LOW);
  // opcode de 2 bytes
  spi_transfer(address);
  spi_transfer(value);
  digitalWrite(SLAVESELECT, HIGH); // libera chip, sinaliza fim da transmissão
}