-
-
Save DorianRudolph/ca283dfdfd185bc812b7 to your computer and use it in GitHub Desktop.
| //Program that outputs all PS2 scancodes via serial | |
| #define BUFFER_SIZE 45 | |
| static volatile uint8_t buffer[BUFFER_SIZE]; | |
| static volatile uint8_t head, tail; | |
| #define DATA_PIN 10 | |
| #define IRQ_PIN 3 | |
| // The ISR for the external interrupt | |
| void ps2interrupt(void) { | |
| static uint8_t bitcount=0; | |
| static uint8_t incoming=0; | |
| static uint32_t prev_ms=0; | |
| uint32_t now_ms; | |
| uint8_t n, val; | |
| val = digitalRead(DATA_PIN); | |
| now_ms = millis(); | |
| if (now_ms - prev_ms > 250) { | |
| bitcount = 0; | |
| incoming = 0; | |
| } | |
| prev_ms = now_ms; | |
| n = bitcount - 1; | |
| if (n <= 7) { | |
| incoming |= (val << n); | |
| } | |
| bitcount++; | |
| if (bitcount == 11) { | |
| uint8_t i = head + 1; | |
| if (i >= BUFFER_SIZE) i = 0; | |
| if (i != tail) { | |
| buffer[i] = incoming; | |
| head = i; | |
| } | |
| bitcount = 0; | |
| incoming = 0; | |
| } | |
| } | |
| static inline uint8_t get_scan_code(void) { | |
| uint8_t c, i; | |
| i = tail; | |
| if (i == head) return 0; | |
| i++; | |
| if (i >= BUFFER_SIZE) i = 0; | |
| c = buffer[i]; | |
| tail = i; | |
| return c; | |
| } | |
| void setup() { | |
| Serial.begin(9600); | |
| attachInterrupt(0, ps2interrupt, FALLING); | |
| pinMode(IRQ_PIN, INPUT_PULLUP); | |
| pinMode(DATA_PIN, INPUT_PULLUP); | |
| head = 0; | |
| tail = 0; | |
| } | |
| void loop() { | |
| uint8_t scan_code = get_scan_code(); | |
| if (scan_code) { | |
| Serial.println(scan_code, HEX); | |
| } | |
| } |
| //Program that also outputs all PS2 scancodes via serial and can also send commands to the keyboard | |
| #define BUFFER_SIZE 45 | |
| static volatile uint8_t buffer[BUFFER_SIZE]; | |
| static volatile uint8_t head, tail; | |
| static volatile uint8_t sendBits, msg, bitCount, setBits; | |
| #define DATA_PIN 10 | |
| #define IRQ_PIN 3 | |
| // The ISR for the external interrupt | |
| void ps2interrupt(void) { | |
| static uint8_t bitcount=0; | |
| static uint8_t incoming=0; | |
| static uint32_t prev_ms=0; | |
| uint32_t now_ms; | |
| uint8_t n, val; | |
| if (!sendBits){ | |
| val = digitalRead(DATA_PIN); | |
| now_ms = millis(); | |
| if (now_ms - prev_ms > 250) { | |
| bitcount = 0; | |
| incoming = 0; | |
| } | |
| prev_ms = now_ms; | |
| n = bitcount - 1; | |
| if (n <= 7) { | |
| incoming |= (val << n); | |
| } | |
| bitcount++; | |
| if (bitcount == 11) { | |
| uint8_t i = head + 1; | |
| if (i >= BUFFER_SIZE) i = 0; | |
| if (i != tail) { | |
| buffer[i] = incoming; | |
| head = i; | |
| } | |
| bitcount = 0; | |
| incoming = 0; | |
| } | |
| } else { | |
| --sendBits; | |
| uint8_t b = bitCount - 1; | |
| if (b == 8){ | |
| digitalWrite(DATA_PIN, !(setBits & 1)); | |
| } else if (b == 9) { | |
| pinMode(DATA_PIN, INPUT_PULLUP); | |
| } else if (b < 8) { | |
| bool bt = (msg >> b) & 1; | |
| digitalWrite(DATA_PIN, bt); | |
| setBits += bt; | |
| } | |
| ++bitCount; | |
| } | |
| } | |
| static inline uint8_t get_scan_code(void) { | |
| uint8_t c, i; | |
| i = tail; | |
| if (i == head) return 0; | |
| i++; | |
| if (i >= BUFFER_SIZE) i = 0; | |
| c = buffer[i]; | |
| tail = i; | |
| return c; | |
| } | |
| void setup() { | |
| Serial.begin(9600); | |
| attachInterrupt(0, ps2interrupt, FALLING); | |
| pinMode(IRQ_PIN, INPUT_PULLUP); | |
| pinMode(DATA_PIN, INPUT_PULLUP); | |
| head = 0; | |
| tail = 0; | |
| sendBits = 0; | |
| } | |
| void send_msg(uint8_t m) { | |
| noInterrupts(); | |
| pinMode(IRQ_PIN, OUTPUT); | |
| digitalWrite(IRQ_PIN, LOW); | |
| delayMicroseconds(60); | |
| pinMode(IRQ_PIN, INPUT_PULLUP); | |
| msg = m; | |
| bitCount = 0; | |
| sendBits = 12; | |
| setBits = 0; | |
| pinMode(DATA_PIN, OUTPUT); | |
| digitalWrite(DATA_PIN, LOW); | |
| interrupts(); | |
| } | |
| bool send_led; | |
| uint8_t led; | |
| void loop() { | |
| uint8_t scan_code = get_scan_code(); | |
| if (scan_code) { | |
| Serial.println(scan_code, HEX); | |
| if (scan_code == 0x58){ | |
| send_msg(0xED); | |
| led ^= 4; | |
| send_led = true; | |
| } else if (scan_code == 0xFA && send_led) { | |
| send_msg(led); | |
| send_led = false; | |
| } | |
| } | |
| } |
| //Complete Program for an Arduino to act as an PS2 to USB converter | |
| #define DATA_PIN 10 | |
| #define IRQ_PIN 3 | |
| #define BUFFER_SIZE 45 | |
| static volatile uint8_t buffer[BUFFER_SIZE]; | |
| static volatile uint8_t head, tail; | |
| static volatile uint8_t sendBits, msg, bitCount, setBits; | |
| KeyReport report; | |
| uint8_t K[255], KE[255]; | |
| uint8_t leds; | |
| bool send_leds; | |
| void setup_keymaps(){ | |
| K[0x1C] = 4; | |
| K[0x32] = 5; | |
| K[0x21] = 6; | |
| K[0x23] = 7; | |
| K[0x24] = 8; | |
| K[0x2B] = 9; | |
| K[0x34] = 10; | |
| K[0x33] = 11; | |
| K[0x43] = 12; | |
| K[0x3B] = 13; | |
| K[0x42] = 14; | |
| K[0x4B] = 15; | |
| K[0x3A] = 16; | |
| K[0x31] = 17; | |
| K[0x44] = 18; | |
| K[0x4D] = 19; | |
| K[0x15] = 20; | |
| K[0x2D] = 21; | |
| K[0x1B] = 22; | |
| K[0x2C] = 23; | |
| K[0x3C] = 24; | |
| K[0x2A] = 25; | |
| K[0x1D] = 26; | |
| K[0x22] = 27; | |
| K[0x35] = 28; | |
| K[0x1A] = 29; | |
| K[0x45] = 39; | |
| K[0x16] = 30; | |
| K[0x1E] = 31; | |
| K[0x26] = 32; | |
| K[0x25] = 33; | |
| K[0x2E] = 34; | |
| K[0x36] = 35; | |
| K[0x3D] = 36; | |
| K[0x3E] = 37; | |
| K[0x46] = 38; | |
| K[0x0E] = 53; | |
| K[0x4E] = 45; | |
| K[0x55] = 46; | |
| K[0x5D] = 49; | |
| K[0x66] = 42; | |
| K[0x29] = 44; | |
| K[0x0D] = 43; | |
| K[0x58] = 227; //CAPS 57 | |
| K[0x12] = 225; | |
| K[0x14] = 224; | |
| K[0x11] = 226; | |
| K[0x59] = 229; | |
| K[0x5A] = 40; | |
| K[0x76] = 41; | |
| K[0x05] = 58; | |
| K[0x06] = 59; | |
| K[0x04] = 60; | |
| K[0x0C] = 61; | |
| K[0x03] = 62; | |
| K[0x0B] = 63; | |
| K[0x83] = 64; | |
| K[0x0A] = 65; | |
| K[0x01] = 66; | |
| K[0x09] = 67; | |
| K[0x78] = 68; | |
| K[0x07] = 69; | |
| K[0x7E] = 57;//Scroll 71 | |
| K[0x54] = 47; | |
| K[0x77] = 83; | |
| K[0x7C] = 85; | |
| K[0x7B] = 86; | |
| K[0x79] = 87; | |
| K[0x71] = 99; | |
| K[0x70] = 98; | |
| K[0x69] = 89; | |
| K[0x72] = 90; | |
| K[0x7A] = 91; | |
| K[0x6B] = 92; | |
| K[0x73] = 93; | |
| K[0x74] = 94; | |
| K[0x6C] = 95; | |
| K[0x75] = 96; | |
| K[0x7D] = 97; | |
| K[0x5B] = 48; | |
| K[0x4C] = 51; | |
| K[0x52] = 52; | |
| K[0x41] = 54; | |
| K[0x49] = 55; | |
| K[0x4A] = 56; | |
| K[0x61] = 100; | |
| KE[0x1F] = 227; | |
| KE[0x14] = 228; | |
| KE[0x27] = 231; | |
| KE[0x11] = 230; | |
| KE[0x2F] = 101; | |
| KE[0x7c] = 70; | |
| KE[0x70] = 73; | |
| KE[0x6C] = 74; | |
| KE[0x7D] = 75; | |
| KE[0x71] = 76; | |
| KE[0x69] = 77; | |
| KE[0x7A] = 78; | |
| KE[0x75] = 82; | |
| KE[0x6B] = 80; | |
| KE[0x72] = 81; | |
| KE[0x74] = 79; | |
| KE[0x4A] = 84; | |
| KE[0x5A] = 88; | |
| } | |
| void ps2interrupt(void) { | |
| static uint8_t bitcount=0; | |
| static uint8_t incoming=0; | |
| static uint32_t prev_ms=0; | |
| uint32_t now_ms; | |
| uint8_t n, val; | |
| if (!sendBits){ | |
| val = digitalRead(DATA_PIN); | |
| now_ms = millis(); | |
| if (now_ms - prev_ms > 250) { | |
| bitcount = 0; | |
| incoming = 0; | |
| } | |
| prev_ms = now_ms; | |
| n = bitcount - 1; | |
| if (n <= 7) { | |
| incoming |= (val << n); | |
| } | |
| bitcount++; | |
| if (bitcount == 11) { | |
| uint8_t i = head + 1; | |
| if (i >= BUFFER_SIZE) i = 0; | |
| if (i != tail) { | |
| buffer[i] = incoming; | |
| head = i; | |
| } | |
| bitcount = 0; | |
| incoming = 0; | |
| } | |
| } else { | |
| --sendBits; | |
| uint8_t b = bitCount - 1; | |
| if (b == 8){ | |
| digitalWrite(DATA_PIN, !(setBits & 1)); | |
| } else if (b == 9) { | |
| pinMode(DATA_PIN, INPUT_PULLUP); | |
| } else if (b < 8) { | |
| bool bt = (msg >> b) & 1; | |
| digitalWrite(DATA_PIN, bt); | |
| setBits += bt; | |
| } | |
| ++bitCount; | |
| } | |
| } | |
| static inline uint8_t get_scan_code(void) { | |
| uint8_t c, i; | |
| i = tail; | |
| if (i == head) return 0; | |
| i++; | |
| if (i >= BUFFER_SIZE) i = 0; | |
| c = buffer[i]; | |
| tail = i; | |
| return c; | |
| } | |
| void setup_ps2(){ | |
| attachInterrupt(0, ps2interrupt, FALLING); | |
| pinMode(IRQ_PIN, INPUT_PULLUP); | |
| pinMode(DATA_PIN, INPUT_PULLUP); | |
| head = 0; | |
| tail = 0; | |
| sendBits = 0; | |
| } | |
| void setup() { | |
| setup_keymaps(); | |
| setup_ps2(); | |
| Keyboard.begin(); | |
| delay(1000); | |
| } | |
| bool ext, brk; | |
| int skip; | |
| void report_add(uint8_t k) { | |
| uint8_t i; | |
| if (k >= 224) { | |
| report.modifiers |= 1 << (k - 224); | |
| } else if (report.keys[0] != k && report.keys[1] != k && | |
| report.keys[2] != k && report.keys[3] != k && | |
| report.keys[4] != k && report.keys[5] != k) { | |
| for (i = 0; i < 6; ++i) { | |
| if (report.keys[i] == 0) { | |
| report.keys[i] = k; | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| void report_remove(uint8_t k) { | |
| uint8_t i; | |
| if (k >= 224) { | |
| report.modifiers &= ~(1 << (k - 224)); | |
| } else { | |
| for (i = 0; i < 6; ++i) { | |
| if (report.keys[i] == k) { | |
| report.keys[i] = 0; | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| void send_msg(uint8_t m) { | |
| noInterrupts(); | |
| pinMode(IRQ_PIN, OUTPUT); | |
| digitalWrite(IRQ_PIN, LOW); | |
| delayMicroseconds(60); | |
| pinMode(IRQ_PIN, INPUT_PULLUP); | |
| msg = m; | |
| bitCount = 0; | |
| sendBits = 12; | |
| setBits = 0; | |
| pinMode(DATA_PIN, OUTPUT); | |
| digitalWrite(DATA_PIN, LOW); | |
| interrupts(); | |
| } | |
| void loop() { | |
| uint8_t k = get_scan_code(), k2; | |
| if (k) { | |
| if (skip) { | |
| --skip; | |
| } else { | |
| if (k == 0xE0) { | |
| ext = true; | |
| } else if (k == 0xF0) { | |
| brk = true; | |
| } else if (k == 0xFA) { | |
| if (send_leds) { | |
| send_leds = false; | |
| send_msg(leds); | |
| } | |
| } else { | |
| if (k == 0xE1) { | |
| k2 = 72; | |
| skip = 7; | |
| brk = true; | |
| report_add(k2); | |
| Keyboard.sendReport(&report); | |
| } else { | |
| k2 = ext ? KE[k] : K[k]; | |
| } | |
| if (k2){ | |
| if (brk){ | |
| report_remove(k2); | |
| if (k2 == 83 || k2 == 71 || k2 == 57){ | |
| send_leds = true; | |
| if (k2 == 83) { | |
| leds ^= 2; | |
| } else if (k2 == 71) { | |
| leds ^= 1; | |
| } else if (k2 == 57) { | |
| leds ^= 4; | |
| } | |
| send_msg(0xED); | |
| } | |
| } else { | |
| report_add(k2); | |
| } | |
| Keyboard.sendReport(&report); | |
| } | |
| brk = false; | |
| ext = false; | |
| } | |
| } | |
| } | |
| } |
"KeyReport" does not a name of type...
my logitech F510 gamepad does not work with USB host shield 2.0. Work all my mice only :-). Could somebody help me?
in the file "/libraries/Keyboard/src/Keybard.h" I moved the line
void sendReport(KeyReport* keys);
three rows down so it no more sits in the "private:" section but in the "public:" section
Then I added:
#include <Keyboard.h>
to the top of the main program code
it compiled without error (Arduino 1.6.9 used) for a Leonardo
Don't run this program on BIOS PC
Hi. I was make some refactoring and fix interruption for Arduino Pro Mini. It's currently not requiring to patch the Keyboard.h.
https://github.com/kolsys/PS2USBConverter/tree/master
Don't run this program on BIOS PC
Why not?
Hi, I get a lot of errors when compiling:
Arduino: 1.8.19 (Mac OS X), Board: "Arduino Uno"
In file included from /Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino:3:0:
/Users/Mustafa/Documents/Arduino/libraries/Keyboard/src/Keyboard.h:29:2: warning: #warning "Using legacy HID core (non pluggable)" [-Wcpp]
#warning "Using legacy HID core (non pluggable)"
^~~~~~~
PS2toUSB:14:1: error: 'KeyReport' does not name a type
KeyReport report;
^~~~~~~~~
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino: In function 'void setup()':
PS2toUSB:198:3: error: 'Keyboard' not found. Does your sketch include the line '#include <Keyboard.h>'?
Keyboard.begin();
^~~~~~~~
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino: In function 'void report_add(uint8_t)':
PS2toUSB:208:5: error: 'report' was not declared in this scope
report.modifiers |= 1 << (k - 224);
^~~~~~
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino:208:5: note: suggested alternative: 'remove'
report.modifiers |= 1 << (k - 224);
^~~~~~
remove
PS2toUSB:209:14: error: 'report' was not declared in this scope
} else if (report.keys[0] != k && report.keys[1] != k &&
^~~~~~
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino:209:14: note: suggested alternative: 'remove'
} else if (report.keys[0] != k && report.keys[1] != k &&
^~~~~~
remove
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino: In function 'void report_remove(uint8_t)':
PS2toUSB:224:5: error: 'report' was not declared in this scope
report.modifiers &= ~(1 << (k - 224));
^~~~~~
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino:224:5: note: suggested alternative: 'remove'
report.modifiers &= ~(1 << (k - 224));
^~~~~~
remove
PS2toUSB:227:11: error: 'report' was not declared in this scope
if (report.keys[i] == k) {
^~~~~~
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino:227:11: note: suggested alternative: 'remove'
if (report.keys[i] == k) {
^~~~~~
remove
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino: In function 'void loop()':
PS2toUSB:271:11: error: 'Keyboard' not found. Does your sketch include the line '#include <Keyboard.h>'?
Keyboard.sendReport(&report);
^~~~~~~~
PS2toUSB:271:32: error: 'report' was not declared in this scope
Keyboard.sendReport(&report);
^~~~~~
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino:271:32: note: suggested alternative: 'remove'
Keyboard.sendReport(&report);
^~~~~~
remove
PS2toUSB:293:11: error: 'Keyboard' not found. Does your sketch include the line '#include <Keyboard.h>'?
Keyboard.sendReport(&report);
^~~~~~~~
PS2toUSB:293:32: error: 'report' was not declared in this scope
Keyboard.sendReport(&report);
^~~~~~
/Users/Mustafa/Documents/Arduino/Arduino PS2 to USB HID Keyboard Converter/PS2toUSB/PS2toUSB.ino:293:32: note: suggested alternative: 'remove'
Keyboard.sendReport(&report);
^~~~~~
remove
Multiple libraries were found for "Keyboard.h"
Used: /Users/Mustafa/Documents/Arduino/libraries/Keyboard
Not used: /Applications/Arduino.app/Contents/Java/libraries/Keyboard
exit status 1
'KeyReport' does not name a type
Can please suggest any modification to get this working? you already put too much work into this probably its worth another look at it.
Thanks.
It turned out that the Keyboard library doesn't work on UNO.
I'm looking into updating the firmware with this.
https://mitchtech.net/arduino-usb-hid-keyboard/
Hey, I wrote this a very long time ago and am not really interested in maintaining this anymore. But some others have posted fixes in this thread. And you are right, the Uno cannot act as HID out of the box. I used this with the Leonardo.
sendReport has been moved to /libraries/Keyboard/src/Keybard.h