Pi5 Laptop

*ENGINEERING UNIT – PROTOTYPE

Parts list:

  • 5″ capacitive touch LCD display for Raspberry pi 4B/5
  • Raspberry Pi 5 with heatsink&fan
  • Aluminum Mounting Plate
  • Arduino Pro Micro with single NPN/resistor-based logic inverter/3V-5V level shifter circuit
  • Belkin 5v 3A, 37Wh, 3.7V, 10000mAh Power Bank
  • Compaq G750 Foldable keyboard (inverted TTL output broken out and top removed)
  • Arduino Uno + USB cable
  • Dsub_9 socket (Arduino IO breakout port)
  • USB-C/USB-A panel mount port (Input power and single USB data transfer)

Software:

Keyboard translater Arduino Micro code:

#include <Keyboard.h>
#include <HashMap.h>
#include <SoftwareSerial.h>
#define checkKeyPress(keyInt, mapDown, mapUp) if (mapDown.contains(keyInt)) { char keyPressed = mapDown.valueAt(mapDown.indexOf(keyInt)); Serial.println("ACTION: " + String(keyPressed) + " DOWN"); Keyboard.press(keyPressed); cachedKeyData = ""; } if (mapUp.contains(keyInt)) { char keyPressed = mapUp.valueAt(mapUp.indexOf(keyInt)); Serial.println("ACTION: " + String(keyPressed) + " UP"); Keyboard.release(keyPressed); cachedKeyData = ""; }
SoftwareSerial keySerial(8, 9);
HashMap<long, char, 66> keyMapDown;
HashMap<long, char, 66> keyMapUp;
HashMap<long, char, 7> fnKeyMapDown;
HashMap<long, char, 7> fnKeyMapUp;
HashMap<long, char, 15> numLckKeyMapDown;
HashMap<long, char, 15> numLckKeyMapUp;
bool numLckMode = false;
bool fnMode = false;
long fnKeyDown = 0x2fd;
long fnKeyUp = 0x82fd;
long numLckKeyDown = 0x58a7;
long numLckKeyUp = 0xd8a7;
String cachedKeyData = "";
void keySetup() {
//Number keys
keyMapDown[0x16e9] = '1';
keyMapUp[0x96e9] = '1';
keyMapDown[0x1ee1] = '2';
keyMapUp[0x9ee1] = '2';
keyMapDown[0x26d9] = '3';
keyMapUp[0xa6d9] = '3';
keyMapDown[0x25da] = '4';
keyMapUp[0xa5da] = '4';
keyMapDown[0x2ed1] = '5';
keyMapUp[0xaed1] = '5';
keyMapDown[0x36c9] = '6';
keyMapUp[0xb6c9] = '6';
keyMapDown[0x3dc2] = '7';
keyMapUp[0xbdc2] = '7';
keyMapDown[0x3ec1] = '8';
keyMapUp[0xbec1] = '8';
keyMapDown[0x46b9] = '9';
keyMapUp[0xc6b9] = '9';
keyMapDown[0x45ba] = '0';
keyMapUp[0xc5ba] = '0';
//Letter keys
keyMapDown[0x1ce3] = 'a';
keyMapUp[0x9ce3] = 'a';
keyMapDown[0x32cd] = 'b';
keyMapUp[0xb2cd] = 'b';
keyMapDown[0x21de] = 'c';
keyMapUp[0xa1de] = 'c';
keyMapDown[0x23dc] = 'd';
keyMapUp[0xa3dc] = 'd';
keyMapDown[0x24db] = 'e';
keyMapUp[0xa4db] = 'e';
keyMapDown[0x2bd4] = 'f';
keyMapUp[0xabd4] = 'f';
keyMapDown[0x34cb] = 'g';
keyMapUp[0xb4cb] = 'g';
keyMapDown[0x33cc] = 'h';
keyMapUp[0xb3cc] = 'h';
keyMapDown[0x43bc] = 'i';
keyMapUp[0xc3bc] = 'i';
keyMapDown[0x3bc4] = 'j';
keyMapUp[0xbbc4] = 'j';
keyMapDown[0x42bd] = 'k';
keyMapUp[0xc2bd] = 'k';
keyMapDown[0x4bb4] = 'l';
keyMapUp[0xcbb4] = 'l';
keyMapDown[0x3ac5] = 'm';
keyMapUp[0xbac5] = 'm';
keyMapDown[0x31ce] = 'n';
keyMapUp[0xb1ce] = 'n';
keyMapDown[0x44bb] = 'o';
keyMapUp[0xc4bb] = 'o';
keyMapDown[0x4db2] = 'p';
keyMapUp[0xcdb2] = 'p';
keyMapDown[0x15ea] = 'q';
keyMapUp[0x95ea] = 'q';
keyMapDown[0x2dd2] = 'r';
keyMapUp[0xadd2] = 'r';
keyMapDown[0x1be4] = 's';
keyMapUp[0x9be4] = 's';
keyMapDown[0x2cd3] = 't';
keyMapUp[0xacd3] = 't';
keyMapDown[0x3cc3] = 'u';
keyMapUp[0xbcc3] = 'u';
keyMapDown[0x2ad5] = 'v';
keyMapUp[0xaad5] = 'v';
keyMapDown[0x1de2] = 'w';
keyMapUp[0x9de2] = 'w';
keyMapDown[0x22dd] = 'x';
keyMapUp[0xa2dd] = 'x';
keyMapDown[0x35ca] = 'y';
keyMapUp[0xb5ca] = 'y';
keyMapDown[0x1ae5] = 'z';
keyMapUp[0x9ae5] = 'z';
//Symbol keys
keyMapDown[0xef1] = '`';
keyMapUp[0x8ef1] = '`';
keyMapDown[0x4eb1] = '-';
keyMapUp[0xceb1] = '-';
keyMapDown[0x55aa] = '=';
keyMapUp[0xd5aa] = '=';
keyMapDown[0x4cb3] = ';';
keyMapUp[0xccb3] = ';';
keyMapDown[0x5da2] = '\'';
keyMapUp[0xdda2] = '\'';
// # key but mapping is wrong so has to be changed
keyMapDown[0x52ad] = 92;
keyMapUp[0xd2ad] = 92;
keyMapDown[0x41be] = ',';
keyMapUp[0xc1be] = ',';
keyMapDown[0x49b6] = '.';
keyMapUp[0xc9b6] = '.';
keyMapDown[0x4ab5] = '/';
keyMapUp[0xcab5] = '/';
// \ key but mapping is wrong so has to be changed
keyMapDown[0x748b] = 49;
keyMapUp[0xf48b] = 49;
keyMapDown[0x54ab] = '[';
keyMapUp[0xd4ab] = '[';
keyMapDown[0x5ba4] = ']';
keyMapUp[0xdba4] = ']';
//Special keys
keyMapDown[0x718e] = KEY_BACKSPACE;
keyMapUp[0xf18e] = KEY_BACKSPACE;
keyMapDown[0x5ca3] = ' ';
keyMapUp[0xdca3] = ' ';
keyMapDown[0x58a7] = KEY_CAPS_LOCK;
keyMapUp[0xd8a7] = KEY_CAPS_LOCK;
keyMapDown[0x14eb] = KEY_LEFT_CTRL;
keyMapUp[0x94eb] = KEY_LEFT_CTRL;
keyMapDown[0x12ed] = KEY_LEFT_SHIFT;
keyMapUp[0x92ed] = KEY_LEFT_SHIFT;
keyMapDown[0x708f] = KEY_LEFT_ALT;
keyMapUp[0xf08f] = KEY_LEFT_ALT;
keyMapDown[0x7f8] = KEY_LEFT_GUI;
keyMapUp[0x87f8] = KEY_LEFT_GUI;
keyMapDown[0x738c] = KEY_RIGHT_CTRL;
keyMapUp[0xf38c] = KEY_RIGHT_CTRL;
keyMapDown[0x59a6] = KEY_RIGHT_SHIFT;
keyMapUp[0xd9a6] = KEY_RIGHT_SHIFT;
keyMapDown[0x11ee] = KEY_RIGHT_ALT;
keyMapUp[0x91ee] = KEY_RIGHT_ALT;
keyMapDown[0x6699] = KEY_DELETE;
keyMapUp[0xe699] = KEY_DELETE;
keyMapDown[0x5aa5] = KEY_RETURN;
keyMapUp[0xdaa5] = KEY_RETURN;
keyMapDown[0xdf2] = KEY_TAB;
keyMapUp[0x8df2] = KEY_TAB;
keyMapDown[0x28d7] = KEY_UP_ARROW;
keyMapUp[0xa8d7] = KEY_UP_ARROW;
keyMapDown[0x609f] = KEY_DOWN_ARROW;
keyMapUp[0xe09f] = KEY_DOWN_ARROW;
keyMapDown[0x5ea1] = KEY_LEFT_ARROW;
keyMapUp[0xdea1] = KEY_LEFT_ARROW;
keyMapDown[0x2fd0] = KEY_RIGHT_ARROW;
keyMapUp[0xafd0] = KEY_RIGHT_ARROW;
// Function keys
fnKeyMapDown[0xdf2] = KEY_ESC;
fnKeyMapUp[0x8df2] = KEY_ESC;
fnKeyMapDown[0x718e] = 0;
fnKeyMapUp[0xf18e] = 0;
fnKeyMapDown[0x5aa5] = 0;
fnKeyMapUp[0xdaa5] = 0;
fnKeyMapDown[0x28d7] = KEY_PAGE_UP;
fnKeyMapUp[0xa8d7] = KEY_PAGE_UP;
fnKeyMapDown[0x609f] = KEY_PAGE_DOWN;
fnKeyMapUp[0xe09f] = KEY_PAGE_DOWN;
fnKeyMapDown[0x5ea1] = KEY_HOME;
fnKeyMapUp[0xdea1] = KEY_HOME;
fnKeyMapDown[0x2fd0] = KEY_END;
fnKeyMapUp[0xafd0] = KEY_END;
// Number lock keys
numLckKeyMapDown[0x3dc2] = '7';
numLckKeyMapUp[0xbdc2] = '7';
numLckKeyMapDown[0x3ec1] = '8';
numLckKeyMapUp[0xbec1] = '8';
numLckKeyMapDown[0x46b9] = '9';
numLckKeyMapUp[0xc6b9] = '9';
numLckKeyMapDown[0x45ba] = '*';
numLckKeyMapUp[0xc5ba] = '*';
numLckKeyMapDown[0x3cc3] = '4';
numLckKeyMapUp[0xbcc3] = '4';
numLckKeyMapDown[0x43bc] = '5';
numLckKeyMapUp[0xc3bc] = '5';
numLckKeyMapDown[0x44bb] = '6';
numLckKeyMapUp[0xc4bb] = '6';
numLckKeyMapDown[0x4db2] = '-';
numLckKeyMapUp[0xcdb2] = '-';
numLckKeyMapDown[0x3bc4] = '1';
numLckKeyMapUp[0xbbc4] = '1';
numLckKeyMapDown[0x42bd] = '2';
numLckKeyMapUp[0xc2bd] = '2';
numLckKeyMapDown[0x4bb4] = '3';
numLckKeyMapUp[0xcbb4] = '3';
numLckKeyMapDown[0x4cb3] = '+';
numLckKeyMapUp[0xccb3] = '+';
numLckKeyMapDown[0x3ac5] = '0';
numLckKeyMapUp[0xbac5] = '0';
numLckKeyMapDown[0x49b6] = '.';
numLckKeyMapUp[0xc9b6] = '.';
numLckKeyMapDown[0x4ab5] = '/';
numLckKeyMapUp[0xcab5] = '/';
}
/*
void checkKeyPress(long keyInt, HashMap mapDown, HashMap mapUp) {
if (mapDown.contains(keyInt)) {
char keyPressed = mapDown.valueAt(mapDown.indexOf(keyInt));
Serial.println("ACTION: " + String(keyPressed) + " DOWN");
Keyboard.press(keyPressed);
cachedKeyData = "";
}
if (mapUp.contains(keyInt)) {
char keyPressed = mapUp.valueAt(mapUp.indexOf(keyInt));
Serial.println("ACTION: " + String(keyPressed) + " UP");
Keyboard.release(keyPressed);
cachedKeyData = "";
}
}
*/
void checkKey() {
String newCache = cachedKeyData;
newCache.replace(",", "");
char charBuf[50];
newCache.toCharArray(charBuf, 50) ;
long keyInt = strtol(charBuf, NULL, 16);
if (fnMode) {
checkKeyPress(keyInt, fnKeyMapDown, fnKeyMapUp);
if (keyInt == numLckKeyDown) {
numLckMode = !numLckMode;
Serial.println("NUM LOCK KEY MODE TOGGLED");
cachedKeyData = "";
}
if (keyInt == numLckKeyUp) {
cachedKeyData = "";
}
}
if (numLckMode) {
checkKeyPress(keyInt, numLckKeyMapDown, numLckKeyMapUp);
}
if (keyInt == fnKeyDown) {
fnMode = true;
Serial.println("FUNCTION KEY MODE ON");
cachedKeyData = "";
}
if (keyInt == fnKeyUp) {
fnMode = false;
Serial.println("FUNCTION KEY MODE OFF");
cachedKeyData = "";
}
if (cachedKeyData != "") {
checkKeyPress(keyInt, keyMapDown, keyMapUp);
}
}
void setup() {
keySetup();
Keyboard.begin();
Serial.begin(9600);
keySerial.begin(4800);
keySerial.listen();
delay(2000);
Serial.println("Starting...");
}
void loop() {
if (keySerial.available()) {
String keyData = String(keySerial.read(), HEX);
if (cachedKeyData.length() < 1) {
cachedKeyData = keyData;
} else {
cachedKeyData = cachedKeyData + "," + keyData;
}
Serial.println("JUST GOT: " + keyData);
Serial.println("SO FAR: " + cachedKeyData);
checkKey();
}
if (Serial.available()) {
//keySerial.write(Serial.read());
if (char(Serial.read()) == 'c') {
cachedKeyData = "";
Serial.println("CLEARED CACHE");
}
}
}



Leave a comment