Introduction: Arduino Adafruit Bluefruit for IOS Switch Control

Leveraging iOS Switch Control and an Adafruit Bluefruit, you can make switches to control actions on your mobile phone!

Switch Control is an accessibility feature that is often used by people with disabilities as an alternative method of providing input to their device(s).

In this instructable, we'll go through the steps on how to get your switch control up and running. If you have all the supplies listed below, it should take you about an hour to get it up and running.

Supplies

  • Adafruit Bluefruit Feather nRF52
  • Half Breadboard
  • Wires
  • LED Light
  • 4x - push buttons
  • 4x - 10Ω Resistors
  • 1x - 220Ω Resistors

Step 1: Gather Supplies

Make sure you have all the supplies!

Step 2: Bluefruit Setup

If it's the first time you are using your Bluefruit Feather, you may want to set up a simple circuit layout and test uploading a sketch.

Step 3: Plug Everything In!

Checkout the fritzing breadboard diagram if you'd like to replicate my exact circuit design. Maybe you can think of a more organized layout!

Here is a textual description of everything I have on my board (also represented in the images and fritzing diagram):

  • Half Breadboard
  • Bluefruit Feather is placed in columns B - H at the top
  • Gray wire from G on Feather to ground
  • Red wire from USB on Feather to power
  • Orange wire from Pin 7 on Feather to I21
  • Red wire from ground to power
  • Gray wire from ground to ground
  • Yellow wire from Pin 11 on Feather to A28
  • Yellow wire from Pin 30 on Feather to A25
  • Yellow wire from Pin 27 on Feather to A22
  • 220Ω Resistor from F21 to I19
  • Green LED light in J19 and ground
  • 10Ω Resistor from I22 to power
  • 10Ω Resistor from I25 to power
  • 10Ω Resistor from I28 to power
  • Red wire from G24 to power
  • Red wire from G27 to power
  • Red wire from G30 to power
  • Push button in E22, E24, F22, F24
  • Push button in E25, E27, F25, F27
  • Push button in E28, E30, F28, F30

In case you want to edit the fritzing, you can download the file here too.

Step 4: Computer Setup!

If this is the first time you're using an Arduino and/or an Adafruit Bluefruit Feather, you'll need to download and install the Arduino IDE.

Here are the directions, as copied from the course this project was for...

  • Install Arduino IDE
  • Open Preferences and put ‘https://adafruit.github.io/arduino-board-index/package_adafruit_index.json’ in the Additional Boards Manager URL

  • Open Tools>Board…>Board Manager

  • Click on Adafruit nRF52 and click ‘Install’

  • Quit and re-open the Arduino IDE

  • Check if you have succeeded. You should be able to select the Bluefruit board from the Boards menu, select the correct port from Tools>Port and upload a sketch!

  • If you are on a mac, you will additionally need to install the USB to UART bridge drivers provided by Silabs. Be sure (within 30 minutes of install) to approve it in the Security and Privacy settings for your mac (you’ll see a button for this below “Allow apps downloaded from…”).

  • If you are Windows, you may need to install a driver.

  • Check if you have succeeded. You should see a USB port in your Arduino Ports menu

  • You’ll want the Bluefruit libraries and sample code. Go to Tools>Manage Libraries and search for bluefruit. Install the Adafruit BluefruitLE nRF51 suite

Step 5: Load the Code!

Now that your Bluefruit is ready to be programmed with the computer, download the sketch and upload.

You can also copy it at the end of this step.

Here's an overview of how the code works:

The code makes the Bluefruit act like a Bluetooth keyboard. It is mapped to characters which can be the input that iOS devices use for switch control. You'll set up the iOS device on the next step.

/*********************************************************************
  Switch Control with Adafruit Feather

  Grady Thompson (gradyat@uw.edu)
  2019

  This code to build a simple switch control system is built off of
  hid-keyboard provided by Adafruit.

  Adafruit header below:

  This is an example for our nRF52 based Bluefruit LE modules

  Pick one up today in the adafruit shop!

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  MIT license, check LICENSE for more information
  All text above, and the splash screen below must be included in
  any redistribution
*********************************************************************/
#include 

BLEDis bledis;
BLEHidAdafruit blehid;

bool hasKeyPressed = false;

const int buttonLeftPin = 11;
const int buttonSelectPin = 30;
const int buttonRightPin = 27;
const int ledPin = 7;

