[Solved] Unable to Detect Key Release

I am trying to create a keyboard, but before turning it loose with keypresses I’d like to test the logic on the serial monitor.

I should only see " pressed" once per button press, and should print " released" on release. However I get a constant stream of " pressed" until I release it. On the bright side, the statement corresponding to the intended button appears, just constantly.

My best guess is that there is something going on in my switch statement near the end of the code, or in the if…else statement starting a few lines before that.

I’m using a ProMicro board.

#include <Keyboard.h>

byte keyPins[] = {2, 3, 4, 5, 6}; //Pins numbers assigned as inputs
byte ctrl = 128;  //defining variables to send ACII values
byte shift = 129;
byte alt = 130;
byte esc = 177;
byte num8 = 56;

#define NUMBUTTONS sizeof(keyPins)

boolean buttonState[NUMBUTTONS];
boolean buttonStatePrev[NUMBUTTONS];

long debouncePrev[NUMBUTTONS]; //array of last times buttons changes states
long debounceDelay = 25; //debounce time


void setup() {
  //Keyboard.begin();
  Serial.begin(9600);
  //for loop initiates variables
  for (int i = 0; i<NUMBUTTONS; i++){
    pinMode(keyPins[i],INPUT_PULLUP);
    buttonStatePrev[i] = false;
    debouncePrev[i] = 0;
  }
}

void loop() {
  checkButtons(); //calls function to read button states into array
  sendSignals(); //sends signals based on what buttons change states
}

void checkButtons(){ //function to read button states into array
  for (int i=0; i<NUMBUTTONS; i++) {
      buttonState[i] = (digitalRead(keyPins[i]) == LOW); //LOW returns true if button is pressed
  }
}

void sendSignals() { //function to send pressed key commands to computer
  boolean ChangedUp[NUMBUTTONS]; //boolean to determine whether key changed to pressed
  for(int i=0; i<NUMBUTTONS; i++){ChangedUp[i] = false;} //initialize to false
  boolean ChangedDown[NUMBUTTONS]; //boolean to determine whether key changed to unpressed
  for(int i=0; i<NUMBUTTONS; i++){ChangedDown[i] = false;} //initialize to false

  
  for(int i=0; i<NUMBUTTONS; i++) {
    if((buttonState[i] != buttonStatePrev[i]) && (debouncePrev[i] + debounceDelay <= millis())){
      if(buttonState[i] == true){
        ChangedUp[i] = true; //builds array determining whether button changed state to pressed
      }
      else{
        ChangedDown[i] = true; //builds array determining whether button changed state to released
      }
        debouncePrev[i] = millis(); //update debounce array
    }
  }
  for(int i=0; i<NUMBUTTONS; i++) {
    switch(i){
      case 0: //PIN 2, ctrl button
        if(ChangedUp[i] == true) Serial.println("ctrl pressed");
        else if(ChangedDown[i] == true) Serial.println("ctrl released");
        break;
      case 1: // PIN 3, shift button
        if(ChangedUp[i] == true) Serial.println("shift pressed");
        else if(ChangedDown[i] == true) Serial.println("shift released");
        break;
      case 2: // PIN 4, alt button
        if(ChangedUp[i] == true) Serial.println("alt pressed");
        else if(ChangedDown[i] == true) Serial.println("alt released");
        break;
      case 3: //PIN 5, esc button
        if(ChangedUp[i] == true) Serial.println("esc pressed");
        else if(ChangedDown[i] == true) Serial.println("esc released");
        break;
      case 4: //PIN 6, ctrl + 8
        if(ChangedUp[i] == true){
          /*Keyboard.press(ctrl);
          Keyboard.press(num8);
          Keyboard.release(num8);
          Keyboard.release(ctrl);*/
          Serial.println("Normal");
        }
        break;
      }
  }
}

HI, ? ? ? Please go up and read your post, what the blazes are you talking about. Anybody reading your first post will shut off and not bother when they see how it is constructed.

