As we mentioned earlier, one of the advantages of the using an Arduino or feather based system is it allows you to use the device for more than just iOS switch control. Personally I have implemented a multiuse device which not only controls my iPhone using switch control, it can also be changed into another mode where it is used as an infrared TV remote. While we aren't going to go into the complexities of writing such an application, we have included this "multimode" sample sketch that shows you how you can switch in and out of iOS switch control and do something else. We recommend you implement the "simple" version first and get it working before attempting this version.

A global variable called Mode is initialized to SWITCH_MODE. This makes the program operate identically to the "simple" version we showed you earlier. However if you hold down one of the switches longer than 10 seconds (the value EXIT_LIMIT) then it switches into an alternate mode by setting Mode= OTHER_MODE; Our sample code while using OTHER_MODE simply blinks the pin 13 LED five times and then reverts to SWITCH_MODE. You can come up with something much more useful to do in that alternate mode. Perhaps you would have code that would turn them off or on environmental controls, operate pan and tilt servos to help you take a photo with your iPhone, or some other useful function. Whenever you want to go back to iOS Switch Control you simply set Mode=SWITCH_MODE

This sketch depends on both of the standard BluefruitConfig.h and our BluefruitRoutines.h file. Here is the source code for the main sketch.

//iOS switch control example
//Multiple mode 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

//Flag to tell if you are using switch control or other functions
uint8_t Mode;
#define SWITCH_MODE 1
#define OTHER_MODE 2
#define EXIT_LIMIT 10000ul  //Time limit for switching modes

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) {
  uint32_t Start=millis();
  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*/
  };
  if( (millis()-Start) > EXIT_LIMIT) {
    Mode= OTHER_MODE;
  }
  ble.println(F("AT+BLEKEYBOARDCODE=00-00"));
  MESSAGE(F("Released"));
}

// This reads the switches and decides what keypresses
// to send to the BLE device.
void doSwitchMode (void) {
  uint8_t i=readSwitches();
  switch (i) {
    case DO_PREVIOUS: pressKeyCode('p'); break;
    case DO_SELECT:   pressKeyCode('s'); break;
    case DO_NEXT:     pressKeyCode('n'); break;
  }
}

// This routine can perform some alternate function other than
// iOS switch control. It will be engaged if you hold a button
// for a very very long time.
void doOtherMode (void) {
  /*Insert your code here*/
  MESSAGE(F("Doing other mode."));
  //For demonstration purposes we will just blink the LED pin 13
  //a few times and then go back into switch control mode.
  pinMode(13, OUTPUT);
  for(uint8_t i=0;i<5;i++ ) {
    digitalWrite(13, HIGH); delay(1000);
    digitalWrite(13, LOW);  delay(1000);
  }
  Mode=SWITCH_MODE;
  MESSAGE(F("Returning to switch mode"));
}

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();
  Mode=SWITCH_MODE;
}

void loop() {
  switch(Mode) {
    case SWITCH_MODE: doSwitchMode(); break;
    case OTHER_MODE:  doOtherMode(); 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. 

Try holding down one of your switches for more than 10 seconds. Note how it switches into the alternate mode and blinks the pin 13 LED. After five blinks, it will revert back to switch control mode.

If you have not done so already, you should pair the BLE device to your iOS device and configure switch control as described in the earlier 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

This guide was first published on Feb 13, 2017. It was last updated on Mar 08, 2024.

This page (Multimode Feather Code) was last updated on Feb 08, 2017.

Text editor powered by tinymce.