soligen2010 / Adafruit_ADS1X15

Driver for TI's ADS1x15: 12 and 16 bit Differential or Single-Ended ADC with PGA and Comparator
Other
60 stars 30 forks source link

Runing multiple analog channels on continuous-conversion mode #9

Closed FadiBunni closed 6 years ago

FadiBunni commented 6 years ago

Hello,

Thanks you soo much for this library, it works much better than the adafruit one, really good at solving the conversion delay problem.

Before i explain my issue, i had like to explain what i need the ADC to do.

I have 6 pressure transducers that I want to ultimately sample at 2.5kHz each, for this I need to use the ads1015. But right now i only have a ads1115 so 860 will do. Now my problem is to sample all of them at max sampling rate (860 or 3.3k depending on the chip I have). When I use all the analog channels the sampling rate goes down to about 860/4, because of the conversiondelay for each reading. So I tried to use multiple chips each having only 1 analog input, so 4 chips each having 1 pressure transducer. But this result in the same problem since the chips still has the same conversiondelay X 4.

Then I read about the continuous-conversion-mode that you have implemented /example/continuous/continuous.ino, utilizing the interrupt pin. I can see that having 1 analog input to one sensor gives the max sampling rate of 860, so that is cool.

Now my question is it possible to all the channels (4) on continuous-conversion-mode having all running on max sampling rate? If so how does the code look like running multiple channels? because I tried to outcomment line 38 to try to run 2 analog channels, but i only get the reading of the last one.

If this is not possible will it then be possible to run multiple chips all running on continuous-conversion-mode with each having 1 analog input, and then use two I2C buses since only 4 chips can be used togeather?

Thanks so much!

//Fadi

soligen2010 commented 6 years ago

Continuous mode can only be one channel at a time. This is a hardware limitation. You can run multiple chips. Each will need it's own I2C address and it's own interrupt pin if you want to use interrupts. This is more advanced stuff so I suggest you download the datasheet for the chip from TI. And, if you are not very familiar with pin change interrupts, research that too. I suggest that you keep to the pattern in the example and don't read the value in the interrupt routine because the I2C communication is not fast. Set a volatile flag in the interrupt to indicate data is ready and read the actual value in the loop ( then reset the flag).

FadiBunni commented 6 years ago

Alright I got you. So I am going to run multiple chips with only one channel on each chip.

I think I have solved the problem of using interrupt pins for each chip. Below is the code running two chips with each one having 1 interrupt pin and one channel on. And it is working fine, what do you think about the code?

Thanks :)


include

include

include

include

Adafruit_ADS1115 ads1115_0(0X48); / Use this for the 16-bit version / Adafruit_ADS1115 ads1115_1(0X49);

const int alertPin_4 = 4; const int alertPin_3 = 3;

volatile bool continuousConversionReady_0 = false; volatile bool continuousConversionReady_1 = false;

void setup(void) { pinMode(alertPin_4, INPUT); pinMode(alertPin_3, INPUT); SerialUSB.begin(1000000); SerialUSB.println("Hello!");

SerialUSB.println("Getting single-ended readings from AIN0..3");
SerialUSB.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");

// The ADC input range (or gain) can be changed via the following
// functions, but be careful never to exceed VDD +0.3V max, or to
// exceed the upper and lower limits if you adjust the input range!
// Setting these values incorrectly may destroy your ADC!
//                                                                ADS1015  ADS1115
//                                                                -------  -------
// ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
ads1115_0.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
                                  // ads1115.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
                                  // ads1115.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
                                  // ads1115.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
                                  // ads1115.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
ads1115_1.setGain(GAIN_ONE);
ads1115_0.begin();
ads1115_1.begin();

ads1115_0.startContinuous_SingleEnded(0);
ads1115_1.startContinuous_SingleEnded(0);

attachInterrupt(digitalPinToInterrupt(alertPin_4), continuousAlert_0, FALLING);
attachInterrupt(digitalPinToInterrupt(alertPin_3), continuousAlert_1, FALLING);
//Wire.setClock(400000);

}

void continuousAlert_0() {

// Do not call getLastConversionResults from ISR because it uses I2C library that needs interrupts
// to make it work, interrupts would need to be re-enabled in the ISR, which is not a very good practice.

continuousConversionReady_0 = true;

} void continuousAlert_1() {

// Do not call getLastConversionResults from ISR because it uses I2C library that needs interrupts
// to make it work, interrupts would need to be re-enabled in the ISR, which is not a very good practice.

continuousConversionReady_1 = true;

} int i = 0; int b; int sum = 0; int16_t adc0; int16_t adc1; int16_t adc2; int16_t adc3; void loop(void) { int counter = 0; long start = millis();

//time_t n = now();

while (millis()<start + 1000) {
    /*adc0 = ads1115_0.readADC_SingleEnded(0);*/
    //adc1 = ads1115_1.readADC_SingleEnded(0);
    //adc2 = ads1115.readADC_SingleEnded(2);
    //adc3 = ads1115.readADC_SingleEnded(3);
    //for(int i = 0; i <= 100; i++) {
    //  adc0_1 = ads1115.readADC_Differential_0_1();
    //  sum += adc0_1;
    //}
    //adc0_1 = ads1115.readADC_Differential_0_1();
    //SerialUSB.print("ADS_0,AIN0: ");
    //SerialUSB.print(adc0);
    //SerialUSB.print(" ADS_1,AIN1: ");
    //SerialUSB.println(adc1);
    //SerialUSB.print(" AIN2: ");
    //SerialUSB.println(adc0);
    //SerialUSB.print(" AIN3: ");
    //SerialUSB.println(adc3);
    //SerialUSB.println(adc0_1);
    //SerialUSB.print("Sum: ");
    //SerialUSB.println(sum/100);
    //SerialUSB.println(" ");

    //if (n != b) {
    //  b = n;
    //}
    //SerialUSB.print("samples: ");
    //SerialUSB.println(i);
    //SerialUSB.print("seconds: ");
    //SerialUSB.println(n);

    if (continuousConversionReady_0) {
        float result = ((float)ads1115_0.getLastConversionResults()) * ads1115_0.voltsPerBit();
        continuousConversionReady_0 = false;
        SerialUSB.print("ads1115_0 ");
        SerialUSB.print(result, 7);
        //SerialUSB.print(" at millisecond ");
        //SerialUSB.println(millis());
        //counter++;
    }
    if (continuousConversionReady_1) {
        float result = ((float)ads1115_1.getLastConversionResults()) * ads1115_1.voltsPerBit();
        continuousConversionReady_1 = false;
        SerialUSB.print(" ads1115_1 ");
        SerialUSB.println(result, 7);
        //SerialUSB.print(" at millisecond ");
        //SerialUSB.println(millis());
        //counter++;
    }
    //counter++;
}

//i++;
//sum = 0;
SerialUSB.println(counter);

}

soligen2010 commented 6 years ago

I would suggest cutting down on the redundant code by using arrays

FadiBunni commented 6 years ago

Yea, I will do that once I have tested for all chips.

Thanks for your help!

You may close this issue :)