Computer keyboard (100 keys)

Hello, I am working on a project, its computer keyboard with 100 keys. I use arduino micro, two 74hc595 shift registers, and some chinese keys (i also used one diode for each key). Here is circuit diagram(i forgot to connect some pins on shift registers, but its already fixed on pcb):

I already have some working code, but its still far from the behavior of the normal computer keyboard. What i want now, is modify the code, so i can use also function keys properly. But i dont really know how
here is code:


//library
#include <Keyboard.h>


//defining pins for registers

//register IC2
int colData1 = 2;
int colLatch1 = 3;
int colClock1 = 4;
//register IC1
int colData2 = 5;
int colLatch2 = 6;
int colClock2 = 7;

byte shiftcols1 = B11111111;
byte shiftcols2 = B11111111;

//defining rows
int rowA = A1; 
int rowB = A2; 
int rowC = A3;
int rowD = A4;
int rowE = A5;
int rowF = 10;
int rowG = 9;
int rowH = 8;

int ColToCheck1 = 0;
int ColToCheck2 = 0;

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;


long previousKeyboardMicros = 0;
long keyboardInterval = 500;

//arrays
const byte shiftCol1[8] = {B01111111, B10111111, B11011111, B11101111, B11110111, B11111011, B11111101, B11111110};
const byte shiftCol2[8] = {B01111111, B10111111, B11011111, B11101111, B11110111, B11111011, B11111101, B11111110};

const char keys[8][14] = {
  {'0','1','2','3','4','7','8','9',KEY_END,KEY_PAGE_DOWN,'0',KEY_F5,KEY_F10,'0'},
  {KEY_LEFT_CTRL,'`',KEY_F1,KEY_F2,'5','6','=',KEY_F8,KEY_HOME,KEY_PAGE_UP,KEY_INSERT,KEY_DELETE,KEY_F9,'-'},
  {'x','0','0','0','b','n','0',KEY_RIGHT_GUI,KEY_LEFT_ARROW,KEY_KP_MINUS,KEY_RIGHT_ARROW,KEY_DOWN_ARROW,KEY_F12,'/'},
  {'0','z','x','c','v','m',',','.','0',KEY_KP_ASTERISK,KEY_KP_SLASH,KEY_NUM_LOCK,KEY_RETURN,'ň'},
  {KEY_LEFT_ALT,KEY_ESC,'0',KEY_F4,'g','h',KEY_F6,'0',KEY_UP_ARROW,KEY_KP_DOT,KEY_KP_0,' ',KEY_F11,'x'},
  {';','a','s','d','f','j','k','l',KEY_KP_ENTER,KEY_KP_3,KEY_KP_2,KEY_KP_1,KEY_RIGHT_SHIFT,KEY_LEFT_GUI},
  {'[',KEY_TAB,KEY_CAPS_LOCK,KEY_F3,'t','y',']',KEY_F7,KEY_RIGHT_CTRL,KEY_KP_6,KEY_KP_5,KEY_KP_4,KEY_LEFT_SHIFT,KEY_BACKSPACE},
  {'[','q','w','e','r','u','i','o',KEY_KP_PLUS,KEY_KP_9,KEY_KP_8,KEY_KP_7,'p','0'},
};
void setup() {
  delay(5000);     //protection
  Keyboard.begin();
  Serial.begin(9600);
  //pinmode for rows
  pinMode(rowA, INPUT_PULLUP);
  pinMode(rowB, INPUT_PULLUP);
  pinMode(rowC, INPUT_PULLUP);
  pinMode(rowD, INPUT_PULLUP);
  pinMode(rowE, INPUT_PULLUP); 
  pinMode(rowF, INPUT_PULLUP);
  pinMode(rowG, INPUT_PULLUP);
  pinMode(rowH, INPUT_PULLUP);

  //pinmode for registers
  pinMode(colLatch1, OUTPUT);
  pinMode(colClock1, OUTPUT);
  pinMode(colData1, OUTPUT);
  pinMode(colLatch2, OUTPUT);
  pinMode(colClock2, OUTPUT);
  pinMode(colData2, OUTPUT);
  //set all registers to high, just for sure
  updateShiftRegister1(B11111111);
  updateShiftRegister2(B11111111);
}

void loop() {
  //timer
    unsigned long currentMicros = micros();
    
    if(currentMicros - previousKeyboardMicros > keyboardInterval) {
      previousKeyboardMicros = currentMicros;   
   
      checkKeyboard();
    }
}






