Well, I am trying to read many sensors at once with Arduino Ethernet board, better said all my AD inputs are connected: AD0-4 to AMPLOC 25 current sensors (quite low output resistance, directly connected to AD inputs) and AD5 is a voltage divider, scanning solar array voltage (0-40V).
I do a continuous loop through all AD inputs as fast as possible and my server is reading summary values each minute over the ethernet interface. It simply reads sum of all AD reads on each AD input and a loop counter. The server divides the sum by a counter and gets an average value on the AD input for the finished minute. The goal was to measure power consumptions precisely.
Problem was, that the AMPLOC's are very sensitive and I needed to get a long term precision of one tenth of AD digit, that seemed unrealistic with Arduino. The zero value (sensor has a zero current value at half of the range, that is 2.5V when Vcc is taken from the +5V Arduino source and Arduino reference is set to Vcc), varied +-1AD digit minimum through the day. That is not much, but makes quite a difference in the measurement.
I started to read through the forums and soon I found this topic and tried the doubled AD reads (one blind to switch the mux and second to get the data) but I still got the AD reads influencing each other. Not much, but still... Please note, that I do not want to insert big delays, because I need as much measurements per minute, as possible. The code was like this:
Code: Select all
AD0 = analogRead(0);
analogRead(1); //switch mux to the next input to stabilize, discard this read
ADD0 = ADD0+AD0; // some math to remember max, min and sum values. It gives some time to the mux cap to charge
MAX0 = max (AD0,MAX0);
MIN0 = min (AD0,MIN0);
AD1 = analogRead(1); //read A1 value
analogRead(2); //switch mux to the next input to stabilize, discard this read
.....
At the end I found some reply here, that someone discharged the mux capacitor between the reads by switching the mux cap to a grounded AD input. I had no free AD input to test it, but at this moment I realized, that the only AD input, which does not vary a lot, is the internal thermal sensor at AD8. So I tried to insert an analogRead of the thermal sensor to (dis)charge the mux capacitor to a stable value before all reads, something like:
(please note that the following code is an example, you cannot use analogRead(8) with the Arduino Ethernet board, you have to use alternative analogRead routine, the Arduino internal will make analogRead(0) instead of analogRead(8), it does not take input numbers 8 and above)
Code: Select all
AD0 = analogRead(0); // read the A0 value
analogRead(8); // discharge the mux cap to stable temp value (+-10 digits do not matter)
analogRead(1); //switch mux to the next input to charge the mux cap (discard this read)
ADD0 = ADD0+AD0; // remember values
MAX0 = max (AD0,MAX0);
MIN0 = min (AD0,MIN0);
AD1 = analogRead(1);
analogRead(8); // discard the mux cap to stable temp value (+-10 digits do not matter)
analogRead(2); //switch mux to the next input to charge the mux cap, discard this read
etc...
This is much better! The long term AMPLOC sensor zero value precision is really in the range of 0.1 AD digits, that is perfect. Running this loop for all 6 inputs gives me a loop frequency around 260Hz. Not much but at least something with stable values.
Maybe this helps someone. If you have any further suggestions, please keep me posted.