|
|
View previous topic :: View next topic |
Author |
Message |
Tolias
Joined: 20 Feb 2018 Posts: 2
|
PIC16F887 - I2C - ADS1115 problem |
Posted: Wed Feb 21, 2018 7:42 am |
|
|
Hello,
This is my first post in this forum, as you can see from the subject i use the microcontroller PIC16F887 with the external A/D module ADS1115 due to i need 16-bit resolution for my temperature sensor. The main problem that i face is when i try to read the data from the external A/D, i have minus results.
As hardware my board it works properly, i have already connect 2 pull up resistors 4.2K in SDA(pin 23) and SCL(pin 18). Also i found in this forum a code that when i run it i can see in my terminal that the A/D module it has ACK add: 90(according to datasheet its correct) and Number of i2c chips found:1.
Here you are my code:
Code: |
#include <main.h>
#include <16F887.h>
#FUSES NOBROWNOUT
#FUSES NOLVP
#device ICD=TRUE
#use delay(internal=8MHz)
#use RS232(DEBUGGER)
#use I2C (master, sda = PIN_C4, scl = PIN_C3)
#use rs232( baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, ERRORS)
void main()
{
int8 msb,lsb;
int16 dval;
int8 address = 0x90;
float Vout,temp1;
setup_oscillator(OSC_8MHZ, 3);
i2c_start(); // Configuration of registers
i2c_write(address);//address of device last bit R/W read=1 write=0
i2c_write(0x01);//address point Register
i2c_write(0x80);//Config register MSB
i2c_write(0x83);//Config register LSB
i2c_stop();
i2c_start(); //write address Point register
i2c_write(address); //First byte address of device last bit R/W
i2c_write(0x00); //Second byte point to convertion register
i2c_stop();
delay_ms(500);
while(TRUE)
{
i2c_start();
i2c_write(address);//address of device R/W
i2c_write(0x00);// 0x00
i2c_start();
i2c_write(0x91); //0x91
msb=i2c_read();
lsb=i2c_read();
delay_ms(100);
i2c_stop();
printf("\n\r");
dval = make16(msb,lsb); //merge the MSB and LSB
printf("data1 %d\n\r", msb);
printf("data2 %d\n\r", lsb);
printf("dval %ld\n\r", dval);
Vout = ((float)dval * 5 / 65535); //Voltage = digital / refV
temp1 = (Vout - 1.25) / 0.005; // Temp = (Vout - 1.25)/5mV
printf("temp1 %f\n\r", temp1);
delay_ms(1000);
}
}
|
This is what i have in my terminal.
Quote: | data1 -1
data2 -1
dval -2049
temp1 718.74 |
I hope to provide me some ideas in order to understand my errors, i read many times very carefully the datasheet of ADS1115 but i m sure that something is missing in my mind.
Thank you in advance
Apostolos |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19512
|
|
Posted: Wed Feb 21, 2018 10:30 am |
|
|
OK. First, applause...
Lots of basic testing done.
Looking at your code, you set the device up to perform a single conversion. Then you never trigger a conversion again. It'll go back to sleep after the conversion. The example you are basing the code on, sets it to continuous conversion mode, so after 1/6th second, you can read and get new values continuously. There is also no point in delaying after the read before the stop.
To use single conversion, you'd have to include the configuration setting inside the loop. So:
Code: |
while (TRUE)
{
i2c_start(); // Configuration of registers
i2c_write(address);//address of device last bit R/W read=1 write=0
i2c_write(0x01);//address point Register
i2c_write(0x80);//Config register MSB
i2c_write(0x83);//Config register LSB
i2c_stop();
delay_ms(130); //pause for conversion - since you are
//selecting 8sps, need 1/8th second for conversion
//You could poll the status instead of just waiting
i2c_start();
i2c_write(address);//address of device R/W
i2c_write(0x00);// 0x00 - result
i2c_start();
i2c_write(address | 1); //read
msb=i2c_read();
lsb=i2c_read(0); //nack second byte
i2c_stop();
|
Note that dval should be declared as a _signed_ int16.
You are currently getting back 255, which is pretty common for 'something not programmed right'. Now we need to find out 'what'.... |
|
|
Tolias
Joined: 20 Feb 2018 Posts: 2
|
|
Posted: Thu Feb 22, 2018 3:03 am |
|
|
Hi,
Thanks for the answer i changed the code by using your advice but still i do not have the expected results.
Here you are the code:
Code: |
#include <main.h>
#include <16F887.h>
#FUSES NOBROWNOUT
#FUSES NOLVP
#device ICD=TRUE
#use delay(internal=8MHz)
#use RS232(DEBUGGER)
#use I2C (master, sda = PIN_C4, scl = PIN_C3)
#use rs232( baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, ERRORS)
void main()
{
int8 msb,lsb;
signed int16 dval;
int8 address = 0x90;
float Vout,temp1;
setup_oscillator(OSC_8MHZ, 3);
while(TRUE)
{
i2c_start(); // Configuration of registers
i2c_write(address);//address of device last bit R/W read=1 write=0
i2c_write(0x01);//address point Register 0x1
i2c_write(0x80);//Config register MSB 3rd bit 0- 0x80
i2c_write(0x83);//Config register LSB - 0x83
i2c_stop();
delay_ms(130);
i2c_start();
i2c_write(address);//address of device R/W
i2c_write(0x00);// 0x00
i2c_start();
i2c_write(address | 1); //0x91
msb=i2c_read();
lsb=i2c_read(0);
i2c_stop();
printf("\n\r");
dval = make16(msb,lsb); //merge the MSB and LSB 0x7F
printf("data1 %d\n\r", msb);
printf("data2 %d\n\r", lsb);
printf("dval %ld\n\r", dval);
Vout = ((float)dval * 5 / 65535); //Voltage = digital / refV
temp1 = (Vout - 1.25) / 0.005; // Temp = (Vout - 1.25)/5mV
printf("temp1 %f\n\r", temp1);
delay_ms(1000);
}
}
|
This is the result that i have in my terminal:
Quote: |
data1 -75
data2 -112
dval -19056
temp1 -540.77
data1 -75
data2 -110
dval -19054
temp1 -540.74 |
Now the temperature decrease it when i use hot air in the sensor, i think this is positive it means that i can read the temperature but i m sure that have some mistakes in the calibration. I do not know if am i correct this is just my conclusion. I would be really happy if someone have some advice for debugging.
Thank you
Apostolos |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|