// IC2
void updateShiftRegister1(byte cols1) {
  
  digitalWrite(colLatch1, LOW);
  shiftOut(colData1, colClock1, MSBFIRST, cols1); 
  digitalWrite(colLatch1, HIGH);
}
// IC1
void updateShiftRegister2(byte cols2) {

  
  digitalWrite(colLatch2, LOW);
  shiftOut(colData2, colClock2, MSBFIRST, cols2);  
  digitalWrite(colLatch2  , HIGH); 
}



//checking keys
void checkKeyboard() {
  updateShiftRegister2(B11111111);   //all pins to 1, just for sure
  updateShiftRegister1(shiftCol1[ColToCheck1]); //every time only 1 pin to 0
  if (digitalRead(rowA) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[0][ColToCheck1]);
    lastDebounceTime = millis(); //"debounce"
  }
}

  //---------------------------------
  if (digitalRead(rowB) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[1][ColToCheck1]);
    lastDebounceTime = millis();
  }
}



  //---------------------------------
  if (digitalRead(rowC) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[2][ColToCheck1]);
    lastDebounceTime = millis();
}
  }


  //---------------------------------
  if (digitalRead(rowD) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[3][ColToCheck1]);
    lastDebounceTime = millis();
}
  }


  //---------------------------------
  if (digitalRead(rowE) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[4][ColToCheck1]);
    lastDebounceTime = millis();
}
  }


  //---------------------------------
  if (digitalRead(rowF) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[5][ColToCheck1]);
    lastDebounceTime = millis();
 }
  }


  //---------------------------------
  if (digitalRead(rowG) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[6][ColToCheck1]);
    lastDebounceTime = millis();
}
  }


  //---------------------------------
  if (digitalRead(rowH) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[7][ColToCheck1]);
    lastDebounceTime = millis();
}
  }
  ColToCheck1 = ColToCheck1 + 1;


  if (ColToCheck1 > 7 ) {
    ColToCheck1 = 0;
  }
//-----------------------------------------------
//-----------------------------------------------
//-----------------------------------------------
//-----------------------------------------------
//second half

  updateShiftRegister1(B11111111);
  updateShiftRegister2(shiftCol2[ColToCheck2]);
  if (digitalRead(rowA) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[0][ColToCheck2+7]);
    lastDebounceTime = millis();
}
  }


  //---------------------------------
  if (digitalRead(rowB) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[1][ColToCheck2+7]);
    lastDebounceTime = millis();
}

  }


  //---------------------------------
  if (digitalRead(rowC) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[2][ColToCheck2+7]);
    lastDebounceTime = millis();
}
  }


  //---------------------------------
  if (digitalRead(rowD) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[3][ColToCheck2+7]);
    lastDebounceTime = millis();
}
  }


  //---------------------------------
  if (digitalRead(rowE) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[4][ColToCheck2+7]);
    lastDebounceTime = millis();
}
  }


  //---------------------------------
  if (digitalRead(rowF) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[5][ColToCheck2+7]);
    lastDebounceTime = millis();
 }
  }


  //---------------------------------
  if (digitalRead(rowG) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[6][ColToCheck2+7]);
    lastDebounceTime = millis();
}
  }


  //---------------------------------
  if (digitalRead(rowH) == LOW) {
    if ((millis() - lastDebounceTime) > debounceDelay) {
    Keyboard.print(keys[7][ColToCheck2+7]);
    lastDebounceTime = millis();
}
  }
  ColToCheck2 = ColToCheck2 + 1;


  if (ColToCheck2 > 7 ) {
    ColToCheck2 = 0;
  }
  updateShiftRegister1(B11111111);
  updateShiftRegister2(B11111111);

}

In what way is it not behaving correctly?

only one function has a function key - be pressed. explain, if i want help you what on your opinion my next action is, what should i do?

UPD.: you has shift registers completely independent, why?

UPD2: i dont know if you able to reconnect strange wiring of registers, so i shorted the sketch so far:

#include <Keyboard.h>

//register IC2
const byte colData1 = 2;
const byte colLatch1 = 3;
const byte colClock1 = 4;

//register IC1
const byte colData2 = 5;
const byte colLatch2 = 6;
const byte colClock2 = 7;

//defining rows
const byte ROWs[8] = {A1, A2, A3, A4, A5, 10, 9, 8};

