Manual
do
Maker
.
com
Dessa vez vamos ver algo sobre o ADS1115, introduzindo o artigo do ADS1115 com Arduino, depois com ESP8266 e Raspberry. Primeiramente com Arduino porque é o mais simples, já tem biblioteca pronta e não há muito o que se pensar.
O ADS1115 é um ADC (conversor analógico-digital) de alta resolução. Esse modelo possui 16 bits de resolução, abrindo um leque de 65536 valores possíveis em uma leitura, contra 8 bits do Arduino UNO. Ou seja, esse conversor pode lhe dar muito mais precisão do que o ADC do Arduino, mas ele é muito mais útil ainda para interfacear com o ESP8266 que só tem 1 entrada analógica (que suporta no máximo 1V no pino) e muito mais útil ainda no Raspberry, que não possui conversor ADC.
Ele opera entre 2 e 5V, de modo que é compatível com Arduino, ESP8266, Raspberry, MSP432, Onion Omega, Carambola, etc.
O barramento de comunicação desse dispositivo é I²C, possibilitando assim uma rede com mais dispositivos do mesmo tipo ou com outros, como por Exemplo, o PCF8574, exibido em 2 artigos anteriores. Com ambos, você consegue expandir tanto as portas analógicas quanto as portas digitais, facilitando a integração com ambientes mais complexos.
O ADS1115 é endereçável, e isso lhe permite agregar mais dispositivos do mesmo tipo no barramento I²C e assim expandir ainda mais as leituras analógicas.
Seu endereçamento tem 7 bits de comprimento e você pode selecionar qual endereço utilizar da seguinte maneira:
Hex | bin | conect |
0x48 | 1001000 | ADR ao GND |
0x49 | 1001001 | ADR ao VDD |
0x4A | 1001010 | ADR ao SDA |
0x4B | 1001011 | ADR ao SCL |
A apresentação da Adafruit mostra o wiring. Basicamente VCC, GND e os GPIOs SDA e SCL.
Além disso, nesse documento você tem o link para a biblioteca e exemplos de uso. A biblioteca é bastante completa e sem dúvida satisfará suas expectativas. Como o documento é completo e tem inclusive exemplo de código, não vou me repetir, deixo apenas a referência e parto agora para o ADS1115 com ESP8266.
As informações detalhadas você encontra no datasheet (como sempre).
A leitura da word vem invertida, isto é, se você leu um valor 0x3412, isso é 0x1234. Sabendo disso previamente, podemos criar uma função que coloque o valor na devida ordem:
def invertWord(val):
return ((val&0xff)<<8)+(val>>8)
O primeiro byte enviado pelo master deve ser o endereço do ADS1115. O endereço pode ser obtido através de um scan no barramento, Seguidamente, deve ser enviado o segundo byte, que é o ponteiro para o registrador (que pode ser observado no datasheet supracitado).
Eu sei que isso pode parecer complicado, mas servirá como referência quando tudo estiver claro. Adiante, o terceiro e o quarto byte são escritos no registrador indicado no segundo byte. Todas as transações entre o master e o ADS1115 devem ser precedidas pela condição de start e finalizada com a condição de stop.
Vamos iniciar com a primeira configuração, que é a conversão em modo continuo; isto é, tão logo uma conversão esteja pronta, outra é iniciada.
Seu outro modo de operação é ler e dormir em intervalos, mas vou me ater ao mais breve possível.
Primeiro byte: 144
Se refere aos 7 bits do endereço I²C seguido pelo bit de low para read/write.
Segundo byte: 1
Apontamento para o registrador de configuração.
Terceiro byte: 132
MSB do registrador de configuração s ser escrito.
Quarto byte: 131
LSB do registrador de configuração a ser escrito.
Primeiro byte: 144
O mesmo que a primeira escrita do processo anterior.
Segundo byte: 0
Apontamento para o registrador de conversão.
Primeiro byte: 145
Os 7 bits do endereço I²C seguidos pelo bit de leitura/escrita em high agora.
Segundo byte: O ADS responde com a conversão contida no registrador MSB.
Terceiro byte: O ADS respondo com o valor de conversão do registrador LSB.
Isso é o que consta no datasheet, o que parece bastante simples. Em casa não tenho nada conectado ao ADS1115, mas nada me impediu de escrever esses comandos:
Se está correto o procedimento? Bem, você pode escrever em hexa ou binário, não importa. Os primeiros 2 bytes de retorno dessa longa string repletas de 255 são referentes ao valor que supostamente seria lido se tivesse algo pendurado no ADS1115. O caso é que ao ler, passa-se o tamanho desejado de bytes lidos e eu passei 145, mas apenas 2 formavam a word. A questão mesmo é que não consigo comprovar se o processo está certo no ESP8266, mas faça o teste também. Já no Raspberry a história é outra, pois tive que utilizá-lo na empresa.
No Raspberry Pi utiliza-se a tradicional lib SMBus. Também escrito em python, mas com as respectivas diferenças entre o ESP8266 com a machine.I2C e qualquer Linux com SMBus.
Para ficar claríssimo, esse código estou utilizando para medir a tensão de 2 bancos de baterias, através de um divisor resistivo, aplicando então as devidas proporções. Mantenha o foco na leitura do dispositivo, o restante é pertinente ao meu trabalho:
import smbus, time
#racks de baterias
rack_a = 0xe383
rack_b = 0xe3b3
#addr 0x48
#instancia do SMBus. Se for no Onion Omega, troque (1) por (0)
i2cbus = smbus.SMBus(1)
#Faz a inversao quando lendo a word
def invertWord(val):
return ((val&0xff)<<8)+(val>>8)
def voltageReader(rack):
#calibrar
i2cbus.write_word_data(0x48, 0x01, rack)
time.sleep(0.02)
raw = i2cbus.read_word_data(0x48,0x00)
inverted = invertWord(raw)
#0.6 eh uma tolerancia devido ao erro grostesco do resistor em 5%
voltage = (inverted * 0.002625)+0.6
#basta-me 1 posicao flutuante
return round(voltage,1)
def bothRacks():
#retorna uma lista com as leituras dos 2 racks
return [voltageReader(rack_a),voltageReader(rack_b)]
Esse processo para o Raspberry Pi está devidamente homologado, portanto assino embaixo. Já no ESP8266 foi um experimento cheio de suposições, mas se eu tiver algum tempo extra tento fazer algo pro ESP que também possa assinar embaixo!
Inscreva-se no nosso canal Manual do Maker Brasil no YouTube.
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.