Teensy keyboard troubleshooting

Hello,

I'm trying to build a keyboard using a Teensy 4.1. I've tried running a few different firmwares I found online but had a problem where the keyboard would output both the key pressed and the key on the row beneath.

There's no obvious shorts/problems in the hardware side of things, so I wanted to check if the problem was in the code I was running. I wrote some short code to print out if a key on a specific row was pressed, with the plan to check each key press outputs the intended row/column pins. In the Arduino IDE, board is set to Teensy 4.1, USB type is "Keyboard".

//Define number of rows and columns in keyboard
const int NUM_ROWS = 6;
const int NUM_COLS = 22;

//Define pin numbers of rows and columns
int rowPins[] = {38,37,36,35,34,33};
int colPins[] = {3,4,5,6,7,8,9,10,11,12,13,14,40,24,25,26,27,28,29,30,31,32};

//test row 1 switches
int R1 = 38;

void setup() {
  Keyboard.begin();

  //test pin 38
  pinMode(R1,INPUT_PULLUP);
  if (digitalRead(R1)) {
    Keyboard.write("pin 38 high");
  } else{
    Keyboard.write("pin 38 low");
  }
  //this part does not print anything

}

void loop() { 
  if (digitalRead(R1)) {
    Keyboard.write("Key on row 1 not pressed"); //does print
    delay(5000);
  } else {
  Keyboard.write("Key on row 1 pressed"); //never prints
  }
}

I've tried this to check a few rows and columns but it never outputs that a key is pressed. I know the switches are wired at least mostly correctly, as the keyboard will type something with a different firmware.
I am getting some funny voltage readings from the pins, but that's likely because it's difficult to hold the multimeter whilst not pressing any keys.

I'm also still learning C, so perhaps (hopefully) the problem is glaringly obvious.

Any help would be greatly appreciated.

each key should be in serial with diode
https://www.gammon.com.au/forum/?id=14175

Thanks for replying. Each key has a diode and is wired like the example. Here's a photo of the wiring (picture wouldn't upload directly)

I ran the debug code from that link and it is showing two key presses for each key pressed. I took the other row wires out of the teensy to narrow down a potential short but still it still registers two key presses.

are you sure the naked row wire is not touching Alu plate?
I don't see any place in sketch where you activate column one by one and read bits in the row.

here

#include "Keyboard.h"

const byte NUM_ROWS = 6;
const byte NUM_COLS = 22;

const byte rowPins[] = {38, 37, 36, 35, 34, 33};
const byte colPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 40, 24, 25, 26, 27, 28, 29, 30, 31, 32};

byte Row = 0;

void setup() {
  Keyboard.begin();
  for (byte i = 0; i < NUM_ROWS; i++) {
    pinMode(rowPins[i], OUTPUT);
  }
}

void loop() {
  digitalWrite(rowPins[Row], HIGH);
  Keyboard.print("Key on row ");
  Keyboard.print(String(Row));
  for (byte i = 0; i < NUM_COLS; i++) {
    if (digitalRead(colPins[i]))Keyboard.println(" not pressed");
    else Keyboard.println(" pressed"); 
  }
  digitalWrite(rowPins[Row], LOW);
  Row++;
  delay(10);
}

Definitely no continuity between the diode rows and the plate, nor the diodes and the black wires. No continuity between rows either.

In my sketch I just manually changed the pin number for simplicity. Thank you for the code

Here's what I've done so far:

  • Checked for shorts/continuity between teensy pins
  • Tested all diodes
  • Ran test code with only one row and one column connected, still getting ghost key presses. Same for all row/column combinations I tested.
  • Swapped row/column assignment in sketch (read some other threads where this was the issue). This gave no output

When I press a key on the bottom row, it's also registering a key press on the top row. I think this would indicates that it's not due to shorts

There are some inconsistencies though, such as:

  • Pressing key 9 registers key 31 9 times
  • Pressing key 33 registers key 55 repeatedly until released
  • Some keys register only the correct key
  • Sometimes the key incorrectly triggered doesn't physically exist in the wiring matrix

Could this be a problem caused by having different numbers of keys in each row? I thought this was necessary due to the layout of the switches.
In one column I only have one key, due to ease of wiring the columns. This always triggers the correct key press. Does this indicate problems with my matrix wiring?

I've just tried taking the column with the single switch out of the equation but no difference.

do you have other dev boards except teensy?

No I only have the one teensy. I struggled to find in stock boards with the amount of pins I needed. Do you think it's a problem with the board?

you say only one column and row using has ghosting. if not the keyboard issue then what ?

Makes sense, I'll get another board ordered and test that. Would you recommend something other than a teensy?

no. but for test reason check other board how it does

The Teensy 4.1 uses the IMXRT1062DVJ6 MCU. I checked the datasheet and the pullup values for GPIO are listed as 22K or 47K or 100K.

Various keyboard designs normally use 10K pullups, some use 4.7K. Some designs use series resistors on the rows or columns (depending on ckt configuration) to deal with issues when multiple keys are press. Also would greatly reduce "ringing" on the signal, as this is a very fast MCU.

I would recommend using 4.7K external pullups on the colPins and series connected 470Ω resistors on the rowPins (preferably located at the output pin).

Overall I'm this should significantly reduce ghosting/crosstalk/ringing. Just need a couple of resistors to test one key to see what happens.

1 Like

You declare Row as a variable (global).
Your loop --

void loop() {
  digitalWrite(rowPins[Row], HIGH);
  Keyboard.print("Key on row ");
  Keyboard.print(String(Row));
  for (byte i = 0; i < NUM_COLS; i++) {
    if (digitalRead(colPins[i]))Keyboard.println(" not pressed");
    else Keyboard.println(" pressed"); 
  }
  digitalWrite(rowPins[Row], LOW);
  Row++;
  delay(10);
}

Row gets Incremented each pass through, but it looks like it never gets
set back to 0 (after the 6th iteration). So, --

void loop() {
  digitalWrite(rowPins[Row], HIGH);
  Keyboard.print("Key on row ");
  Keyboard.print(String(Row));
  for (byte i = 0; i < NUM_COLS; i++) {
    if (digitalRead(colPins[i]))Keyboard.println(" not pressed");
    else Keyboard.println(" pressed"); 
  }
  digitalWrite(rowPins[Row], LOW);
  Row++;
  if(Row > 5)    // Reset Row
  {
    Row = 0;     //  Now Re-cycling
  }
  delay(10);
}

This has fixed the problem for about half the columns, thank you. I'll try 10k to see if it fixes the others.
There's some ghosting when keys are pressed quickly or multiple key are pressed but for now I'll put it down to the code, since it's just a test program. (Running the code prev posted from gammon.com)

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