quinta-feira, 10 de julho de 2014

Conectando o ADC MCP3008 ao Raspberry Pi para leitura de sensores analógicos, etc.

MCP3008 PDIP
MCP3008 PDIP, créditos Adafruit

Um dos recursos que algumas pessoas sentem falta no Raspberry Pi é um ADC ( Conversor analógico digital ), quem está acostumado a mexer com Arduino deve ter reparado ou usado os pinos que vão de A0 à A5, que normalmente utilizam para conexão de sensores analógicos, apesar de se ter vários usos. Quem faz esse trabalho de leitura no Arduino é o ADC interno do chip Atmega.

No caso do Raspberry Pi não temos um ADC acessível, sendo preciso a utilização de uma placa de expansão ou um ADC externo. Existe ainda outras possibilidades, em alguns casos a utilização de uma "gambiarra" via capacitor como demonstrado no site adafruit é possível, mas que não terá a precisão de um ADC. Outra seria a utilização do ADC interno de chips Atmega ou PIC ligados ao Raspberry Pi por meio de comunicação serial.


Hoje o ADC mais comum que vejo utilizarem no Raspberry Pi é o MCP3004 ou MCP3008. Eles estão disponíveis no invólucro( em inglês, conhecido como package ) PDIP, de possível utilização em uma protoboard. Ambos fabricados pela Microchip, a diferença entre eles está na quantidade de canais e invólucros disponíveis, sendo o MCP3004 de 4 canais em invólucros PDIP, SOIC, TSSOP e o MCP3008 de 8 canais em invólucros PDIP e SOIC.

Para utilização da maioria o PDIP é o recomendável. No meu caso eu comprei um de invólucro SOIC na Aliexpress, pois estava mais barato do que o PDIP na época, a US$1,77. O problema dos outros invólucros como o SOIC é que além de ser preciso soldar, eles são SMD e muito pequenos.

MCP3008 SOIC
MCP3008 SOIC

As especificações básicas do MCP3008 são as seguintes:

- 8 canais
- 10 bits de resolução
- Tensão de operação: 2.7V - 5.5V
- Amostragem máxima de 200ksps em 5V ou 75ksps máximo em 2.7V
- Comunicação SPI

Como a tensão de operação está entre 2.7V e 5.5V iremos utilizar a mesma tensão dos GPIOs do Raspberry Pi, que é de 3.3V.

Olhando no esquemático temos os seguintes pinos:

Pinos do MCP3008
Pinos do MCP3008

As ligações com o Raspberry Pi serão feitas da seguinte forma:

Vdd -> 3.3v
Vref -> 3.3v
AGND -> GND
CLK -> SCLK( pino 23 )
Dout -> MISO( pino 21 )
Din -> MOSI( pino 19 )
CS/SHDN -> CE0( pino 24 )
DGND -> GND

O pino Vdd trata-se da alimentação do circuito, o Vref é a tensão de referência na leitura analógica, essa tensão pode ser diferente da Vdd, entretanto no nosso caso utilizaremos a mesma. Os pinos CLK, Dout, Din são respectivamente pino de clock, data input e data output do SPI. O pino CS/SHDN é usado para indicar comunicação com o chip quando em LOW ou caso contrário colocar em modo de baixo consumo( standby ) com HIGH.

Ligações do MCP3008 ao Raspberry Pi
Ligações do MCP3008 ao Raspberry Pi

Todos os pinos do outro lado do chip que não estão ligados são os analógicos. Atenção à posição do chip, que pode ser diferenciada por uma bolinha, ponto, etc. na ponta do mesmo.

Na parte de software para scripts ou testes podemos utilizar a ferramenta "gpio" da biblioteca wiringPi, ela conta com uma extensão para o chip mcp3004 mas que pode ser utilizado também para o mcp3008.

Caso ainda não tenha ela instalada, baixe a biblioteca utilizando o GIT:

$ git clone git://git.drogon.net/wiringPi

Caso não tenha o git instalado:
$ sudo apt-get install git-core

Entre no diretório wiringPi e rode como root ou sudo:

$ cd wiringPi
$ sudo ./build

Esse comando irá compilar e instalar automaticamente a biblioteca.


Todos os testes foram realizados no Raspbian e Raspberry Pi modelo B rev 2.0.

Para utilização é preciso carregar a extensão spi:

$ gpio load spi

