MASSO G3 - ovládací panel (emulovaná USB klávesnice)
Napsal: 22. 11. 2021, 5:37
Ahoj,
trochu už bylo nakousnuto zde. Modrošův ovládací panel využívá pro obsluhu většiny tlačítek Arduino s ATmega32U4 čipem (např. Leonardo) emulující USB klávesnici, čímž ušetří mnoho fyzických IO na MASSO kartě pro jiné využití. Jde o Modrošův nápad, já psal program. V SZ se mi ozval GeminiRacing, že by ho to také zajímalo, tak jsem se rozhodl založit toto téma (Modroš byl pro).
Zjednodušené schéma:
Mapa tlačítek:
Pin 2 = CTRL + ALT + Home (Homing)
Pin 3 = CTRL + ALT + P (Parking)
Pin 4 = U (Z+)
Pin 5 = D (Z-)
Pin 6-9 = Šipky (Jog XY)
Pin 10 = SHIFT (plus šipka nebo U nebo D = Rapid)
Pin 11 = F11 (Feed, +- dělá ruční kolečko)
Pin 12 = F12 (Spindle RPM , +- dělá ruční kolečko)
Program:
Bohužel to nefunguje zcela ideálně, nefungují modifikační klávesy (SHIFT, CTRL a ALT)
Mezi Arduinem a Massem je zřejmě nějaká nekompatibilita (na PC či MACu funguje vše bez problémů). Osobně bych zkusil dotaz na MASSO support fóru, protože ale sám MASSO kontroler nemám a Modroš měl jiné starosti, nechali jsme to zatím být (postižená tlačítka jsou momentálně řešena přes fyzické IO, viz schema*).
Další možnost by byla použít modul ze skutečné USB klávesnice.
T.
* Tady možná trochu kecám, nevím úplně přesně, jak to má Modroš vyřešeno (motal jsem se jen kolem toho Arduina).
trochu už bylo nakousnuto zde. Modrošův ovládací panel využívá pro obsluhu většiny tlačítek Arduino s ATmega32U4 čipem (např. Leonardo) emulující USB klávesnici, čímž ušetří mnoho fyzických IO na MASSO kartě pro jiné využití. Jde o Modrošův nápad, já psal program. V SZ se mi ozval GeminiRacing, že by ho to také zajímalo, tak jsem se rozhodl založit toto téma (Modroš byl pro).
Zjednodušené schéma:
Mapa tlačítek:
Pin 2 = CTRL + ALT + Home (Homing)
Pin 3 = CTRL + ALT + P (Parking)
Pin 4 = U (Z+)
Pin 5 = D (Z-)
Pin 6-9 = Šipky (Jog XY)
Pin 10 = SHIFT (plus šipka nebo U nebo D = Rapid)
Pin 11 = F11 (Feed, +- dělá ruční kolečko)
Pin 12 = F12 (Spindle RPM , +- dělá ruční kolečko)
Program:
Kód: Vybrat vše
/*
* MASSO G3 HID control v4
*/
#include <Keyboard.h>
#define DEBOUNCE_MS 50
#define BEEP_PRESS_MS 20
#define BEEP_RELEASE_MS 5 // 0 = no key-release beep
#define KEY_HOMING_PIN 2 // ctrl-alt-home
#define KEY_PARKING_PIN 3 // ctrl-alt-p
#define KEY_U_PIN 4
#define KEY_D_PIN 5
#define KEY_ARROW_LEFT_PIN 6
#define KEY_ARROW_RIGHT_PIN 7
#define KEY_ARROW_UP_PIN 8
#define KEY_ARROW_DOWN_PIN 9
#define KEY_SHIFT_PIN 10
#define KEY_F11_PIN 11
#define KEY_F12_PIN 12
#define KEY_PRESSED_LED LED_BUILTIN
#define SPEAKER_PLUS_PIN A4
#define SPEAKER_MINUS_PIN A5
#define HEARTBEAT_PIN A0
#define KEY_BUFFERS_SIZE 13 // highest KEY_xxx_PIN number used + 1
//---------------------------------------------------------
// global variables
//---------------------------------------------------------
boolean keyStates[KEY_BUFFERS_SIZE];
byte keyTimers[KEY_BUFFERS_SIZE];
byte beepTimer;
//---------------------------------------------------------
// setup
//---------------------------------------------------------
void clearBuffers() {
for (byte i = 0; i < KEY_BUFFERS_SIZE; i++) {
keyStates[i] = false;
keyTimers[i] = 0;
}
}
void setup() {
pinMode(KEY_HOMING_PIN, INPUT_PULLUP);
pinMode(KEY_PARKING_PIN, INPUT_PULLUP);
pinMode(KEY_U_PIN, INPUT_PULLUP);
pinMode(KEY_D_PIN, INPUT_PULLUP);
pinMode(KEY_ARROW_LEFT_PIN, INPUT_PULLUP);
pinMode(KEY_ARROW_RIGHT_PIN, INPUT_PULLUP);
pinMode(KEY_ARROW_UP_PIN, INPUT_PULLUP);
pinMode(KEY_ARROW_DOWN_PIN, INPUT_PULLUP);
pinMode(KEY_SHIFT_PIN, INPUT_PULLUP);
pinMode(KEY_F11_PIN, INPUT_PULLUP);
pinMode(KEY_F12_PIN, INPUT_PULLUP);
pinMode(KEY_PRESSED_LED, OUTPUT);
pinMode(SPEAKER_PLUS_PIN, OUTPUT);
pinMode(SPEAKER_MINUS_PIN, OUTPUT);
pinMode(HEARTBEAT_PIN, OUTPUT);
clearBuffers();
Keyboard.begin();
}
//---------------------------------------------------------
// core methods
//---------------------------------------------------------
#define KEY_STATE_PRESSED 0
#define KEY_STATE_RELEASED 1
#define KEY_STATE_STILL 2
byte fetchKeyState(byte inputPin) {
if (keyTimers[inputPin] == 0) {
boolean pressedBefore = keyStates[inputPin];
boolean pressedNow = digitalRead(inputPin) == 0;
if (pressedBefore != pressedNow) {
keyStates[inputPin] = pressedNow;
keyTimers[inputPin] = DEBOUNCE_MS;
if (pressedNow) {
beepTimer = BEEP_PRESS_MS;
return KEY_STATE_PRESSED;
}
beepTimer = BEEP_RELEASE_MS;
return KEY_STATE_RELEASED;
}
} else {
keyTimers[inputPin]--;
}
return KEY_STATE_STILL;
}
void handleSingleKey(byte inputPin, char code) {
byte keyState = fetchKeyState(inputPin);
if (keyState == KEY_STATE_PRESSED) {
Keyboard.press(code);
} else if (keyState == KEY_STATE_RELEASED) {
Keyboard.release(code);
}
}
void handleMultiKey(byte inputPin, void (*callbackFunction)(byte)) {
byte keyState = fetchKeyState(inputPin);
if (keyState != KEY_STATE_STILL) {
callbackFunction(keyState);
}
}
void handleBeep() {
if (beepTimer > 0) {
digitalWrite(SPEAKER_PLUS_PIN, beepTimer & 1);
digitalWrite(SPEAKER_MINUS_PIN, !(beepTimer & 1));
beepTimer--;
} else {
digitalWrite(SPEAKER_PLUS_PIN, false);
digitalWrite(SPEAKER_MINUS_PIN, false);
}
}
void handleStatusLed() {
boolean keyPressed = false;
for (byte i = 0; i < BUFFERS_SIZE; i++) {
keyPressed = keyStates[i] || keyPressed;
}
digitalWrite(KEY_PRESSED_LED, keyPressed);
}
//---------------------------------------------------------
// multi-key callbacks
//---------------------------------------------------------
void homing(byte keyState) {
if (keyState == KEY_STATE_PRESSED) {
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press(KEY_LEFT_ALT);
Keyboard.press(KEY_HOME);
} else {
Keyboard.release(KEY_HOME);
Keyboard.release(KEY_LEFT_ALT);
Keyboard.release(KEY_LEFT_CTRL);
}
}
void parking(byte keyState) {
if (keyState == KEY_STATE_PRESSED) {
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press(KEY_LEFT_ALT);
Keyboard.press('p');
} else {
Keyboard.release('p');
Keyboard.release(KEY_LEFT_ALT);
Keyboard.release(KEY_LEFT_CTRL);
}
}
//---------------------------------------------------------
// main loop
//---------------------------------------------------------
void loop() {
digitalWrite(HEARTBEAT_PIN, true);
handleMultiKey(KEY_HOMING_PIN, homing);
handleMultiKey(KEY_PARKING_PIN, parking);
handleSingleKey(KEY_U_PIN, 'u');
handleSingleKey(KEY_D_PIN, 'd');
handleSingleKey(KEY_ARROW_LEFT_PIN, KEY_LEFT_ARROW);
handleSingleKey(KEY_ARROW_RIGHT_PIN, KEY_RIGHT_ARROW);
handleSingleKey(KEY_ARROW_UP_PIN, KEY_UP_ARROW);
handleSingleKey(KEY_ARROW_DOWN_PIN, KEY_DOWN_ARROW);
handleSingleKey(KEY_SHIFT_PIN, KEY_RIGHT_SHIFT);
handleSingleKey(KEY_F11_PIN, KEY_F11);
handleSingleKey(KEY_F12_PIN, KEY_F12);
handleStatusLed();
handleBeep();
digitalWrite(HEARTBEAT_PIN, false);
delayMicroseconds(855); // cca 1ms per loop
}

Další možnost by byla použít modul ze skutečné USB klávesnice.
T.
* Tady možná trochu kecám, nevím úplně přesně, jak to má Modroš vyřešeno (motal jsem se jen kolem toho Arduina).