PS/2 rouge sur +5V PS/2 noir sur GND PS/2 vert sur 3 (clock) PS/2 blanc sur 4 (data)
speaker sur 8 et ground
brancher les fils I2C comme dans https://www.aranacorp.com/fr/communication-i2c-entre-raspberry-pi-et-arduino/
PS/2 rouge sur +5V PS/2 noir sur GND PS/2 vert sur 3 (clock) PS/2 blanc sur 4 (data)
speaker sur 8 et ground
brancher les fils I2C comme dans https://www.aranacorp.com/fr/communication-i2c-entre-raspberry-pi-et-arduino/
#include <Arduino.h> | |
#include <PS2KeyAdvanced.h> | |
#include <cww_MorseTx.h> | |
#include <EEPROM.h> | |
#include <Wire.h> | |
#define I2C_SLAVE_ADDRESS 9 // 12 pour l'esclave 2 et ainsi de suite | |
#define PAYLOAD_SIZE 1 | |
#define DATAPIN 4 | |
#define IRQPIN 3 | |
#define SPEAKER_PIN 8 | |
#define WPM 20 | |
char azerty(uint16_t c, bool shift, bool altGr); | |
bool performAction(uint16_t c); | |
cww_MorseTx morseTone(7, WPM, SPEAKER_PIN, 600, false); | |
PS2KeyAdvanced keyboard; | |
int slider = WPM; | |
void setup() { //1024 octets d'EEPROM | |
// Configure the keyboard library | |
keyboard.begin(DATAPIN, IRQPIN); | |
Wire.begin(I2C_SLAVE_ADDRESS); | |
Serial.begin(115200); | |
Serial.println("Clavier Morse: appuyez sur CAPS LOCK pour émettre & configurer"); | |
morseTone = cww_MorseTx(7, slider, SPEAKER_PIN, 440, false); | |
//Serial.println(EEPROM.length()); | |
slider = EEPROM.read(0); | |
if (slider == 0) | |
slider = WPM; | |
else | |
Serial.println(slider); | |
keyboard.resetKey(); | |
Wire.onRequest(onWireRequest); | |
Wire.onReceive(onWireReceive); | |
} | |
uint16_t c; | |
char lettre; | |
bool shift; | |
bool altGr; | |
bool capsLock; | |
byte rcv; | |
void loop() { | |
if (rcv != 0) { | |
morseTone.send(rcv); | |
Serial.write(rcv); | |
Serial.println(""); | |
rcv = 0; | |
} | |
if (keyboard.available()) { | |
// read the next key | |
c = keyboard.read(); | |
if (c > 0) { | |
shift = c & PS2_SHIFT; | |
altGr = c & PS2_ALT_GR; | |
capsLock = keyboard.getLock() & PS2_LOCK_CAPS; | |
if (!(c & PS2_BREAK)) { | |
if (capsLock) { | |
if (performAction(c & 0xFF)) | |
goto end;//continue; //si une action a été effectuée on ne fait rien d'autre | |
} | |
lettre = azerty(c & 0xFF, shift, altGr); | |
if (lettre == ' ') | |
delay(1000); | |
if (lettre == ';') | |
delay(2000); | |
if (lettre > 31) { //symboles imprimables | |
if (lettre >= 65 && lettre <= 90) {//lettre de l'alphabet | |
if (capsLock) { | |
morseTone.send(lettre + 32); //32 pour convertir en lowercase | |
delay(500); | |
} | |
if (c & PS2_SHIFT) //shift | |
Serial.write(lettre); | |
else | |
Serial.write(lettre + 32); | |
} else { | |
Serial.write(lettre); | |
} | |
} | |
} | |
} | |
} | |
end: | |
; | |
} | |
char azerty(uint16_t c, bool shift, bool altGr) { | |
/*if (c == 0x8B && !shift) | |
return '<'; | |
if (c == 0x8B && shift) | |
return '>';*/ | |
switch (c) { | |
case PS2_KEY_Q: | |
return 'A'; | |
case PS2_KEY_A: | |
return 'Q'; | |
case PS2_KEY_Z: | |
return 'W'; | |
case PS2_KEY_W: | |
return 'Z'; | |
case PS2_KEY_SEMI: | |
return 'M'; | |
case PS2_KEY_M: | |
return ','; | |
case PS2_KEY_ENTER: | |
return '\n'; | |
case 0x8B: | |
if (shift) | |
return '>'; | |
else | |
return '<'; | |
case PS2_KEY_6: | |
if (altGr) | |
return '|'; | |
else | |
return '6'; | |
case PS2_KEY_0: | |
if (altGr) | |
return '@'; | |
case PS2_KEY_E: | |
if (altGr) | |
return '€'; //marche pas | |
default: | |
return c; | |
} | |
} | |
bool performAction(uint16_t c) { | |
if (c == PS2_KEY_UP_ARROW) { | |
slider++; | |
return true; | |
} | |
if (c == PS2_KEY_DN_ARROW) { | |
slider--; | |
return true; | |
} | |
if (c == PS2_KEY_KP_ENTER) { | |
Serial.println(""); | |
Serial.print("slider="); | |
Serial.println(slider); | |
morseTone = cww_MorseTx(7, slider, SPEAKER_PIN, 440, false); | |
return true; | |
} | |
if (c == PS2_KEY_KP_PLUS) { | |
EEPROM.update(0, slider); | |
return true; | |
} | |
if (c == PS2_KEY_KP_MINUS) { | |
for (int i = 0; i < slider; i++) { | |
keyboard.setLock(NULL); | |
delay(500); | |
keyboard.setLock(PS2_LOCK_CAPS); | |
delay(500); | |
} | |
} | |
return false; | |
} | |
void onWireRequest() | |
{ | |
Wire.write(c); | |
} | |
void onWireReceive(int len) | |
{ | |
rcv = Wire.read(); //on le lit que le premier pour retourner dans la boucle | |
} |
from threading import Thread | |
import smbus2 as smbus | |
import time | |
slave_addr = 0x09 | |
class KBWatcher(Thread): | |
def __init__(self, bus): | |
self.i2c = bus | |
super().__init__(daemon=True) | |
def run(self): | |
last=0 | |
while True: | |
new = self.i2c.read_byte(slave_addr) | |
if new != last: | |
print(hex(new)) | |
last=new | |
if __name__ == '__main__': | |
with smbus.SMBus(1) as i2c: | |
t = KBWatcher(i2c) | |
t.start() | |
while True: | |
val = input() | |
for c in val: | |
i2c.write_byte(slave_addr, ord(c)) | |
time.sleep(1) |