Simple Feather Code

The sample sketch presumes that you have three switches connected to the feather board. We have chosen to use pin numbers "A0", "A1", and "A2" to represent the "Previous", "Select", and "Next" functions. Although these are "analog" capable pins we are using them as standard digital input pins with the INPUT_PULLUP parameter. We chose them because they are adjacent to a ground pin which makes it easy to wire them up and it is unlikely that they will conflict with any other use of the device. It also gives you the option to rewrite the code to use an analog joystick rather than momentary press switches.

The function readSwitches() reads all three switches and turns them into a single unsigned byte value.

The main loop repeatedly calls this function and depending on the results initiates transmission of a keypress via the BLE connection.

The function pressKeyCode(c) handles the transmission of a keypress. It first sends a BLE command to press and hold the proper key. Then it repeatedly calls readSwitches() until it detects that the switch has been released. Then it sends a release command via BLE. In this way we can correctly process long keypresses. There is a delay(100) that helps to denounce the switches. If you find you're getting accidental double presses you could increase this value or if it is processing your presses too slowly you could decrease it.

NOTE: The codes being sent by the BLE command are not standard ASCII character codes. They are special keyboard press codes. For more information on the AT+BLEKEYBOARDCODE= BLE command see this following link.

Here is the source code for the "simple" sample program.

//iOS switch control example
//Simple version
#define MY_DEBUG 1
#include "BluefruitRoutines.h"

//Pin numbers for switches
#define PREVIOUS_SWITCH A0
#define SELECT_SWITCH A1
#define NEXT_SWITCH A2

//Actions
#define DO_PREVIOUS 1
#define DO_SELECT   2
#define DO_NEXT     4

uint8_t readSwitches(void) {
  return (~(digitalRead(PREVIOUS_SWITCH)*DO_PREVIOUS
      + digitalRead(SELECT_SWITCH)*DO_SELECT
      + digitalRead (NEXT_SWITCH)*DO_NEXT)
     ) & (DO_PREVIOUS+ DO_SELECT+ DO_NEXT);
}

//Translate character to keyboard keycode and transmit
void pressKeyCode (uint8_t c) {
  ble.print(F("AT+BLEKEYBOARDCODE=00-00-"));
  uint8_t Code=c-'a'+4;
  if (Code<0x10)ble.print("0");
  ble.print(Code,HEX);
  ble.println(F("-00-00-00-00"));
  MESSAGE(F("Pressed."));
  delay(100);//de-bounce
  while (readSwitches()) { //wait for button to be released
    /*do nothing*/
  };
  ble.println(F("AT+BLEKEYBOARDCODE=00-00"));
  MESSAGE(F("Released"));
}

void setup() {
#if(MY_DEBUG)
  while (! Serial) {}; delay (500);
  Serial.begin(9600); Serial.println("Debug output");
#endif
  pinMode(SELECT_SWITCH, INPUT_PULLUP);
  pinMode(NEXT_SWITCH, INPUT_PULLUP);
  pinMode(PREVIOUS_SWITCH, INPUT_PULLUP);
  initializeBluefruit();
}

void loop() {
  uint8_t i=readSwitches();
  switch (i) {
    case DO_PREVIOUS: pressKeyCode('p'); break;
    case DO_SELECT:   pressKeyCode('s'); break;
    case DO_NEXT:     pressKeyCode('n'); break;
  }
}

You should compile and upload the sketch and open your serial monster. You can see initialization steps that the program does. Then try pressing and releasing each of the three switches and note how it first transmits the keypress and then transmits the release signal.

You should pair the BLE device to your iOS device and configure switch control as described in the previous section of this tutorial. It should function virtually identically to the description of the EZ-Key device we described earlier.

Once you have everything working properly you should disable debugging by editing the line near the top to read #define MY_DEBUG 0

Last updated on Feb 13, 2017 Published on Feb 13, 2017