Keyboard pullup resistors

Hello,

I made a post a while ago under programming questions (Teensy keyboard troubleshooting) but I've realised it's actually a hardware problem so am creating a new thread in (hopefully) the right place.

I am building a keyboard and having trouble with the matrix. I am using a Teensy 4.1, with the code found here (at bottom of this post also): https://www.gammon.com.au/forum/?id=14175

Upon advice from the previous thread, I have added pullup resistors on all the rows and columns. I have tried both 4.7k and 10k resistors with limited success.
Previously I was having trouble with each key registering a key press for both the key intended and the key below. Using any value resistor has reduced most of this.

Issues I am still having include:

  • Some keys output the key below. E.g. Key 0 outputs 'Key 22 pressed'
  • Some keys don't register a key press at all, or only work occasionally
  • Some keys registering multiple presses each time.

All switches and diodes have been tested, and there are no shorts.

Key layout is 22 columns, 6 rows

Key outputs using 4.7k resistors are in the images here (Apologies, I think I'm too new to upload photos directly).

On column 6, all the keys were registering multiple key presses. I assumed this was due to too little resistance. I've tried replacing the 4.7k with a 10k and a 6.8k, and both give no output. I've also tried 470ohm and 1k and those outputted multiple key presses for key 6 and 28 when pressing key 6.
I've tried changing some of the resistors on the other problematic columns and had similar results.

Any guidance or ideas would be greatly appreciated, many thanks in advance.

// Keypad_Decoder
//
// Author: Nick Gammon
// Date: 17th February 2018

/*
 *  
 *   
 */

// Outputs to Serial in the format: 0b1nnnnnnn for a key down and 0b0nnnnnnn for a key-up
//            nnnnnnn will be the current row/column combination
//            Also every HEARTBEAT_TIME outputs 0xFF if all keys are up (heartbeat)

#include <limits.h>     /* for CHAR_BIT */

const byte ROWS = 6;
const byte COLS = 22;
const bool ENABLE_PULLUPS = true;  // make false if you are using external pull-ups
const unsigned long DEBOUNCE_TIME = 10;     // milliseconds
const unsigned long HEARTBEAT_TIME = 2000;  // milliseconds
const bool DEBUGGING = true;               // make true for human-readable output

// define here where each row and column is connected to
const byte rowPins [ROWS] = {38,37,36,35,34,33}; //connect to the row pinouts of the keypad
const byte colPins [COLS] = {3,4,5,6,7,8,9,10,11,12,13,14,40,24,25,26,27,28,29,30,31,32}; //connect to the column pinouts of the keypad


// See: http://c-faq.com/misc/bitsets.html

#define BITMASK(b) (1 << ((b) % CHAR_BIT))
#define BITSLOT(b) ((b) / CHAR_BIT)
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
#define BITCLEAR(a, b) ((a)[BITSLOT(b)] &= ~BITMASK(b))
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))

// number of items in an array
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

// total number of keys
const byte TOTAL_KEYS = ROWS * COLS;

// remember previous setting of each key
char lastKeySetting [(TOTAL_KEYS + CHAR_BIT - 1) / CHAR_BIT];  // one bit each, 0 = up, 1 = down
unsigned long lastKeyTime [TOTAL_KEYS];       // when that key last changed
unsigned long lastHeartbeat;                  // when we last sent the heartbeat

void setup ()
{
  Serial.begin (115200);
  while (!Serial) { }  // wait for Serial to become ready (Leonardo etc.)

  // set each column to input-pullup (optional)
  if (ENABLE_PULLUPS)
    for (byte i = 0; i < COLS; i++)
      pinMode (colPins [i], INPUT_PULLUP);

}  // end of setup

void loop ()
  {
  byte keyNumber = 0;
  unsigned long now = millis ();  // for debouncing

  // check each row
  for (byte row = 0; row < ROWS; row++)
    {
    // set that row to OUTPUT and LOW
    pinMode (rowPins [row], OUTPUT);
    digitalWrite (rowPins [row], LOW);

    // check each column to see if the switch has driven that column LOW
    for (byte col = 0; col < COLS; col++)
      {
      // debounce - ignore if not enough time has elapsed since last change
      if (now - lastKeyTime [keyNumber] >= DEBOUNCE_TIME)
        {
        bool keyState = digitalRead (colPins [col]) == LOW; // true means pressed
        if (keyState != (BITTEST (lastKeySetting, keyNumber) != 0)) // changed?
          {
          lastKeyTime [keyNumber] = now;  // remember time it changed
          // remember new state
          if (keyState)
            BITSET (lastKeySetting, keyNumber);
          else
            BITCLEAR (lastKeySetting, keyNumber);
          if (DEBUGGING)
            {
            Serial.print (F("Key "));
            Serial.print (keyNumber);
            if (keyState)
              Serial.println (F(" down."));
            else
              Serial.println (F(" up."));
            }  // if debugging
          else
            Serial.write ((keyState ? 0x80 : 0x00) | keyNumber);
          }  // if key state has changed
        }  // debounce time up
      keyNumber++;
      } // end of for each column

    // put row back to high-impedance (input)
    pinMode (rowPins [row], INPUT);
    }  // end of for each row

  // Send a heartbeat code (0xFF) every few seconds in case
  // the receiver loses an occasional keyup.
  // Only send if all keys are not pressed (presumably the normal state).
  if (now - lastHeartbeat >= HEARTBEAT_TIME)
    {
    lastHeartbeat = now;
    bool allUp = true;
    for (byte i = 0; i < ARRAY_SIZE (lastKeySetting); i++)
      if (lastKeySetting [i])
        allUp = false;
    if (allUp)
      {
      if (DEBUGGING)
        Serial.println (F("No keys pressed."));
      else
        Serial.write (0xFF);
      } // end of all keys up
    } // end if time for heartbeat
  } // end of loop

The code looks good to me so I would guess a loose connection or short circuit somewhere.

Thanks for your reply. I've rewired and checked everything several times so it seems unlikely at this point, but I will check again to be sure.

You made it a hardware question, okay. Where is the schematic? A "WeTransfer" link won't do, I can't even access it. Generally, you should be able to just paste images into a post.

Trying to upload the images directly just gives an error. I looked it up before and I believe new users aren't allowed to post images. I've tried several different file types, compressing files, etc, but no joy. Unsure how else to post the pictures.

Upload, or paste?

Still just getting upload error. Is there a 3rd party website I could use to host the images and embed?

Sorry, I think this is a known problem with the forum settings. I'm not sure how long until you can post those. I'm not sure what hosting to suggest. Can you add it as an attachment?

Nope, it's all the same errors unfortunately

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