Wednesday, July 16, 2014

Arduino waitForButtonPress function

Lots of programming robotics languages (RobotC, leJOS NXJ, Cricket Logo, NXT-G) have functions that allow you to suspend processes while waiting for some kind of input. My robotics students most learned about leJOS NXJ's Button.waitForAnyPress() method. When we moved on to programming Arduinos one of them wanted to use the same concept to run a sensor calibration routine in setup(). So we had to make one, and it turned out to be very easy. She was initially trying to do something complicated with boolean variables but I remembered using this simple construct in
RobotC:

while(SensorValue(touchSensor) == 0)  // while the Touch Sensor is inactive (hasn't been pressed):
  {
    // DO NOTHING (wait for press)
  }

and thought something similar should be possible in Arduino. Here is what we worked out:

while(digitalRead(buttonPin) == HIGH) {
    //program will sit here until button is pressed (LOW)
  }

We turned that into a function and added a little debounce wait time and had ourselves a very nice waitForPress() function to call in our programs. The button is HIGH, or not pressed, by default, which we achieve by setting the pinMode to INPUT_PULLUP in setup, using the Arduino's internal pullup resistor. Here is what the function looks like, with an added delay to provide a debounce:

void waitForPress() {
  while(digitalRead(buttonPin) == HIGH) {
    //program will sit here until button is pressed (LOW)
  } 
  delay(1000); //delay for button debounce
}

Now students could call waitForPress() in setup to run a calibration routine in setup, like

  Serial.println("Turn lights ON and press the button.");
  waitForPress();
  recordMaxLight();
  Serial.println("Turn lights OFF and press the button.");
  waitForPress();
  recordMinLight();
  calibrateLightSensor();

with the function calls defined as:

void recordMaxLight() {
  maxLightVal = analogRead(ldrPin); //ldrPin is light dependent resistor
}
void recordMinLight() {
  minLightVal = analogRead(ldrPin);
}
int calibrateLightSensor() {
  ldrThreshhold = (maxLightVal + minLightVal) / 2;
  Serial.print("calibrated threshhold: ");
  Serial.println(ldrThreshhold);
  return ldrThreshhold;
}

No comments :