CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

ADS1115 CAN16 bits driver - delay !?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
joseph20480



Joined: 21 Dec 2011
Posts: 35

View user's profile Send private message

ADS1115 CAN16 bits driver - delay !?
PostPosted: Wed Feb 22, 2017 10:39 am     Reply with quote

hi,

I'm currently write an library for the ADS1115 (Family of ADS1113/4/5).
It's an i2C 16 bits sigma delta.
My library works... i'm able to write into register, read register, configure the chip and have the result of the conversion. But, if i want to change somethings into the register (like change the input pin), i have to wait at least 25ms before read the new conversion result...
I have read different library for this chip for Arduino and i have never see that ... if you have an idea...

Code:

ADS1115_write(addr_1, configuration_register, ADS1115_OS_MASK + ADS1115_MUX_SINGLE_0 + ADS1115_PGA_2_048V + ADS1115_MODE_CONTIN + ADS1115_RATE_64SPS + ADS1115_disable_comparator);



Code:

//----------------------------------
byte ADS1115_ready(int8 addr)
{
   byte ack;
   i2c_start();
   ack=i2c_write(addr+write_bit);
   i2c_stop();   

   return !ack;
}
//----------------------------------



Code:

//----------------------------------
void ads1115_write(int8 addr,int8 reg,int16 data)
{
   int8 lo,hi;

   lo=data;
   hi=data>>8;

   i2c_start();
   i2c_write(addr + write_bit);   // Address
   i2c_write(reg);       // Config register
   i2c_write(hi);      
   i2c_write(lo);      
   i2c_stop();
}
//----------------------------------


Code:

//----------------------------------
int16 ads1115_read(int8 addr,int8 reg)
{
   int16 data;

   i2c_start();
   i2c_write(addr + write_bit);   
   i2c_write(reg);    
   i2c_stop();

   i2c_start();
   i2c_write(addr + read_bit);   
   data=i2c_read(1);
   data=data<<8;
   data=data+i2c_read(1);
   i2c_stop();


   return data;
}
//----------------------------------


Code:

//----------------------------------
int16 ADS1115_raw_measure(int8 addr,int8 channel)
{
   int16 mesure;
   int16 registre;


   registre=ADS1115_read(addr,configuration_register);

   registre = registre & 0b1000111111111111;
   if (channel==0){registre=registre | ADS1115_MUX_SINGLE_0;}
   if (channel==1){registre=registre | ADS1115_MUX_SINGLE_1;}
   if (channel==2){registre=registre | ADS1115_MUX_SINGLE_2;}
   if (channel==3){registre=registre | ADS1115_MUX_SINGLE_3;}
   
   ADS1115_write(addr,configuration_register,registre);
   [b] delay_ms(25); //...... Delay !???!!! [/b]
   mesure=ADS1115_read(addr,convertion_register);


   return mesure;
}
//-----------------------------------


The problem appears when i ask measure on every channel (begin by ch1, ch2, ch3, ch4) :
WITH delay : normal operation, the result of conversion is good.
Without delay : it's seem that the mux into the chip have not change... i try to measure the channel two, but the chip send me the value of channel 1.
temtronic



Joined: 01 Jul 2010
Posts: 8220
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 22, 2017 11:16 am     Reply with quote

I see that chip has two modes, single or continuous . My guess is that you've set it for 'single' reading mode which automaticly 'powers down' to save energy.
You should printout the actual 'configuration' bits to confirm their settings.

It may not be what the problem is , but should be looked at.

Jay
joseph20480



Joined: 21 Dec 2011
Posts: 35

View user's profile Send private message

PostPosted: Thu Feb 23, 2017 2:15 am     Reply with quote

temtronic wrote:
I see that chip has two modes, single or continuous . My guess is that you've set it for 'single' reading mode which automaticly 'powers down' to save energy.
You should printout the actual 'configuration' bits to confirm their settings.

It may not be what the problem is, but should be looked at.

Jay