const char leftChar = (char) 'a';
const char selectChar = (char) 's';
const char rightChar = (char) 'd';

int buttonLeftState = LOW;
int buttonSelectState = LOW;
int buttonRightState = LOW;
//int ledState = LOW;



void setup()
{

  pinMode(ledPin, OUTPUT);
  pinMode(buttonLeftPin, INPUT);
  pinMode(buttonSelectPin, INPUT);
  pinMode(buttonRightPin, INPUT);

  Serial.begin(115200);
  //  while ( !Serial ) delay(10);   // for nrf52840 with native usb
  //
  //  Serial.println("Bluefruit52 HID Keyboard Example");
  //  Serial.println("--------------------------------\n");
  //
  //  Serial.println();
  //  Serial.println("Go to your phone's Bluetooth settings to pair your device");
  //  Serial.println("then open an application that accepts keyboard input");
  //
  //  Serial.println();
  //  Serial.println("Enter the character(s) to send:");
  //  Serial.println();

  Bluefruit.begin();
  Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values
  Bluefruit.setName("Bluefruit513");

  // Configure and Start Device Information Service
  bledis.setManufacturer("Adafruit Industries");
  bledis.setModel("Bluefruit Feather 52");
  bledis.begin();

  /* Start BLE HID
       Note: Apple requires BLE device must have min connection interval >= 20m
       ( The smaller the connection interval the faster we could send data).
       However for HID and MIDI device, Apple could accept min connection interval
       up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max
       connection interval to 11.25  ms and 15 ms respectively for best performance.
  */
  blehid.begin();

  // Set callback for set LED from central
  //blehid.setKeyboardLedCallback(set_keyboard_led);

  /* Set connection interval (min, max) to your perferred value.
     Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
     min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms
  */
  /* Bluefruit.Periph.setConnInterval(9, 12); */

  // Set up and start advertising
  startAdv();
}

void startAdv(void)
{
  // Advertising packet
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD);

  // Include BLE HID service
  Bluefruit.Advertising.addService(blehid);

  // There is enough room for the dev name in the advertising packet
  Bluefruit.Advertising.addName();

  /* Start Advertising
     - Enable auto advertising if disconnected
     - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
     - Timeout for fast mode is 30 seconds
     - Start(timeout) with timeout = 0 will advertise forever (until connected)

     For recommended advertising interval
     https://developer.apple.com/library/content/qa/qa1931/_index.html
  */
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms
  Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
  Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds
}

void loop()
{
  buttonLeftState = digitalRead(buttonLeftPin);
  buttonSelectState = digitalRead(buttonSelectPin);
  buttonRightState = digitalRead(buttonRightPin);
  if (buttonLeftState == HIGH) {
    Serial.println("left button pressed");
    blehid.keyPress('d');
    digitalWrite(ledPin, HIGH);
    delay(250);
    digitalWrite(ledPin, LOW);
  }
  if (buttonSelectState == HIGH) {
    Serial.println("select button pressed");
    blehid.keyPress('s');
    digitalWrite(ledPin, HIGH);
    delay(250);
    digitalWrite(ledPin, LOW);
    blehid.keyRelease();
  }
  if (buttonRightState == HIGH) {
    Serial.println("right button pressed");
    blehid.keyPress('a');
    digitalWrite(ledPin, HIGH);
    delay(250);
    digitalWrite(ledPin, LOW);
    blehid.keyRelease();
  }
  delay(10);
}

Step 6: Set Up Your IOS Device!

Open the Settings app on your iOS device. Go to Accessibility, then Switch Control. Go to Switches, then Add New Switch. Trigger a button and then select what you'd like to do. I used "Move to Previous Item," "Move to Next Item," and "Select Item" for the buttons on mine. Do this for each of the three buttons. Go back to switch control settings and change Scanning Style to manual. What this means is that when you activate the switch control feature, your device will scan previous and next in rows, allowing you to select an item, which then you can tap or do other touch commands. Don't forget to toggle on Switch Control at the top. The LED light will give you visual feedback.

Step 7: That's It!

This small version of a switch control system demonstrates how iOS Switch Control works. It would be easily feasible to use different types of switches to make a better low-cost physical input accessibility system for someone using a smartphone.

Assistive Tech Contest

Participated in the
Assistive Tech Contest