Having a problem with the value of ADC

Hi Guys,

I am using Arduino mega 2560 board. I am working on a project of a datalogger using thermistors. My goal is to read 7 analog inputs from the arduino board coming from 7 thermistors based circuit and convert it into temperature. I am using an volatge divider circuit for each thermistor. The thermistor has 30K ohm resistance at 25°C and I am using a series resistance of 33K ohm. I want to output all the 7 channels measing temperature simultaneously with high acccuracy.

I am currently reading two analog inputs from arduino using the simulink package of arduino with 2 thermistor based circuits.The problem is I am not getting the same ADC value from both of them. I mean, they are offset by atleast ±5. Lets say, I get the ADC value 499 from one sensor and i get 495 from another sensor. It would be greatly helpful if anyone could help me on this topic. I am finding it easy to implement in simulink rather to code it in arduino IDE.

How can I do that using Arduino IDE ? I want to log all the temperatures simulatenously into a file at sampling rate of atleast 2 Hz. Please help me on this.

You're seeing the effect of component tolerance. The thermistors are probably 1% but the resistors are more likely 5%. An error of about 5 out of 500 is quite close, and lucky. You will have to select one as a calibrated reference and scale the others to it.

You cannot read all at the same time as there is only one internal ADC. It selects the right input through an equivalent analogue switch. You can eliminate most of the problem by selecting them from 0 to 6 then 6 to 0 in one sequence. The average of the two readings for each channel is a close match to the center of the time window. For example, the readings for A0 are the first and last while A6 is in the middle in terms of time. If the drift is linear then the A0 average reading will be at the same time as A6.

In your sequence, insert a delay(1); as the analogue switch needs time to settle on the new input voltage.

Arctic_Eddie:
In your sequence, insert a delay(1); as the analogue switch needs time to settle on the new input voltage.

Or read the same ADC twice but discard the first reading.

Thank you @Arctic_Eddie

Arctic_Eddie: You can eliminate most of the problem by selecting them from 0 to 6 then 6 to 0 in one sequence. The average of the two readings for each channel is a close match to the center of the time window. For example, the readings for A0 are the first and last while A6 is in the middle in terms of time. If the drift is linear then the A0 average reading will be at the same time as A6.

I did not understand this part of reply completely. Could you please elaborate on this.

Thank you Riva,

In Arduino IDE, do you mean to say I use analogread(pin) twice to get the reading?

I would like to program it in but since I am controlling the board using Simulink as of now. Could you please tell me how could I do that in simulink?

If your data changes from the time of the first reading, A0, to the last, A6, then it's not the same as all channels reading simultaneously. A6 was read later than A0. When each channel is read twice then the average time of a pair of readings of the same channel is the first time plus the last time divided by two. Therefore, if you read all channels twice but in opposite sequence then the average time for each is the same. The average time is midway between the first reading of A6 and the second reading of A6.

Make a time chart from the first time of A0 to the last time of A0 and you'll see that the average time for each channel is the same time, hence simultaneously.

A0 A1 A2 A3 A4 A5 A6 * A6 A5 A4 A3 A2 A1 A0 where * is the average time for all channels.

The difference between the two readings of A0 is a measure of how quickly your data is changing in that time period.

Got a good multimeter?
Then sort NTC and resistors by value. Pair them accordingly

int tbl[7];
int i;

void setup() 
{
}

void read_sensors()
{
  for (i=0; i<7; i++)
  {
    analogRead(i); // dummy
    tbl[i]=analogRead(i);
  } 
  for (i=6; i>=0; i--)
  { 
    analogRead(i); // dummy
    tbl[i]= (tbl[i]+analogRead(i))/2;
  } 
}

void loop() 
{
  read_sensors();
  // more code
}

varun3055: In Arduino IDE, do you mean to say I use analogread(pin) twice to get the reading?

There's actually only one analog measuring circuit in the Arduino chip and that is fronted (again internally) by a multiplexer. So what you're seeing is the residual charge in that ADC being reflected in the results of other pins. The effect is most notable when you're performing analogReads of multiple pins in quick succession.

The simple solution, like Riva suggested, is to perform two analog readings with each pin and only use the last result. Usually that is sufficient for a reasonably accurate reading.

