0

Have confirmed that the BootKeyboard programming on the Leonardo is able to launch the macOS recovery partition or boot screen.

The problem I've got is that this only works if you send it after the Leonardo has made HID connection to the computer - eg it can't be "holding" the keys first which is what I was hoping it could do.

So I have the Leonardo reboot the Mac it's it on it's own external power so it continues to run the code. I established the BootKeyboard keys were working by tying the pressed keys to a button on the Leonardo and when the connection is established pressing the button straight away to successfully open the boot menu.

The connection establishment is shown by the red LED flashing on the Leonardo board - so is it possible to use this connection established as a "virtual button" to immediately press the key commands I need? Can I act on this anyway in the code?

Here is some demo code to explain what I want to do.

#include <HID-Project.h>
#include <HID-Settings.h>
char chr;   // for incoming serial data, type char is signed 8-bit, -128 to 127, ASCII is char codes. Save 1 byte over type int.

void setup() {
  BootKeyboard.begin();
  Keyboard.begin();
  Mouse.begin();
  Serial.begin(115200);
  pinMode(5, OUTPUT);
}

void loop() {
  // At this point the Leonardo has run all my operations and is waiting for the computer to finish running a script - the computer talks to the Leonardo over the serial port (by sending Echo 1) to let it know it's at the end of the script, at which point the rest of the code runs below...
  if (Serial.available() > 1) 
    {
    // read the next char in the Serial input buffer, might be the last/latest arrived
    (chr = Serial.read() > 1);
    // run commands which opens the reboot menu on macOS and reboots the computer
  delay(1000); 
  Keyboard.press(KEY_LEFT_CTRL);
  Keyboard.press(KEY_F2);
  delay(100);
  Keyboard.releaseAll();
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_RETURN);
  delay(1000);
  Keyboard.write(KEY_TAB);
  delay(100);
  Keyboard.write(KEY_TAB);
  delay(100);
  Keyboard.write(' ');
  delay(5000);

// At this point the computer reboots and I need the following BootKeyboard button to press only once the USB connection has been established again - as mentioned the Leonardo doesn't lose its position in the code as it's powered externally so it doesn't reset. But the USB connection will be lost and then after the reboot it will be established again (and the Leonardo red LED flashes to show this) and then it needs to immediately press the following buttons at this time to enter the boot menu

  BootKeyboard.press(KEY_LEFT_GUI);
  BootKeyboard.press('r');
  delay(120000);
  BootKeyboard.releaseAll();
  delay(1000);
// Language Select Screen
  Keyboard.write(KEY_RETURN);
  delay(11000);
// Recovery Partition
  Mouse.click(MOUSE_LEFT);
  delay(50);
  Keyboard.write(KEY_TAB);
  delay(50);
  Keyboard.write(KEY_TAB);
  delay(50);
  Keyboard.write(KEY_TAB);
  delay(50);
  Keyboard.write(KEY_TAB);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_DOWN_ARROW);
  delay(50);
  Keyboard.write(KEY_RETURN);
  delay(4500);
  Keyboard.print("Terminal Command");
  digitalWrite(5, HIGH); // This triggers the NodeMCU connected to pin 5 to send a pushover notification to let me know it's completed the job
  delay(100);   //short wait time
  digitalWrite(5, LOW);
 }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.