Need some help and advices - Multiplexing sensor ranges!

Howdy folks,

I'm pretty much new around and I've thought of automating a certain process in a laboratory. Did the math, the calculations and it comes out that I need a 14 bit ADC, however the Arduino board I had in mind only comes with 10 bit. How can that be addressed to? Anyone had this difficulty and managed solving it?

Please answer, as I'm in a bit of rush. Thanks for your indulgence. :slight_smile:

Use an external ADC chip, there are lots about. You interface them with either SPI or I2C bus.
Look these up in the playground section of this site.

Could you tell what you want to measure ?
For some lab measurements you would need a lot of analog knowledge to get 14 bits of accuracy.

At least start with a 16 bit exernal ADC.
This one seems a good choice, ADS1115 16-Bit ADC - 4 Channel with Programmable Gain Amplifier [STEMMA QT / Qwiic] : ID 1085 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits
Adafruit has even a tutorial, a library and example code for it.

daemon_deluxe:
Howdy folks,

I'm pretty much new around and I've thought of automating a certain process in a laboratory. Did the math, the calculations and it comes out that I need a 14 bit ADC, however the Arduino board I had in mind only comes with 10 bit. How can that be addressed to? Anyone had this difficulty and managed solving it?

10 bits can measure down to 0.01%. Getting less than 0.01% noise/distortion in your input signal will probably be a far bigger problem than lack of bits in your A/D converter.

Noise/distortion won't be a problem as I'm using a linear displacement transducer from Miyamoto. It's error is 0.03%, displacement is 10mm(give or take 5%). I'm trying to measure up to at least a 0.001 error in the displacement, and 10bits won't do, as 2^10 = 1024. Dividing 10mm in 1024 gives out an error of 0.0097. I want it a bit firmer. Wanted 14 bits because that would place the error at 0.0001 and would give me a lot of breathing space, as I need to automate the process via a variable solenoid valve. :slight_smile:

I think I'll got with the Adafruit, as it has a library and the code doesn't need to be very complex. Now, just another newbie question, as I haven't worked with Arduino until now : if I interface it with a tablet Arm7 core, how would it see it? Is it auto and can I stream the data directly via USB or do I need a catch/drop routine written in Java? Any hand of help is very appreciated, and I'll post the project code here, for everyone to check out and learn from. :slight_smile:

Noise/distortion won't be a problem

Yes it will, it is always a problem with analogue circuits, it is not just a matter of having a good transducer. You will pick up noise through EMI, and power supply unless you take measures to combat and reduce it.

if I interface it with a tablet Arm7 core, how would it see it? I

What operating system?

Is it auto and can I stream the data directly via USB

Only if your tablet can take in what looks like a serial com port.

Some of the external ADC modules (such as that adafruit one) if used in their differential input mode offer very good rejection of common mode noise sources. The arduino analog inputs are 'single ended' and will always suffer more from external noise sources then differential inputs will.

Lefty

10 bits can measure down to 0.01%

you can do oversampling with the 10 bits ADC of the arduino, takes some time but it works.
every factor 4 more samples gives you 1 bit extra

14 bits needs averaging 4^4 = 64 samples

See tech notes of AVR - http://www.atmel.com/images/doc8003.pdf -

Experimental code that includes a 2nd variation that has proper rounding.

//
//    FILE: analogReadN.pde
//  AUTHOR: Rob Tillaart
//    DATE: 2012-05-10
//
// PUPROSE: higher precision analogRead()
//
// http://www.atmel.com/Images/doc8003.pdf 
//

void setup()
{
  Serial.begin(115200);

  for (int b=10; b< 17; b++)
  {
    unsigned int val = analogReadN(A0, b);
    Serial.println(val, DEC); 
  }
}

void loop()
{
}

uint16_t analogReadN(uint8_t pin, uint8_t bits)
{
  bits = constrain(bits, 10, 16) -10;

  int samples = 1 << (bits << 1);

  uint32_t sum=0;
  for (int i=0; i< samples; i++) sum += analogRead(pin);     
  return sum >> bits;                             
}

uint16_t analogReadNreference(uint8_t pin, uint8_t bits)
{
  bits = constrain(bits, 10, 16) -10;

  int d = 1;
  for (int i=0; i<bits; i++) d *= 2;
  int samples = d*d;

  uint16_t sum = 0;
  for (int i=0; i< samples; i++) sum += analogRead(pin);     
  return (sum + d/2) / d;    // rounding                             
}

daemon_deluxe:
Noise/distortion won't be a problem as I'm using a linear displacement transducer from Miyamoto. It's error is 0.03%, displacement is 10mm(give or take 5%). I'm trying to measure up to at least a 0.001 error in the displacement, and 10bits won't do, as 2^10 = 1024. Dividing 10mm in 1024 gives out an error of 0.0097. I want it a bit firmer. Wanted 14 bits because that would place the error at 0.0001 and would give me a lot of breathing space, as I need to automate the process via a variable solenoid valve. :slight_smile:

You should definitely use an external ADC with a differential mode, otherwise ground noise will almost certainly ruin the resolution.

robtillaart:
you can do oversampling with the 10 bits ADC of the arduino, takes some time but it works.
every factor 4 more samples gives you 1 bit extra

True, but that only works if you either add a dither to the signal being measured, or the signal is already noisy and you are interested in the average value.

I'm absolutely positive that the signal is noisy. I'll try my best and filter out what I can, so thanks for the advices. Mind if I come back now and again and start asking stupid question? :slight_smile:

Regards,
Andrei

Questions are never stupid. Not asking them can be. And answers too :wink:
So feel free to question

daemon_deluxe:
I'm absolutely positive that the signal is noisy. I'll try my best and filter out what I can, so thanks for the advices. Mind if I come back now and again and start asking stupid question? :slight_smile:

If the signal changes slowly (eg. physical position) then just put a small ceramic capacitor as close to the ADC input as possible (between ground and ADC input).