I've not used the Simulink package and can't comment on that. I'd find it hard to believe that Simulink users wouldn't have experienced this type of problem in the past though; I'd suggest putting a little effort into searching for this problem in whatever knowledgebase exists for that software.

Chagrin:
I’ve not used the Simulink package and can’t comment on that. I’d find it hard to believe that Simulink users wouldn’t have experienced this type of problem in the past though; I’d suggest putting a little effort into searching for this problem in whatever knowledgebase exists for that software.

Like Chagrin I have no experience with Simulink but if you cannot set it up to double read an analogue pin then can you get Simulink to read the same pin twice and discard the first result in Simulink?

The thermistor has 30K ohm resistance at 25°C and I am using a series resistance of 33K ohm. I want to output all the 7 channels measing temperature simultaneously with high acccuracy.

Part of the problem could be that the ADC is optimized for analog signals with an output impedance of approximately 10k or less. I would add a 100nF capacitor from each analog input to GND, which will effectively lower the impedance on the input.

Thank you @Arctic_Eddie and @knut_ny

I understood it now nicely. I will try to implement it by programming. I don't think I can implement it using simulink. I will try it. Thank you so much for your help.

Chagrin: I've not used the Simulink package and can't comment on that. I'd find it hard to believe that Simulink users wouldn't have experienced this type of problem in the past though; I'd suggest putting a little effort into searching for this problem in whatever knowledgebase exists for that software.

Thank you Chagrin and Riva ,

I comppletely understand your point on analog Reads but I do not think It is possible to do it in that way using simulink since it is block oriented. Even I find it hard to believe that Simulink users have not faced any similar issues regarding this. I gives an error if I use the same analogRead block twice for the same pin. I need to do a deeper research into it. I will explore more about it. Thank you very much for your suggestions, It helped me a lot.

Hi dlloyd,

I have used a 0.1 uF capacitor across the 33 Kohm resistance. Even then I encounter this problem.

Hi @Arctic_Eddie and @knut_ny,

I tried the methods to read the analog pins twice, now the outputs are stable to some extent but not completely. I have also put 0.1uF capacitor across the 33 Kohm resistanc. Even now, I see fluctuations in the sensor values . I am also using extrnal power supply with an adapter of 7.5 V DC.

What else could be the problem?

Put a delay of 1ms between each reading. Also, be sure the sensors are not seeing air currents.

What kind of variation do you see.?

PS Move the capacitor to the thermistor as it's more likely to be an instantaneous source of noise.

Try avoiding all ground loops by using a separate ground wire for every sensor and component. Terminate them all to a common point (usually the power supply ground).

I am also using external power supply with an adapter of 7.5 V DC.

Some adapters have a wide range of voltage output for no-load to full load power. You may find that under no-load condition, there will be 10-12VDC. Fluctuations in load could translate into additional noise and worsened regulation on the Arduino's 5VDC. Have you tried using external regulated 5V with the USB?

Really, the level of error is within tolerance levels of your components (as mentioned by others). If the 33K resistor is ±5%, this could easily be replaced with a more accurate type.

You can do a test to see how much of the error is due to resistor tolerance or sensor tolerance. If initially, you were getting a spread of 5 counts: Swap and get readings for your sensors using the same resistor and analog input. If your variance of readings is reduced to 2 counts, then the remaining 3 counts would be due to the resistor tolerances.

that is how life is! Nothing is ABSOLUTE! Electronics is often 10% (or more) off. Thats the way it is!! We can do things to minimize the effect by adding more electronics to cope...

Look at changes (trend).. more than the actual value.

Riva: Or read the same ADC twice but discard the first reading.

+1 Read the micro datasheet --> it is mandatory each time you change input or change ADC voltage reference. The first reading can be false.

Unless you have a stable supply to the sensors AND have a good reference for the ADC, you are going to get variable readings. 5% is probably pretty good if you don't have a good reference and supply to the sensors configured. For sensor variation, you can have a "calibration factor" that you setup in eeprom that gets used in the final calculation but that only works for sensor variations. Unless you have the voltages stable, you are going to get variable responses.

@Arctic_Eddie

I did put delay and check, even then the temperature is not stable. I get one bit variation in my ADC output

Move the capacitor to the thermistor as it's more likely to be an instantaneous source of noise.[/quote]

Do you mean to say that I put the capacitor between powersupply and the output voltage which is across thermistor?