Please write a proper introduction to your post.

Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html

What is your code supposed to do? What does your code do? What model Arduino are you using?

Tom... :)

I've edited a couple times to try and make it more clear.

I found it, turns out I never updated the array that was keeping track of the last state the button was in, so it always thought that it was not pressed the last time it checked. Here is the working code. Lines 52 and 56 were added to properly keep track of the prior state of the button.

#include <Keyboard.h>

byte keyPins[] = {2, 3, 4, 5, 6}; //Pins numbers assigned as inputs
byte ctrl = 128;  //defining variables to send ACII values
byte shift = 129;
byte alt = 130;
byte esc = 177;
byte num8 = 56;

#define NUMBUTTONS sizeof(keyPins)

boolean buttonState[NUMBUTTONS];
boolean buttonStatePrev[NUMBUTTONS];

long debouncePrev[NUMBUTTONS]; //array of last times buttons changes states
long debounceDelay = 25; //debounce time


void setup() {
  //Keyboard.begin();
  Serial.begin(9600);
  //for loop initiates variables
  for (int i = 0; i<NUMBUTTONS; i++){
    pinMode(keyPins[i],INPUT_PULLUP);
    buttonStatePrev[i] = false;
    debouncePrev[i] = 0;
  }
}

void loop() {
  checkButtons(); //calls function to read button states into array
  sendSignals(); //sends signals based on what buttons change states
}

void checkButtons(){ //function to read button states into array
  for (int i=0; i<NUMBUTTONS; i++) {
      buttonState[i] = (digitalRead(keyPins[i]) == LOW); //LOW returns true if button is pressed
  }
}

void sendSignals() { //function to send pressed key commands to computer
  boolean ChangedUp[NUMBUTTONS]; //boolean to determine whether key changed to pressed
  for(int i=0; i<NUMBUTTONS; i++){ChangedUp[i] = false;} //initialize to false
  boolean ChangedDown[NUMBUTTONS]; //boolean to determine whether key changed to unpressed
  for(int i=0; i<NUMBUTTONS; i++){ChangedDown[i] = false;} //initialize to false

  
  for(int i=0; i<NUMBUTTONS; i++) {
    if((buttonState[i] != buttonStatePrev[i]) && (debouncePrev[i] + debounceDelay <= millis())){
      if(buttonState[i] == true){
        ChangedUp[i] = true; //builds array determining whether button changed state to pressed
        buttonStatePrev[i] = buttonState[i];
      }
      else{
        ChangedDown[i] = true; //builds array determining whether button changed state to released
        buttonStatePrev[i] = buttonState[i];
      }
        debouncePrev[i] = millis(); //update debounce array
    }
  }
  for(int i=0; i<NUMBUTTONS; i++) {
    switch(i){
      case 0: //PIN 2, ctrl button
        if(ChangedUp[i] == true) Serial.println("ctrl pressed");
        else if(ChangedDown[i] == true) Serial.println("ctrl released");
        break;
      case 1: // PIN 3, shift button
        if(ChangedUp[i] == true) Serial.println("shift pressed");
        else if(ChangedDown[i] == true) Serial.println("shift released");
        break;
      case 2: // PIN 4, alt button
        if(ChangedUp[i] == true) Serial.println("alt pressed");
        else if(ChangedDown[i] == true) Serial.println("alt released");
        break;
      case 3: //PIN 5, esc button
        if(ChangedUp[i] == true) Serial.println("esc pressed");
        else if(ChangedDown[i] == true) Serial.println("esc released");
        break;
      case 4: //PIN 6, ctrl + 8
        if(ChangedUp[i] == true){
          /*Keyboard.press(ctrl);
          Keyboard.press(num8);
          Keyboard.release(num8);
          Keyboard.release(ctrl);*/
          Serial.println("Normal");
        }
        break;
      }
  }
}