Intermitent digitalRead problem

I'm using the following function to debounce the push-button of a rotary encoder.
The button uses a Nano's internal pullup resistor.

bool rotaryPress()
{
  bool rotaryButtonPress = false; 
  static bool buttonState = true;
  static bool lastButtonState = true;
  static unsigned long rotaryDbStart = 0;
  const long dbDelay = 50;
  bool sampleButton = false;

  sampleButton = digitalRead(rotaryButtonPin);
  if (!sampleButton) Serial.println("pressed");           // for debugging
  if (sampleButton) Serial.println("not pressed");     // for debugging
  if (lastButtonState)
  {
    rotaryDbStart = millis();
  }
  if (rotaryDbStart + dbDelay < millis())
  {
    if (sampleButton != buttonState)
    {
      buttonState = sampleButton;
      if (buttonState == false)
      {
        rotaryButtonPress = true;
      }
      else rotaryButtonPress = false;
    }
  }
  lastButtonState = sampleButton;

  return rotaryButtonPress;
}

The button debounce function is used in about 7 places in the sketch and works perfectly.
In the 8th place it is called, once the button is pressed, the value of sampleButton never changes, whether the button is released or not.
The only place sanpleButton and rotaryButtonPin appear in the sketch are in this funciton and when rotaryButtonPin is declared and the pin initialised in setup().

As far as I can tell, there is something stopping digitalRead(rotaryButtonPin) from reading a new value. Any thoughts?

Hi,

Is there a reason you are not using a rotary encoder Library?

Can you post a link to the encoder you are using please?

What model Arduino are you using?
Have you got a 0.1uF capacitor between each Arduino input pin to gnd?

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

When I have problems, I divide the code and test it little by little until I find the problem.

There are unnecessary statements in your code and your logic is written in a complex way. Maybe removing everything unnecessary and changing your logic will help you understand what is going on. e.g.

  • rotaryButtonPress is initialized with false and then set to false again

  • sampleButton is initialized and then written again in the next instruction

A good way to reduce logic complexity is to inverse the logic of nested if() statements and early return. Instead of testing a condition and then continue inside you eliminate the inverse. Here is a pseudo code example

Reducing nested if() pseudo code example (click to view)
// Example nested logic
if ( time == time_to_leave_house )
{
  if ( light == light_switched_off )
  {
    if ( door == door_locked )
    {
      return leave_the_house
    }
    else
    {
      return stay_home
    }
  }
}

// Example inverted logic with early return
if ( time != time_to_leave_house )
{
  return stay_home
}

if ( light != light_switched_off )
{
  return stay_home
}

if ( door != door_locked )
{
  return stay_home
}

return leave_the_house

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.