Thanks for your reply but the register sended seems to be correct.
The conversion mode is set to 0 for "continuous-conversion
mode" - page26 from data sheet.

No further remarks ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21508

View user's profile Send private message

PostPosted: Thu Feb 23, 2017 3:04 am     Reply with quote

joseph20480 wrote:
No further remarks ?


Quote:
ADS1115_OS_MASK + ADS1115_MUX_SINGLE_0 + ADS1115_PGA_2_048V + ADS1115_MODE_CONTIN + ADS1115_RATE_64SPS + ADS1115

Post the #define statements for all these constants, and any other
constants that refer to the ads1115.

Post your PIC.

Post your CCS compiler version.

Post your #fuses and your #use delay(), etc.

And I think temtronic is suggesting that you try Single shot mode
instead of continuous conversion mode. See what happens.

And also, post an actual test program. That's why I didn't initially reply.
For example, you have the ADS1115_ready() function, but it is not called
in your posted code snippets. What are you really doing in your program ?
We won't know, until you post a test program.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu Feb 23, 2017 3:34 am     Reply with quote

You do realise the ADS1115 is a delta-sigma ADC don't you? It works by massive oversampling and with heavy digital filtration. They have slow update rates; the ADS1115 going at its fastest at 860samples/second.

Depending on how you have configured it, it will take at least one full sample time to produce an new result after any change. A delay of 25ms imples that the actual sample rate is no more than 40sps, which is entirely plausible for this ADC.

That you get the result of the last conversion until a new converson is complete is also understandable. In short, it appears this convertor is behaving much as I, and you, should expect it to. They are at their best when sampling single, small, slowly-changing signals with high precision but long latency, for things such as load cells, thermocouples, thermistors/PRTs, battery voltages and the like. They are not at their best, or at least are very slow, when used by switching frequently between mulitple signals.
Ttelmah



Joined: 11 Mar 2010
Posts: 17477

View user's profile Send private message

PostPosted: Thu Feb 23, 2017 4:20 am     Reply with quote

The standard Arduino code for this chip, loops continuously, until it sees bit 7 of the first byte read go 'high' to say a conversion has completed.

The normal Arduino routine is effectively:
Code:

int8 msb, lsb;
do
{
   i2c_start();
   i2c_write(addr + read_bit);   
   msb=i2c_read(0);
   lsb=2c_read(1);
   i2c_stop();
} while (bit_test(msb,7)==0);
data = make16(msb & 0x7F, lsb);

So it doesn't wait before triggering this, it keeps repeating the read, until the flag sets to say the conversion has completed.
PCM programmer



Joined: 06 Sep 2003
Posts: 21508

View user's profile Send private message

PostPosted: Thu Feb 23, 2017 4:31 am     Reply with quote

Read the post by Krunal Maniar on July 6, 2016 on the T.I. forum.
It fully explains what happens when you change the channel in continuous
conversion mode (this post is at the end of the thread):
http://e2e.ti.com/support/data_converters/precision_data_converters/f/73/p/526236/1916483#1916483

He also explains why it's better to run in single shot mode if you want
to change the channel.
joseph20480



Joined: 21 Dec 2011
Posts: 35

View user's profile Send private message

PostPosted: Fri Feb 24, 2017 3:36 am     Reply with quote

Thanks to Ttelmah and PCM programmer, you have right !

I had two errors in code/mind.
The first was that I didn't test if the CAN have finished to convert before read the result... the code from Ttelmah work very well.

The second is about the technology and how work an ADC. Very interesting.

Thanks every one !
vasiliok



Joined: 17 May 2011
Posts: 15
Location: Kaunas, Lithuania

View user's profile Send private message

PostPosted: Wed Jun 16, 2021 12:30 am     Reply with quote

I have completed a bit the code of topic starter comrade joseph20480

Code:

#define address1     0x90 // first ADC module
#define address2     0x92 // second ADC module (if you have one?)
#define write_bit    0
#define read_bit     1

