Teensy 4.1 keyboard controller — setting pinMode() requires delay?

JCalhoun

Member
I've done a few keyboards using the Teensy 2.0. Trying the same code with a Teensy 4.1 and ran into some strange behavior, failure.

A simple test app I wrote to try to track down the problem is suggesting that when I press single key, the keyboard scanning is detecting LOW on a couple of column pins when calling digitalRead() when only a single column pin should return LOW.

As this code scans rows/columns in a matrix fashion, it activates one row at a time (setting pinMode() of the row to OUTPUT) sweeps the columns looking for LOW on digitalRead() and then moves on to the next row (sets the previous row pinMode() back to INPUT, sets the new row pinMode() to INPUT).

My only thought was that perhaps the speed of the Teensy 4.1 is such that I may need to pause just a touch after activating a row before testing the column pins. Adding delay(1) after activating a row pin did in fact seem to fix the issue in my test app. Now only a single row/column comes back LOW from digitalRead() when a single key is pressed.

Is this correct? Is it known that slamming pinMode() in a tight loop on the Teensy 4.1 can give false-positives?
 
Yes, this in indeed a very well known problem with multiplexing, either row-column scanning or analog mux chips like 74HC4067 and 74HC4051. It has come up over and over on this forum.

The signal voltage simply takes a brief time to change. The time depends on the circuit's impedance and the amount of unintentional capacitance the pins and wires have. Usually these times are so short that it fully changes during the natural time 8 bit code at 16 MHz can execute. But 32 bit code at 600 MHz on a processor that can execute 2 instructions per cycle runs so much faster. You need a delay between changing the pinMode() and which column is driven, or changing the mux select pins, and when you read the resulting signal.
 
Back
Top