Button press registers on the 2nd press?

I'm writing a basic finite state machine for use of a project and one of the functionalities is to have 1 button toggle 3 different states/modes of operation. I have it working almost the way I want but there seems to be a small issue with my button presses because I have to press the button twice for it to increment my mode counter. I am using a tinkerkit library for LEDs & Button as well as Servo.h (but didn't get to servo control yet). I have Serial Output whenever I enter the switch statement, however when the button doesn't respond I don't see any print statements, so I don't believe any code besides storing the button's state is done.

/* Do the imports */
#include <TinkerKit.h>
#include <Servo.h>

/* Declare the inputs and outputs */
// Inputs
TKButton button(I0);

//Outputs
Servo lid_servo;
TKLed green_led(O3);
TKLed yellow_led(O2);
TKLed red_led(O1);
//Servo on output header 0

//Set up variables
int currentButtonState = 1;
int lastButtonState = 0;
int current_mode = 1; //Values: 
int last_mode = 0;
//1 - Disabled/Maintenance mode 
//2 - Active Mode
//3 - Manual override mode

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


//Main loop//////////////
void loop() {
  //Read the button state
  currentButtonState = button.readSwitch();
  if (currentButtonState == HIGH && currentButtonState != lastButtonState) {
  current_mode++;
  }
  
  //Record the status of the button to track the most recent button state
  lastButtonState = currentButtonState;
  
  //Run this loop if mode changes
  if (current_mode != last_mode){
    switch(current_mode) {
      
      //This is the disabled mode case
      case 1:
      last_mode = current_mode;
      yellow_led.off();
      green_led.off();
      red_led.on();
      showState();
      break;
   
      //This is the active mode case
      case 2:
      last_mode = current_mode;
      red_led.off();
      yellow_led.off();
      green_led.on();
      showState();
      break;
      
      //This is the manual override mode case
      case 3:
      last_mode = current_mode;
      green_led.off();
      red_led.off();
      yellow_led.on();
      Serial.println("Running the manual override function");
      showState();
      delay(50);
      current_mode = (current_mode % 3) + 1;
      Serial.print("current_mode = ");
      Serial.println(current_mode);
      break;
      }
  }
  delay(5);
}
/////Debug Subroutine
void showState() {
  Serial.print("Mode: ");
  Serial.println(current_mode);
 /* Serial.print("Last mode: ");
  Serial.println(last_mode);
  Serial.print("Current State: ");
  Serial.println(currentButtonState);
  Serial.print("Last state ");
  Serial.println(lastButtonState); */
} 
////////////////////////////

////Servo Control Subroutines

///Distance Check Subroutine

You are assigning last_mode = current_mode before you update current_mode, so it does not actually end up equal to current_mode. Hence your next change detection is wrong.

You could simplify that logic by putting the 'current_mode != last_mode' code inside the block which updates current_mode; this would enable you to eliminate last_mode completely.

I'm not familiar with the TinkerKit library, but if I use a Serial.print to look at the button state right after you do the button.readSwitch(), it seems to toggle on every keypress, which would give you the "every second press" symptoms. Checking the library itself, readSwitch does return a variable called _toggleState.

You mightwant to try this change. Instead of readSwitch...

void loop() {
  //Read the button state
  currentButtonState = button.pressed();

This is the typical case of ID 10 T error....

I looked at the TinkerKit library documentation and I need to use a different method on the button.

I modified the readSwitch to read() and it works!

psychephylax:
This is the typical case of ID 10 T error....

ha! I didn't immediately recognize the ID 10 T error.

We used to call that PEBCAK. "Problem Exists Between Chair And Keyboard"

While I'm at it... you have two redundant calls to showstate(), and two redundantstatements of last_mode = current_mode;. No big deal, but eliminating two of each and moving one to a better place in the code will reduce size by a few bytes.

I finished my project and after my PC crashed and I lost some work but I have everything up and running like I wanted.

I know you refer to redundant calls and assignments but I just wanted to make sure you saw it was a switch statement so it would have to be done when each "mode" is entered. Unless I am missing something?

psychephylax:
I know you refer to redundant calls and assignments but I just wanted to make sure you saw it was a switch statement so it would have to be done when each "mode" is entered. Unless I am missing something?

Well, if you have lots of room in the chip, it's not a real bad thing. I like to get into good habits, and try to eliminate redundant statements. More structure equares to easier meintenance, I think.

Have a look at my state machine library here: http://playground.arduino.cc/Code/SMlib
Be shure to analyse the problem before starting to code. And complete the state diagram.

Here is a example with both state diagram and code:

#include <SM.h>
#define RE(signal, state) (state=(state<<1)|(signal&1)&3)==1//macro to detect raising edge

SM machine(DisabledH, DisabledB);
int ButtonState;
const int green_led = 10;
const int yellow_led = 11;
const int red_led = 12;
const int Button = 2;

void setup(){
  pinMode(green_led, OUTPUT);
  pinMode(yellow_led, OUTPUT);
  pinMode(red_led, OUTPUT);
  Serial.begin(115200);
}//setup()

void loop(){
  EXEC(machine);
}//loop()

State DisabledH(){
  digitalWrite(red_led, 1);
  Serial.println("State: Disabled");
}//DisabledH()

State DisabledB(){
  //other code goes here
  if(RE(digitalRead(Button), ButtonState)){
    machine.Set(ActiveH, ActiveB);
    digitalWrite(red_led, 0);
  }//if(RE)
}//DisabledB

State ActiveH(){
  digitalWrite(green_led,1);
  Serial.println("State: Active");
}//ActiveH()

State ActiveB(){
  //other code goes here
  if(RE(digitalRead(Button), ButtonState)){
    machine.Set(OverrideH, OverrideB);
    digitalWrite(green_led, 0);
  }//if(RE)
}//ActiveB()

State OverrideH(){
  digitalWrite(yellow_led,1);
  Serial.println("State: Override");
}//OverrideH()

State OverrideB(){
  //other code goes here
  if(RE(digitalRead(Button), ButtonState)){
    machine.Set(DisabledH, DisabledB);
    digitalWrite(yellow_led, 0);
  }//if(RE)
}//OverrideB()

state machine 3 states state diagram.png