Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 05:02 01 Sep 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : ps2 scan codes for arrow keys backspace

Author Message
tenij000
Regular Member

Joined: 30/05/2025
Location: Netherlands
Posts: 50
Posted: 12:17am 25 Aug 2025
Copy link to clipboard 
Print this post

missing the arrow keys and the back space ps2 scan codes

my setup

connect pico whit the gp8 gp9 pins

try to use giga r1 as ps2 keyboard

  pico    <-----  arduino giga r1 <---- usb keyboard

#include "USBHostGiga.h"
#include <ps2dev.h>  // PS/2 emulatie

Keyboard keyb;             // USB keyboard
PS2dev keyboard(3, 2);     // PS/2 naar PicoMite (clock=3, data=2)

// --- Setup ---
void setup() {
 Serial.begin(9600);
 keyb.begin();            
 keyboard.write(0xAA);    // PS/2 init
 delay(10);
}

// --- Loop ---
void loop() {
 if (keyb.available() > 0) {
   auto _key = keyb.read();
   char c = keyb.getAscii(_key); // ASCII van USB keyboard
   sendPS2(c);                   // stuur naar PicoMite
 }
}

// --- ASCII / special keys naar PS/2 ---
void sendPS2(char c) {
 bool shift = false;

 // Hoofdletter detectie
 if (c >= 'A' && c <= 'Z') {
   shift = true;
   c = c + 32; // omzet naar kleine letter
 }

 uint8_t sc = 0;

 switch(c) {
   // Letters
   case 'a': sc=0x1C; break; case 'b': sc=0x32; break;
   case 'c': sc=0x21; break; case 'd': sc=0x23; break;
   case 'e': sc=0x24; break; case 'f': sc=0x2B; break;
   case 'g': sc=0x34; break; case 'h': sc=0x33; break;
   case 'i': sc=0x43; break; case 'j': sc=0x3B; break;
   case 'k': sc=0x42; break; case 'l': sc=0x4B; break;
   case 'm': sc=0x3A; break; case 'n': sc=0x31; break;
   case 'o': sc=0x44; break; case 'p': sc=0x4D; break;
   case 'q': sc=0x15; break; case 'r': sc=0x2D; break;
   case 's': sc=0x1B; break; case 't': sc=0x2C; break;
   case 'u': sc=0x3C; break; case 'v': sc=0x2A; break;
   case 'w': sc=0x1D; break; case 'x': sc=0x22; break;
   case 'y': sc=0x35; break; case 'z': sc=0x1A; break;

   // Cijfers
   case '1': sc=0x16; break; case '2': sc=0x1E; break;
   case '3': sc=0x26; break; case '4': sc=0x25; break;
   case '5': sc=0x2E; break; case '6': sc=0x36; break;
   case '7': sc=0x3D; break; case '8': sc=0x3E; break;
   case '9': sc=0x46; break; case '0': sc=0x45; break;

   // Enter, Backspace, spatie
   case ' ': sc=0x29; break;
   case '\n': sc=0x5A; break;
   case '\r': sc=0x5A; break;
   case '\b': sc=0x66; break;

   // Speciale tekens
   case '.': sc=0x49; break; case ',': sc=0x41; break;
   case '+': sc=0x55; shift=true; break; case '=': sc=0x55; break;
   case '-': sc=0x4E; break; case '_': sc=0x4E; shift=true; break;
   case '!': sc=0x16; shift=true; break; case '@': sc=0x1E; shift=true; break;
   case '#': sc=0x26; shift=true; break; case '$': sc=0x25; shift=true; break;
   case '%': sc=0x2E; shift=true; break; case '^': sc=0x36; shift=true; break;
   case '&': sc=0x3D; shift=true; break; case '*': sc=0x3E; shift=true; break;
   case '(': sc=0x46; shift=true; break; case ')': sc=0x45; shift=true; break;
   case '"': sc=0x52; shift=true; break; case '\'': sc=0x52; break;
   case '[': sc=0x54; break; case '{': sc=0x54; shift=true; break;
   case ']': sc=0x5B; break; case '}': sc=0x5B; shift=true; break;
   case ';': sc=0x4C; break; case ':': sc=0x4C; shift=true; break;
   case '<': sc=0x41; shift=true; break; case '>': sc=0x49; shift=true; break;
   case '/': sc=0x4A; break; case '?': sc=0x4A; shift=true; break;
   case '\\': sc=0x5D; break; case '|': sc=0x5D; shift=true; break;
   case '`': sc=0x0E; break; case '~': sc=0x0E; shift=true; break;

   // Speciale toetsen PicoMite volgens Appendix H
   case 127: sendExtendedKey(0x66); return; // DEL
   case 128: sendExtendedKey(0x75); return; // Up
   case 129: sendExtendedKey(0x72); return; // Down
   case 130: sendExtendedKey(0x6B); return; // Left
   case 131: sendExtendedKey(0x74); return; // Right
   case 132: sendExtendedKey(0x70); return; // Insert
   case 134: sendExtendedKey(0x6C); return; // Home
   case 135: sendExtendedKey(0x69); return; // End
   case 136: sendExtendedKey(0x7D); return; // Page Up
   case 137: sendExtendedKey(0x7A); return; // Page Down
   default: return;
 }

 ps2SendKey(sc, shift);
}