E a leitura é feita com o seguinte comando:

$ gpio -x mcp3004:100:0 aread 100
1012

Essa leitura que fiz trata-se somente de um resistor de 10K ligado entre o primeiro pino analógico e o VCC, tendo seu valor quase o máximo dos 10 bits.

Nos parâmetros, 100:0 são da própria extensão, o primeiro "100" é o pinbase, o valor base para acessar o pino do ADC, ou seja, se você tem um base de valor 100, seu primeiro pino analógico será 100, o segundo 101 e assim por diante, o segundo argumento é o canal SPI. O argumento após o aread( analog read ) é o pino que desejamos ler levando em conta o valor base. Notei que o valor base mínimo é de 64, apesar de não achar escrito explícito em algum local, o que parece é que esse limite serve para não confundir com os pinos do próprio Raspberry Pi.

Caso queira ou precise lidar com programação para a leitura, é possível utilizar também a própria biblioteca wiringPi para isso.

Um simples programa em C que fizesse a leitura sem parar a cada 500ms seria da seguinte forma:



Salve com nome mcp3008.c, e compile com:

$ gcc mcp3008.c -lwiringPi -o mcp3008

Os valores 100 no código são o valor base explicado anteriormente.

Para fazer a leitura ao girar um potenciômetro, o conectamos como um divisor de tensão da seguinte maneira.

Potenciômetro
Potenciômetro

Ou para utilizar um LDR.

LDR

Quanto ao chip em invólucro SOIC que comprei, optei por soldar fios diretamente à ele e ficou da seguinte maneira:

MCP3008 SOIC SMD com fios
MCP3008 SOIC SMD com fios

Para não poluir esse post com muitas imagens, em um próximo post coloquei algumas imagens dos passos que segui para soldar e criar um invólucro final de proteção.

O MCP3008 assim como sua outra versão de 4 canais são hoje de fácil utilização. Diversos outros ADCs são passíveis de utilização caso esse não te atenda, a questão fica talvez com o suporte de bibliotecas que facilitem o uso e que caso não o tenha terá que programar manualmente.

Referência:
http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf
Imagem: http://www.adafruit.com/images/1200x900/856-01.jpg

9 comentários:

  1. Este comentário foi removido pelo autor.

    ResponderExcluir
  2. Vou começar dizendo que sou novato em eletrônica e no raspberry.
    Em seu artigo você pede para rodar "sudo apt-get install git-core" e após:
    Entre no diretório e rode como root ou sudo:
    ./build
    Só que eu não sei em que diretório você se refere.

    Obrigado.

    ResponderExcluir
    Respostas
    1. Olá, o diretório que me refiro é o "wiringPi", utilizando "cd wiringPi" para entrar nele. Atualizei o post para ficar mais claro, qualquer dúvida só falar, feedbacks são bem vindos!

      Excluir
  3. EverPi.
    Você fez um exemplo de aplicação em C. Poderia fazer outro em Phiton3.
    Desde já agradeço pela atenção.

    ResponderExcluir
    Respostas
    1. Olá Fernando, procure pelo código da adafruit para o mcp3008, eles tem uma versão em python.

      Excluir
  4. EverPi,
    Estou usando esse mesmo ci e um rasp pi3. Consegui ler a variação dos valores de AD com o potenciometro. Contudo, estou tentando usar aqueles sensores não invasivos de corrente feitos pra arduino que necessitam da biblioteca emonlib.
    Minha dúvida é, se você já fez algo relacionado a usar a biblioteca de arduino no rasp, pois estamos lendo um valor que corresponde de 0 a 1023 mas não sabemos quanto ele equivale. Qualquer link é bem vindo!
    Obrigado!

    ResponderExcluir
  5. Depois de expandir as portas SPI com um MCP23S17, como posso ligar um MCP3008 no MCP23S17? Desejaria conhecer um tutorial com a pinagem e script em Python3. Abr.

    ResponderExcluir
  6. Poderia me dizer como faço para utilizar, por exemplo, 4 entradas do mcp3008 em single ended com cada entrada tendo uma fonte diferente? Quando tento fazer isso somente tenho a resposta da entrada CH0. Utilizo um programa escrito em C.
    Obrigado.

    ResponderExcluir
  7. Boa tarde
    Gostaria de saber qual a resolução dos pinos em bits do raspberry pi3

    ResponderExcluir