Averaging Digital input.

I have a digital input that is 0 volts when dry and 5 volts when wet. I have it showing in my software. Every now and then I get a false wet or dry. I think what I want to do is average the input after a hundred samples or so. What would be the proper way of doing this?

Write the values in an array, sum them all up and divide by the number of measurements. Round the result.

The best thing would be to find out why the false readings happen and eliminate the problem.

No need to average the readings. If you cannot prevent the false readings then you could, perhaps, take 100 readings, adding each to a running total and if the total is not zero or 100 then discard that set, otherwise regard the set as valid and record/display the value as wet or dry as appropriate. How often are the readings taken ?

You could also utilize a debounce to ensure that the reading is only valid if it's been that way for X # of milli/microseconds.

Another simple filter for a isolated spikes is to require a data value change to be presented for two or three readings before believing it.

"Tell me once, tell me twice; what you tell me three times I believe is true."

(Edit: You could say this is a way to implement Arrch's proposal.)

-br

This is one of the final hurdles before taking this to Beta test. So time is of the essence.

Write the values in an array, sum them all up and divide by the number of measurements. Round the result.

This looks like a good avenue and the least to learn.

The best thing would be to find out why the false readings happen and eliminate the problem.

I have only seen one false bit of data, and I may have caused it. However I don't want this device kicking out over a bit of noise.

No need to average the readings. If you cannot prevent the false readings then you could, perhaps, take 100 readings, adding each to a running total and if the total is not zero or 100 then discard that set, otherwise regard the set as valid and record/display the value as wet or dry as appropriate.

The logic is to check if the tank is wet before filling ( not empty ) If wet redirect to manual drain, so the culling process would not need to be so severe. This is mainly a safety to prevent overflow.

How often are the readings taken ?

Right now in the main loop. I am only using it for filling but I might want it in other states also like draining, abort fill and such.

You could also utilize a debounce to ensure that the reading is only valid if it's been that way for X # of milli/microseconds.

This is where I started and soon got frustrated.
Creative juices running low at this time.

Another simple filter for a isolated spikes is to require a data value change to be presented for two or three readings before believing it.

"Tell me once, tell me twice; what you tell me three times I believe is true."

(Edit: You could say this is a way to implement Arrch's proposal.)

This is a viable approach but more like tell me 50 times that you are wet I will act.
And I guess it would work pretty much the same if dry

Any code snippets would be greatly appreciated as it has been a long project burning the candle at work and at home and I now am having trouble braining anymore.

There is a debounce example that you should take a look at. It pretty much does exactly what you need, you just have to define the interval.

This is untested code but maybe something like this? The last 16 times (unsigned int) through the loop must match for reading to count as high or low. You could maybe use unsigned long if the loop is tight so you need 32 matching readings or byte for only 8 readings.

unsigned int readBits = 0;

void loop(){
  readBits = readBits << 1;
  if (digitalRead(WetDry) == HIGH) {
    bitSet(readBits,0);
  }
  // Do other stuff

  switch (readBits) {
    case 0xFFFF:
    // Set
      break;
    case 0x0:
    // Clear
      break;
    case default:
    // Not valid (do nothing)
      break;
  }
}

Untested code, but you will see the idea

int levelTotal = 0;
for (int level = 0;level <= 99;level++)
{
  //code here to get sensorReading (0 or 1)
  levelTotal = levelTotal + sensorReading;
}
if {levelTotal != 100)
{
  Serial.println("The tank is not wet");
}