const char keys[8][14] = {
  {'0', '1', '2', '3', '4', '7', '8', '9', KEY_END, KEY_PAGE_DOWN, '0', KEY_F5, KEY_F10, '0'},
  {KEY_LEFT_CTRL, '`', KEY_F1, KEY_F2, '5', '6', '=', KEY_F8, KEY_HOME, KEY_PAGE_UP, KEY_INSERT, KEY_DELETE, KEY_F9, '-'},
  {'x', '0', '0', '0', 'b', 'n', '0', KEY_RIGHT_GUI, KEY_LEFT_ARROW, KEY_KP_MINUS, KEY_RIGHT_ARROW, KEY_DOWN_ARROW, KEY_F12, '/'},
  {'0', 'z', 'x', 'c', 'v', 'm', ',', '.', '0', KEY_KP_ASTERISK, KEY_KP_SLASH, KEY_NUM_LOCK, KEY_RETURN, 'ň'},
  {KEY_LEFT_ALT, KEY_ESC, '0', KEY_F4, 'g', 'h', KEY_F6, '0', KEY_UP_ARROW, KEY_KP_DOT, KEY_KP_0, ' ', KEY_F11, 'x'},
  {';', 'a', 's', 'd', 'f', 'j', 'k', 'l', KEY_KP_ENTER, KEY_KP_3, KEY_KP_2, KEY_KP_1, KEY_RIGHT_SHIFT, KEY_LEFT_GUI},
  {'[', KEY_TAB, KEY_CAPS_LOCK, KEY_F3, 't', 'y', ']', KEY_F7, KEY_RIGHT_CTRL, KEY_KP_6, KEY_KP_5, KEY_KP_4, KEY_LEFT_SHIFT, KEY_BACKSPACE},
  {'[', 'q', 'w', 'e', 'r', 'u', 'i', 'o', KEY_KP_PLUS, KEY_KP_9, KEY_KP_8, KEY_KP_7, 'p', '0'},
};
void setup() {
  delay(5000);     //protection
  Keyboard.begin();
  Serial.begin(9600);
  for (byte i = 0; i < 8; i++)pinMode(ROWs[i], INPUT_PULLUP);

  //pinmode for registers
  pinMode(colLatch1, OUTPUT);
  pinMode(colClock1, OUTPUT);
  pinMode(colData1, OUTPUT);
  pinMode(colLatch2, OUTPUT);
  pinMode(colClock2, OUTPUT);
  pinMode(colData2, OUTPUT);
  //set all registers to high, just for sure
  updateShiftRegister1(B11111111);
  updateShiftRegister2(B11111111);
}

// IC2
void updateShiftRegister1(byte cols1) {
  digitalWrite(colLatch1, LOW);
  shiftOut(colData1, colClock1, MSBFIRST, cols1);
  digitalWrite(colLatch1, HIGH);
}
// IC1
void updateShiftRegister2(byte cols2) {
  digitalWrite(colLatch2, LOW);
  shiftOut(colData2, colClock2, MSBFIRST, cols2);
  digitalWrite(colLatch2  , HIGH);
}

void NextCol(byte IC) {
  if (IC % 2) {
    digitalWrite(colLatch2, LOW);
    digitalWrite(colClock2, HIGH);
    digitalWrite(colClock2, LOW);
    digitalWrite(colLatch2, HIGH);
  }
  else {
    digitalWrite(colLatch1, LOW);
    digitalWrite(colClock1, HIGH);
    digitalWrite(colClock1, LOW);
    digitalWrite(colLatch1, HIGH);
  }
}

void loop() {
  updateShiftRegister2(B11111111);   //all pins to 1, just for sure
  updateShiftRegister1(B01111111); //every time only 1 pin to 0
  for (byte b = 0; b < 8; b++) {
    for (byte i = 0; i < 8; i++)
      if (!digitalRead(i) )Keyboard.print(keys[i][b]);
    NextCol(1);
  }

  updateShiftRegister1(B11111111);
  updateShiftRegister2(B01111111);
  for (byte b = 7; b < 15; b++) {
    for (byte i = 0; i < 8; i++)
      if (!digitalRead(i) )Keyboard.print(keys[i][b]);
    NextCol(2);
  }
}

yes, registers are independent, i made a mistake. And i dont think i am able to reconnect them correctly.
ok, also my fault, not function keys, but keys like shift, ctrl, alt. I think, they should be checked somewhere on the beginning of void checkKeyboard()
and instead of Keyboard.print(), i should use Keyboard.press(). And then they should be released at the end of the code. But how to check these specific keys on the beggining.

and the last thing what i need to update is. in the current state of te code, when i hold the key, it prints that letter in some interval. But on the computer keyboards, when i press and hold the key, it prints one letter, then it waits like 0,2 sec, and after that it prints that letter in interval, idk, 0,05 sec.

yup

and it will work so if:

You need to keep track of the state of each key and call "Keyboard.press()" when the key is first pressed and "Keyboard.release()" when the key is released. Your current code is sending press and release for each key that is held down for each scan of the keyboard.

See the "StateChangeDetection" example.

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