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).