// --- Standaard PS/2 key ---
void ps2SendKey(uint8_t sc, bool shift) {
 if(shift) while(keyboard.write(0x12));    // Shift down
 while(keyboard.write(sc));                // Make code
 while(keyboard.write(0xF0));              // Break code
 while(keyboard.write(sc));
 if(shift) {                               // Shift up
   while(keyboard.write(0xF0));
   while(keyboard.write(0x12));
 }
}

// --- Extended keys voor pijltjes, DEL, etc. ---
void sendExtendedKey(uint8_t sc) {
 while(keyboard.write(0xE0));      // prefix
 while(keyboard.write(sc));         // Make code
 while(keyboard.write(0xE0));
 while(keyboard.write(0xF0));
 while(keyboard.write(sc));         // Break code
}
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5193
Posted: 06:04am 25 Aug 2025
Copy link to clipboard 
Print this post

Hi Tenij000,

key       down        up
left      &hE06B      &hE0F06B
right     &hE074      &hE0F074
up        &hE075      &hE0F075
down      &hE072      &hE0F072


I used this program to read the keys


old=0:cur=0
do
cur = MM.INFO(PS2)
if cur<>old then print "&h"+hex$(cur) : old=cur
loop


Volhout
Edited 2025-08-25 16:04 by Volhout
PicomiteVGA PETSCII ROBOTS
 
tenij000
Regular Member

Joined: 30/05/2025
Location: Netherlands
Posts: 50
Posted: 01:41pm 27 Aug 2025
Copy link to clipboard 
Print this post

update version whit arrow keys delete and backspace working abc 123 !@# etc also works now


#include "USBHostGiga.h"
#include <ps2dev.h> // PS/2 emulation test version woensdag oud

// USB keyboard library instance
Keyboard keyb;

// PS/2 device for emulating a keyboard (pins for PicoMite)
// clock pin = 3, data pin = 2
PS2dev keyboard(3, 2);

// --- Setup Function ---
void setup() {
 Serial.begin(9600); // Initialize serial communication for debugging
 
 // Start the USB host and keyboard connection
 keyb.begin();
 
 // Send the PS/2 self-test successful command to PicoMite
 keyboard.write(0xAA);
 delay(10);
}

// --- Main Loop ---
void loop() {
 // Check if a key is available from the USB keyboard
 if (keyb.available() > 0) {
   // Read the raw key data from the USB keyboard.
   auto _key = keyb.read();
   
   // Check for special extended keys first
   // Iterate through the key codes array to find the correct HID key
   bool foundSpecialKey = false;
   for (int i = 0; i < 6; i++) {
     if (_key.keys[i] == 0x52) { // Up Arrow
       Serial.println("Up Arrow pressed.");
       sendExtendedKey(0x75); // PS/2 scancode for Up Arrow
       foundSpecialKey = true;
     } else if (_key.keys[i] == 0x51) { // Down Arrow
       Serial.println("Down Arrow pressed.");
       sendExtendedKey(0x72); // PS/2 scancode for Down Arrow
       foundSpecialKey = true;
     } else if (_key.keys[i] == 0x50) { // Left Arrow
       Serial.println("Left Arrow pressed.");
       sendExtendedKey(0x6B); // PS/2 scancode for Left Arrow
       foundSpecialKey = true;
     } else if (_key.keys[i] == 0x4F) { // Right Arrow
       Serial.println("Right Arrow pressed.");
       sendExtendedKey(0x74); // PS/2 scancode for Right Arrow
       foundSpecialKey = true;
     } else if (_key.keys[i] == 0x4C) { // Delete
       Serial.println("Delete pressed.");
       sendExtendedKey(0x71); // PS/2 scancode for Delete
       foundSpecialKey = true;
     
     } else if (_key.keys[i] == 0x2A) { // Backspace
       Serial.println("Backspace pressed.");
       sendExtendedKey(0x6B); // PS/2 scancode for Left Arrow
       foundSpecialKey = true;
       sendExtendedKey(0x71); // PS/2 scancode for Delete
       foundSpecialKey = true;
     }
   }
   
   // If no special key was found, check for a standard ASCII key
   if (!foundSpecialKey) {
     char c = keyb.getAscii(_key);
     // If it's a valid ASCII character, send it as a PS/2 key
     if (c != 0) {
       Serial.print("Sending ASCII character: ");
       Serial.println(c);
       sendPS2(c);
     }
   }
 }
}

