Weird behaviour of the Serial library.

Hi everybody!

I am trying to read the information coming out of a mechanical treadmill.
The treadmill has a simple reed switch that connects each time a small magnets passes by it as you walk. Using analogRead I found out that each time the magnet passes I get a series of "0" values (0, 0, 0, 0, 0, 0, 0) from the analog pin i am using, and the rest of the time i can a jumble of random numbers, including some 0's once in a while (123, 1232, 766, 0, 123, 114, 1231, 0).

To find out when someone is walking on the treadmil, I wrote up this code which I expect to detect when a series of at least five 0's is coming from the analog pin (technically the code detects any charachter that repeats more than 5 times in a row).

This is when I got some really weird behaviour from the Serial library I do not understand.
While debugging, I discovered that if I send another "Serial.println()" command at the end of the loop function, the code works as expected. Without that line it doesn't work as expected and I get a constant stream of false "walking" signals.

I have no idea why this happens but I suspect this has to do with the Serial buffer or the way the library works, but I'm not sure.

Any suggestions or ideas why that line at the end of the code makes the above If statements work as intended?

Thanks!

int sensorPin = A0;
int sensorValue = 0;
int lastSensorValue = 100;
int counter = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {

  sensorValue = analogRead(sensorPin);
  
  if (sensorValue == lastSensorValue) {
    counter++;
  } else if (sensorValue != lastSensorValue && counter > 5) {
    Serial.println("walking");
    counter = 0;
  } else if (sensorValue != lastSensorValue && counter < 5) {
    counter = 0;
  }


// the line below makes this work, for some reason.
// without this i get a constant stream of "walking" messages.

  Serial.println("");
  
  lastSensorValue = sensorValue;
}

I suggest the use of pullup-resistor. It will prevent the random readings when reed switch is open. I don't understand why you use analog reading of a digital signal.

Your loop runs hundreds or even thousands of times every second.
Your if statement continue to be true and counter increase as long as your sequence of identical readings continue.
It would be interesting to see how high it goes. Print counter instead of "walking".

Why are you using analogRead() ?

It would seem to be more sensible to use digitalRead() with a digital sensor.
My suggestion would be to use digitalRead() with INPUT_PULLUP in the pinMode() for the input pin and arrange for the input pin to be pulled LOW by the reed switch. The input will probably need debouncing to avoid false multiple triggers and you could even do this crudely by using a small delay() after each reading.

As it is, the Serial.println() at the end of loop() is providing a small delay that debounces the input.

Thanks for the advice!

This sounds great and makes sense - will try it out tomorrow. One question just to clarify, what do you mean by:

UKHeliBob:
arrange for the input pin to be pulled LOW by the reed switch.

Once I connect to a digital pin and set the pin mode to INPUT_PULLUP is there anything else I should change in the circuitry itself?

Thanks!

Once I connect to a digital pin and set the pin mode to INPUT_PULLUP is there anything else I should change in the circuitry itself?

Not if the input pin is already being pulled LOW when the reed switch is closed.

Sounds like you might be confused about what "pulled low" means. It means being connected to ground (as when you close your switch).

--Michael

Edit: I should have said this better. It means forcing the voltage present on an input pin to be low enough that the processor will read it as a 0. Connecting the pin to ground through a switch is one way.
--M.