#define configuration_register   0x01
#define convertion_register      0x00
#define ADS1115_MUX_SINGLE_0     0b0100000000000000
#define ADS1115_MUX_SINGLE_1     0b0101000000000000
#define ADS1115_MUX_SINGLE_2     0b0110000000000000
#define ADS1115_MUX_SINGLE_3     0b0111000000000000





//-----------------------------------------------------------
byte ADS1115_ready(int8 addr)
{
   byte ack;
   i2c_start();
   ack=i2c_write(addr+write_bit);
   i2c_stop();   

   return !ack;
}
//-----------------------------------------------------------




//-----------------------------------------------------------
void ads1115_write(int8 addr,int8 reg,int16 data)
{
   int8 lo,hi;

   lo=data;
   hi=data>>8;

   i2c_start();
   i2c_write(addr + write_bit);   // Address
   i2c_write(reg);       // Config register
   i2c_write(hi);     
   i2c_write(lo);     
   i2c_stop();
}
//-----------------------------------------------------------



//-----------------------------------------------------------
int16 ads1115_read(int8 addr,int8 reg)
{
   int16 data;

   i2c_start();
   i2c_write(addr + write_bit);   
   i2c_write(reg);   
   i2c_stop();

   i2c_start();
   i2c_write(addr + read_bit);   
   data=i2c_read(1);
   data=data<<8;
   data=data+i2c_read(1);
   i2c_stop();


   return data;
}
//-----------------------------------------------------------


//-----------------------------------------------------------
int16 ADS1115_raw_measure(int8 addr,int8 channel)
{
   unsigned int16 mesure;
   unsigned int16 registre=0;


   //registre &= 0b1000001100011111;

   if (channel==0){registre=registre | ADS1115_MUX_SINGLE_0;}
   if (channel==1){registre=registre | ADS1115_MUX_SINGLE_1;}
   if (channel==2){registre=registre | ADS1115_MUX_SINGLE_2;}
   if (channel==3){registre=registre | ADS1115_MUX_SINGLE_3;}
   
   
   ADS1115_write(addr, configuration_register, registre);
   
   delay_ms(280); //For data rate of 8 SPS, maximum time = 2*(1/(0.9*SPS) = 277mS delay
   
   mesure = ADS1115_read(addr, convertion_register);
   //mesure = ADS1115_read(addr, convertion_register);

   return mesure;
}
//-----------------------------------------------------------




And the main code where I read ch1, ch2, ch3 of my first ADC module (I have two modules in the circuit).
Read three channels and show values on LCD screen.
MCU is PIC24FV32KA304

Maybe this code will help someone


Code:
while(TRUE){     
     
         
         resultas = ADS1115_raw_measure(address1, 1);
         
         itampa1 = 0.00133 * (float)resultas;
         lcd_gotoxy(1,1);
         //printf(lcd_putc, "%Lu      ", resultas);
         printf(lcd_putc, "ch1 %2.1f      ", itampa1);
     
     
         delay_ms(1500);
     
     
     
     
     
         resultas = ADS1115_raw_measure(address1, 2);
         
         itampa2 = 0.00133 * (float)resultas;
         lcd_gotoxy(1,1);
         //printf(lcd_putc, "%Lu      ", resultas);
         printf(lcd_putc, "ch2 %2.1f      ", itampa2);
     
       
         delay_ms(1500);

         
         
         resultas = ADS1115_raw_measure(address1, 3);
         
         itampa3 = 0.00133 * (float)resultas;
         lcd_gotoxy(1,1);
         //printf(lcd_putc, "%Lu      ", resultas);
         printf(lcd_putc, "ch3 %2.1f      ", itampa3);
     
         delay_ms(1500);
     
     
     

   }//WHILE

}//MAIN
Ttelmah



Joined: 11 Mar 2010
Posts: 17477

View user's profile Send private message

PostPosted: Wed Jun 16, 2021 2:28 am     Reply with quote

Thanks vasiliok. Nice to have somebody post a potential termination to the
thread.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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