// --- Convert ASCII / Special Keys to PS/2 Scan Codes and send ---
// This function handles standard keys that don't need the extended prefix
void sendPS2(char c) {
 bool shift = false;
 uint8_t sc = 0;

 // Capital letter detection
 if (c >= 'A' && c <= 'Z') {
   shift = true;
   c = c + 32; // Convert to lowercase for scancode mapping
 }

 switch(c) {
   // Letters (PS/2 scancodes)
   case 'a': sc = 0x1C; break; case 'b': sc = 0x32; break;
   case 'c': sc = 0x21; break; case 'd': sc = 0x23; break;
   case 'e': sc = 0x24; break; case 'f': sc = 0x2B; break;
   case 'g': sc = 0x34; break; case 'h': sc = 0x33; break;
   case 'i': sc = 0x43; break; case 'j': sc = 0x3B; break;
   case 'k': sc = 0x42; break; case 'l': sc = 0x4B; break;
   case 'm': sc = 0x3A; break; case 'n': sc = 0x31; break;
   case 'o': sc = 0x44; break; case 'p': sc = 0x4D; break;
   case 'q': sc = 0x15; break; case 'r': sc = 0x2D; break;
   case 's': sc = 0x1B; break; case 't': sc = 0x2C; break;
   case 'u': sc = 0x3C; break; case 'v': sc = 0x2A; break;
   case 'w': sc = 0x1D; break; case 'x': sc = 0x22; break;
   case 'y': sc = 0x35; break; case 'z': sc = 0x1A; break;

   // Numbers
   case '1': sc = 0x16; break; case '2': sc = 0x1E; break;
   case '3': sc = 0x26; break; case '4': sc = 0x25; break;
   case '5': sc = 0x2E; break; case '6': sc = 0x36; break;
   case '7': sc = 0x3D; break; case '8': sc = 0x3E; break;
   case '9': sc = 0x46; break; case '0': sc = 0x45; break;

   // Enter, Backspace, Space
   case ' ': sc = 0x29; break;
   case '\n':
   case '\r': sc = 0x5A; break; // Enter/Return key
   //case '\b': sc = 0x66; break; // Backspace key
  // case '\b': sc = 0x7F; break; // DEL (werkt als backspace in MMBasic)

   
       
   
   // Special characters
   case '.': sc = 0x49; break; case ',': sc = 0x41; break;
   case '+': sc = 0x55; shift=true; break; case '=': sc = 0x55; break;
   case '-': sc = 0x4E; break; case '_': sc = 0x4E; shift=true; break;
   case '!': sc = 0x16; shift=true; break; case '@': sc = 0x1E; shift=true; break;
   case '#': sc = 0x26; shift=true; break; case '$': sc = 0x25; shift=true; break;
   case '%': sc = 0x2E; shift=true; break; case '^': sc = 0x36; shift=true; break;
   case '&': sc = 0x3D; shift=true; break; case '*': sc = 0x3E; shift=true; break;
   case '(': sc = 0x46; shift=true; break; case ')': sc = 0x45; shift=true; break;
   case '"': sc = 0x52; shift=true; break; case '\'': sc = 0x52; break;
   case '[': sc = 0x54; break; case '{': sc = 0x54; shift=true; break;
   case ']': sc = 0x5B; break; case '}': sc = 0x5B; shift=true; break;
   case ';': sc = 0x4C; break; case ':': sc = 0x4C; shift=true; break;
   case '<': sc = 0x41; shift=true; break; case '>': sc = 0x49; shift=true; break;
   case '/': sc = 0x4A; break; case '?': sc = 0x4A; shift=true; break;
   case '\\': sc = 0x5D; break; case '|': sc = 0x5D; shift=true; break;
   case '`': sc = 0x0E; break; case '~': sc = 0x0E; shift=true; break;

   default: return; // Return if the character is not recognized
 }
 
 // Call the function to send the PS/2 key press/release sequence
 ps2SendKey(sc, shift);
}

// --- Send a standard PS/2 key press and release sequence ---
void ps2SendKey(uint8_t sc, bool shift) {
 // Check if a shift key needs to be pressed
 if(shift) keyboard.write(0x12);     // Shift key down (Make Code)
 
 keyboard.write(sc);                 // Main key down (Make Code)
 
 // Send the break code prefix 0xF0
 keyboard.write(0xF0);              
 keyboard.write(sc);                 // Main key up (Break Code)
 
 // Release the shift key if it was pressed
 if(shift) {
   keyboard.write(0xF0);             // Shift key up (Break Code)
   keyboard.write(0x12);
 }
}

// --- Send an extended PS/2 key press and release sequence ---
void sendExtendedKey(uint8_t sc) {
 keyboard.write(0xE0);             // Extended key prefix
 keyboard.write(sc);               // Key down (Make Code)
 
 keyboard.write(0xE0);             // Extended key prefix for break code
 keyboard.write(0xF0);             // Break code prefix
 keyboard.write(sc);               // Key up (Break Code)
}
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025