T-vK / ESP32-BLE-Keyboard

Bluetooth LE Keyboard library for the ESP32 (Arduino IDE compatible)
2.28k stars 379 forks source link

example that makes sending keystrokes conditional to a switch #256

Open StefanL38 opened 8 months ago

StefanL38 commented 8 months ago

Hi @T-vK,

the example-code that you included https://github.com/T-vK/ESP32-BLE-Keyboard/blob/master/examples/SendKeyStrokes/SendKeyStrokes.ino sends keystrokes unconditionally.

I suggest that you modify this example that either sending a keystroke is done only after a waittime of 15 seconds or that sending the keystrokes is only done conditionally on the position of an _"deactivate/activate-sendingkeystrokes"-switch.

This will help beginners. If a beginner modifies your example in a way that permanently sends keystrokes to not beeing caught in a trap where the code is sending keystrokes permanently unconditionally when they want to modify the code again.

You should also add a comment that directs the attention of users to this potential problem. Because it is very specific to keyboard-emulating devices and does not occure with any other kind of devices.

Here is an example-code

// This example turns the ESP32 into a Bluetooth LE keyboard that writes the words, presses Enter, presses a media key and then Ctrl+Alt+Delete

#include <BleKeyboard.h>

BleKeyboard bleKeyboard;

unsigned long MyTestTimer = 0;                   // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 2;

// on ESP32-nodeMCU-boards there is a button on the board
// that is connected to the GPIO-pin 0 (zero)
const byte onBoard_EN_Button = 0;

#define BLE_DEVICE_NAME "my-ESP32-BLE-Keyboard"

void setup() {
  pinMode(onBoard_EN_Button, INPUT_PULLUP);

  Serial.begin(115200);
  while (!Serial);
  Serial.println("Setup-Start");
  PrintFileNameDateTime();

  Serial.println("You have to connect the BLE-device");
  Serial.print("with the name ");
  Serial.println(BLE_DEVICE_NAME);
  Serial.println("to your computer or tablet or smartphone");

  bleKeyboard.setName(BLE_DEVICE_NAME);
  bleKeyboard.begin();
  Serial.println("bleKeyboard.begin() done");
  Serial.println("waiting for bleKeyboard.isConnected()");
  Serial.println("blinking fast until bleKeyboard.isConnected()");

  while ( !bleKeyboard.isConnected() ) {
    unsigned long myTimer;
    yield();
    BlinkHeartBeatLED(OnBoard_LED, 100);
    if ( TimePeriodIsOver(myTimer, 500) ) {
      Serial.print(".");
    }
  }
  Serial.println();

  if (bleKeyboard.isConnected()) {
    Serial.println("bleKeyboard.isConnected()");
    Serial.println("blinking slower 1 Hz");
    Serial.println("press EN-Button (IO-Pin 0) to send keystrokes");
  }
}

void loop() {
  BlinkHeartBeatLED(OnBoard_LED, 500);

  if (digitalRead(onBoard_EN_Button) == LOW) {
    Serial.println("EN-Button presssed");
    Serial.println("delay(100) for cheap debouncing");
    delay(100);

    if (bleKeyboard.isConnected()) {
      Serial.println("send Hello world");
      bleKeyboard.print("Hello world");

      Serial.println("Sending Enter key...");
      bleKeyboard.write(KEY_RETURN);

      Serial.println("Waiting 3 seconds...");
      delay(3000);
      Serial.println("ready for new button-press");
    }
  }
}

void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("  compiled ") );
  Serial.print( F(__DATE__) );
  Serial.print( F(" ") );
  Serial.println( F(__TIME__) );
}

// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}

best regards Stefan

manorius commented 8 months ago

This is a very good point. I was breaking by head why was my code acting weird, and you helped me find the solution. It had to do with the delay. Thanks @StefanL38