Hello, TI E2E community,
I'm working on the development of a high-precision voltmeter/ammeter project.
I selected the ADS1115 chip since it features 16 bits of resolution and also because it was available at some local electronic shops in my city. I also decided that the first stage of my project should be the testing of the ADC.
So I bought the ADS1115 module from Adafruit which features the chip itself plus some other components that makes the circuitry implementation even easier. (schematic can be found here: github.com/.../ADS1X15-Breakout-Board-PCBs)
My setup is quite simple. A PIC16F877A communicates with the ADS1115 and 'prints' the readings to a LCD16x2. The ADS1115 chip reads analog voltage from a 10K ohm potentiometer.
The code I'm using in PIC C compiler is shown below and it contains lines of code with the configuration of the chip:
#include <16f877a.h> #fuses XT,NOWDT #use delay(clock=4000000) #include <lcd.c> #use i2c(Master,sda=PIN_B2,scl=PIN_B4,FORCE_SW) void main(){ int1 flag0; int1 flag1; int1 flag2; int1 flag3; int1 flag4; int1 flag5; int1 flag6; int msb; int lsb; lcd_init(); delay_ms(50); printf(lcd_putc,"\fInicio..."); delay_ms(1000); while(1){ //after a writing, flags go to 0 if master received ACK from slave flag0=1; flag1=1; flag2=1; flag3=1; flag4=1; flag5=1; flag6=1; //-------------------------configuration--------------------------------// i2c_start(); flag0=i2c_write(0b10010000); // address = 0x90 | 0 -> write flag1=i2c_write(0b00000001); // 0x01 -> config register flag2=i2c_write(0b11000001); // 1 -> os, 100 -> an0-gnd, 000 -> +-6.144 range, 0/1 -> continuous/single conversion flag3=i2c_write(0b10000011); // default i2c_stop(); //----------------------------reading-----------------------------------// i2c_start(); flag4=i2c_write(0b10010000); // address = 0x90 | 0 -> write flag5=i2c_write(0b00000000); // 0x00/0x01 -> conversion/config register i2c_stop(); delay_ms(500); i2c_start(); flag6=i2c_write(0b10010001); // address = 0x90 | 1 -> read msb = i2c_read(); lsb = i2c_read(0); // No ACK from master i2c_stop(); //----------------------------output------------------------------------// printf(lcd_putc,"\f%u %u %u\n%u %u %u %u",flag0,flag1,flag2,flag3,flag4,flag5,flag6); //makes sure the whole COM process was fine delay_ms(1000); printf(lcd_putc,"\fmsb,lsb=%u,%u",msb,lsb); //msb and lsb from conversion displays on lcd 16x2 delay_ms(1000); } }
The flags variables are printed as '0's on the LCD, which means that communication is going well and the chip isn't broken. However the problem is that whenever I read the conversion register, I get msb=0 and lsb=0. And the reason for this is that, when I change the code in order to read the configuration register, I get msb=65(0b01000001) and lsb=131(0b10000011) which means that even after 500ms of delay the conversion is still in progress (OS bit is cleared).
Why is this happening? I guess that timings could not be correct, but I read from other threads that this should not be a problem in power-down mode. I've read the datasheet many times and I can't figure out what could be wrong. I've been working on this issue for many days now and I'm running out of ideas.
Some additional information about my setup:
- I'm powering my entire circuit with the output of a switching converter module (the LM2596 module to be precise) whose input is a 9V battery.
- My circuitry is built on a breadboard.
- The I2C lines are connected by jumpers that are 15cm long at max.
- I tried using the actual I2C module from the PIC, which uses RC3 and RC4 pins but for some reason it ends up printing msb=255 and lsb=255 on the LCD. That is why I stuck with the software implementation through normal GPIO pins (B2 and B4).
PD: If anybody knows if it is possible to simulate the chip (ADS1115) in Proteus or some other similar software it would be great if you could post it in this thread because every time I wanted to test my code I had to "burn" my code onto the PIC so that really slowed down the development of my project.
Thanks.