Close

Keys, magical keys

A project log for RemuterMCS

Remote control for muting and unmuting the microphone, camera, and speakers

WJCarpenterWJCarpenter 03/03/2021 at 04:080 Comments

Since I will be using AutoHotKey to intercept keys coming from the remote and taking action on them, my choice of keys to send is pretty wide open. I just need to avoid using keys that might mean something already. And, once I have things set up for the remote, I might also want to use the same shortcuts while I'm sitting at my keyboard. That rules out things like F13-F24, which have standard definitions but are not found on most keyboards.

I have tentatively decided to use these keys as the signals from the remote. If I run into difficulties, it's not too much trouble to change my mind later and use different trigger keys.

KeyFunction
Control + Shift + F9Mute microphone
Control + Shift + F10Unmute microphone
Control + Shift + F7Disable camera
Control + Shift + F8Enable camera
Control + Shift + F11Mute speakers
Control + Shift + F12Unmute speakers

I found in a quick experiment that none of those keys appear to do anything on either my Windows or Linux PC. That's not definitive, and I might discover some crafty application trying to use them for something useful

I'm not going to give an AutoHotKey tutorial here. The website has plenty of documentation. This is a quick script, WhatKeysAreThese.ahk, I created just to show that AHK does intercept the function keys with the modifiers that I decided to use. Nothing fancy. The blob of settings at the top are provided by AHK's Windows right-click context menu New > AutoHotKey Script. When AHK intercepts one of my keys, it pops up a message box and says what it intercepted. If you don't click "OK", the box goes away after 3 seconds.

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

^+F7::
MsgBox, 16, Remuter, Control Shift F7 DISABLE CAMERA, 3
return

^+F8::
MsgBox, 32, Remuter, Control Shift F8 ENABLE CAMERA, 3
return

^+F9::
MsgBox, 16, Remuter, Control Shift F9 MUTE MICROPHONE, 3
return

^+F10::
MsgBox, 32, Remuter, Control Shift F10 UNMUTE MICROPHONE, 3
return

^+F11::
MsgBox, 16, Remuter, Control Shift F11 MUTE SPEAKERS, 3
return

^+F12::
MsgBox, 32, Remuter, Control Shift F12 UNMUTE SPEAKERS, 3
return

Here is a simple Arduino IDE sketch, PushButtonSendKey, that cycles through the hot keys defined above, one key sent per big button press on the M5StickC. To compile and run it, follow the installation instructions for ESP32 BLE Keyboard.

/**
 * This simple sketch cycles through the Remuter F-keys.
 * Every time you push the big "M5" button, it sends a
 * key over Bluetooth.
 * 
 * See https://hackaday.io/project/177896-remuter
 * and https://gitlab.com/wjcarpenter/remuter
 */
#include <BleKeyboard.h>

// M5Stick-C
// GPIO 37 is the big button on the same side as the display
const int buttonPin = 37; // the number of the pushbutton pin
const int ledPin =  10;
int buttonState = 0;
int lastButtonState = LOW;

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

int pressCounter = 0;
BleKeyboard bleKeyboard("Remuter");
// key names are defined in BleKeyboard.h
unsigned char fKeys[] = {KEY_F7, 
                         KEY_F8, 
                         KEY_F9, 
                         KEY_F10, 
                         KEY_F11, 
                         KEY_F12};
int numberOfKeys = sizeof(fKeys) / sizeof(fKeys[0]);

void setup() {
  Serial.begin(500000);
  Serial.println("\nStarting....");
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state HIGH (off)
  digitalWrite(ledPin, HIGH);
  bleKeyboard.begin();
  while (!bleKeyboard.isConnected()) {
    delay(100);
  }
  Serial.println("BT connected");
}

void loop() {
  delay(10); // give it a break
  int reading = digitalRead(buttonPin);
  unsigned long now = millis();
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = now;
  }

  if ((now - lastDebounceTime) > debounceDelay) {
    int ledState = HIGH;
    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // send a key on button pressed down
      // LED is on while button is pressed, off when released
      if (buttonState == LOW) {
        int whichKeyPosition = (pressCounter++) % numberOfKeys;
        unsigned char keyValue = fKeys[whichKeyPosition];
        Serial.print("sending Control Shift F"); 
        Serial.println(keyValue - (KEY_F1 - 1), DEC);
        bleKeyboard.press(KEY_LEFT_CTRL);
        bleKeyboard.press(KEY_LEFT_SHIFT);
        bleKeyboard.press(keyValue);
        bleKeyboard.releaseAll();
        
        ledState = LOW;
      }
      digitalWrite(ledPin, ledState);
    }
  }

  lastButtonState = reading;
}

Discussions