Lower value from the first readout

Hi. I'm using the 4067 multiplexer to read the value of 16 potentiometers and want the arduino to only send the value (over the SimpleMessageSystem in to SuperCollider) if the value has changed. My approach is to first read and store the value of a potentiometer in to an array, wait for some milliseconds, read it again and then compare if a change has been made. If it has, then send it.

With the delay between the two readouts set to 100ms I get this in SuperCollider:
(The first row is the first readout and the second row, the one made 100ms later. And they are from the same potentiometer)

954, 1023
923, 1005
959, 1023
978, 1023
913, 992
1016, 1019
948, 1023
970, 1023
...

The values differ, but I guess that could be evened out (filtered) with a condensator.
The problem is that the first readout is constantly lower than the the one made 100ms later.
Any ideas why? Or another approach maybe?

And the main loop look like this:

void loop() {
int i;
for (i=0; i <16; i++) {
// set which input to read from the multiplexer
digitalWrite(CONTROLpin1, (i&15)>>3);//bit4
digitalWrite(CONTROLpin2, (i&7)>>2);//bit3
digitalWrite(CONTROLpin3, (i&3)>>1);//bit2
digitalWrite(CONTROLpin4, (i&1) );//bit1

oldValueArray = analogRead(0); //store the the value

  • delay(100); // wait*

  • currentValue = analogRead(0); // read it again*
    _ if (abs(currentValue-oldValueArray*) > delta) { //compare, delta=1*_
    _ messageSendInt(oldValueArray*);
    messageSendInt(currentValue);
    messageEnd();
    }
    }
    }*_

What are the data types of your globals? Also, instead of delaying for 100 ms, why not average a number of ADC readings together to get a more representative value of the potentiometer output?

Also you are only asking for the ones that are different by delta so the ones that are the same will never show up, you don't know what percentage are correct.

bens. The globals are all int's. Smart idea to make a average number (it could elliminate the need of filtering the signal). But I dont understand how it could replace the delay(100). Please explain?
(Delay in 100 ms is just for test purpose, in the final version it would be something like 5ms)

Franklin. Yes, but I tried without any if-comparison (just to get the values off the two readouts) and the problem remains. The first readout is constantly lower.

I thought your problem might be due to using unsigned integers rather than integers. If this is not the case, I think your problem is likely due to your not giving the voltage on the analog input pin time to stablize once you select for it from your mux. Try adding a delay of a few microseconds between your last digitalWrite() and your first analogRead(), or perform several analog reads and throw out the first few results as junk.

Also, I wasn't suggesting that you replace your delay(100) with averaging, I was suggesting that you clearly have time to average some results together if you can afford to sit around for 100 ms doing nothing. Even a 5 ms delay is long enough for you to average 40 or 50 values together (in this case the analog reads would replace your delay(5), or you could use a delay(3) and average maybe 20 samples together). My rule of thumb is to always average at least a few analog readings together before relying upon them. Otherwise it's very easy for noise to result in bad/inaccurate readings.

  • Ben

It could be that the voltage hasn't stabilised since you changed the input multiplexor.

Some things to try to see if it is the situation ...

  • wait a short time after switching inputs before taking your first reading.
  • tie all 16 inputs together and see if the value changes.
  • fiddle your code so that it only reads from one input.

You could also use the adc in the Arduino to read lots of values after a quick step change in the pot. position, then see what the response time of the circuit is.

Mike