Simple Keyboard matrix with Teensy 4.1

Status
Not open for further replies.

jrsmile

Member
Hi There,
i just registered to ask a question,
i have a problem with my first Handwired Keyboard.
whenever i push a key it also sends the key in the row above, i have watched several images of keyboards and i am nearly sure it is not the diode direction i got wrong, i probed every cable for shortcircuits but could not find any,could someone have a look and point me in the right direction?

the code is for a teensy 4.1 derived from one here on the forum, it coundn't be much simpler.
but still whenenver i press "q" or "a" i get "qa" if i hold "q" or "a" i get "qaaaaaa"

i just want nkro to work :-(

Code:
/*
 * Programming by Stefan Jakobsson, 2019
 * Released to public domain
 */
 
#define ROW_COUNT 2        //Number of rows in the keyboard matrix
#define COL_COUNT 4       //Number of columns in the keyboard matrix

#define DEBOUNCE 10         //Adjust as needed: increase if bouncing problem, decrease if not all keypresses register; not less than 2
#define SCAN_DELAY 5        //Delay between scan cycles in ms

#define KEY_UNDEFINED -1    //For keyboard matrix positions not in use

int rowPins[] = {2, 3};   //Teensy pins attached to matrix rows
int colPins[] = {7, 6, 5, 4};  //Teensy pins attached to matrix columns

//Key codes for layer 0 (standard layer)
int layer_0[] = {KEY_Q, KEY_W, KEY_E, KEY_R, 
                 KEY_A, KEY_S, KEY_D, KEY_F};

int currentRow = 0;
int keyStatus[ROW_COUNT*COL_COUNT];

void setup() {
  //Row pins
  pinMode(rowPins[0], OUTPUT);
  digitalWrite(rowPins[0], LOW);
  
  int i;
  for (i=1;i<ROW_COUNT;i++){
    pinMode(rowPins[i], INPUT);
  }

  //Column pins
  for (i=0;i<COL_COUNT;i++){
    pinMode(colPins[i], INPUT_PULLUP);
  }

  //Clear keyStatus
  for (i=0;i<ROW_COUNT*COL_COUNT;i++){
    keyStatus[i]=0;
  }
}

void loop() {
  scanKeys();
  delay(SCAN_DELAY);
}

/*
 * Scan keyboard matrix, results stored in keyStatus array
 * 
 * Key status values:
 * DEBOUNCE*2                   = key press event
 * DEBOUNCE+1 to DEBOUNCE*2-1   = key down
 * DEBOUNCE                     = key release event
 * 0 to DEBOUNCE-1              = key up
*/
void scanKeys(){
  int i;
  for (i=0;i<ROW_COUNT*COL_COUNT;i++){
    int pin = getKeyPin(i);
    
    if (keyStatus[i]==0 && digitalRead(pin)==LOW){
      //Key press event
      keyStatus[i] = DEBOUNCE*2;
      keyPress(i);
    }
    else if (keyStatus[i]>DEBOUNCE+1){
      keyStatus[i]--;
    }
    else if (keyStatus[i]==DEBOUNCE+1 && digitalRead(pin)==HIGH){
      //Key release event
      keyStatus[i]--;
      keyRelease(i);
    }
    else if (keyStatus[i]>0 && keyStatus[i]<=DEBOUNCE){
      keyStatus[i]--;
    }
  }
}

/*
 * Returns input pin to be read by keyScan method
 * 
 * Param key is the keyboard matrix scan code (row * COL_COUNT + col)
 */
int getKeyPin(int key){
  int p = key/COL_COUNT;
  if (p != currentRow){
    pinMode(rowPins[currentRow], INPUT);
    pinMode(rowPins[p], OUTPUT);
    digitalWrite(rowPins[p], LOW);
    currentRow=p;
  }
  return colPins[key % COL_COUNT];
}

/*
 * Sends key press event
 * 
 * Param keyCode is the keyboard matrix scan code (row * COL_COUNT + col)
 */

void keyPress(int keyCode){
  if (layer_0[keyCode]!=KEY_UNDEFINED){
    Keyboard.press(layer_0[keyCode]);
  }
}

/*
 * Sends key release event
 * 
 * Param keyCode is the keyboard matrix scan code (row * COL_COUNT + col)
 */
 
void keyRelease(int keyCode){
  if (layer_0[keyCode]!=KEY_UNDEFINED){
    Keyboard.release(layer_0[keyCode]);
  }
}

/*
 * Relases all keys in the layer; called upon change of layer, i.e. press or release of FN key
 * 
 * Param layer[] array of key codes for the layer to be released
 */
void releaseLayer(int layer[]){
  int i;
  for (i=0;i<ROW_COUNT*COL_COUNT;i++){
    if (isKeyDown(i)){
      keyStatus[i] = DEBOUNCE;
      Keyboard.release(layer[i]);
    }
  }
}

/*
 * Returns 0 if the specified key is pressed, otherwise a value not equal to 0
 * 
 * Param keyCode is the keyboard matrix scan code (row * COL_COUNT * col)
 */
 int isKeyDown(int keyCode){
 if (keyStatus[keyCode]>DEBOUNCE) return 1; else return 0; 
}

IMG_20200726_134233_small.jpg
IMG_20200726_134304_small.jpg
IMG_20200726_134318_small.jpg
 
Try adding a delay here:

Code:
int getKeyPin(int key){
  int p = key/COL_COUNT;
  if (p != currentRow){
    pinMode(rowPins[currentRow], INPUT);
    pinMode(rowPins[p], OUTPUT);
    digitalWrite(rowPins[p], LOW);
    currentRow=p;
  }
  ///////////////////////////////////////////////////////////////
  delayMicroseconds(200);
  ///////////////////////////////////////////////////////////////
  return colPins[key % COL_COUNT];
}

You have a delay at the end of loop(), but that is not where you need it. The delay is needed between where you write to the rows and where you read from the columns. Teensy 4.1 runs extremely fast. A lot of code can execute before the voltage on those columns can change!
 
Try adding a delay here:

You have a delay at the end of loop(), but that is not where you need it. The delay is needed between where you write to the rows and where you read from the columns. Teensy 4.1 runs extremely fast. A lot of code can execute before the voltage on those columns can change!

PERFECT! it works flawlessly, thank you very much. Thats what i call Customer Support. ;)
 
Status
Not open for further replies.
Back
Top