SmartKeys.cpp


#include <Arduino.h>

#include <SPI.h>

#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined (_VARIANT_ARDUINO_ZERO_)

#include <SoftwareSerial.h>

#endif


#include "Adafruit_BLE.h"

#include "Adafruit_BluefruitLE_SPI.h"

#include "Adafruit_BluefruitLE_UART.h"


#include "BluefruitConfig.h"



#define FACTORYRESET_ENABLE 0

#define MINIMUM_FIRMWARE_VERSION "0.6.6"

#define MODE_LED_BEHAVIOUR "MODE"


int speakerPin = 4;

int numTones = 10;

int tones[] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440};

// mid C C# D D# E F F# G G# A


int whiteTones[] = {261, 294, 330, 349, 392, 440, 493};

int blackTones[] = {277, 311, 0, 370, 415, 466, 0};



// Create the bluefruit object, either software serial...uncomment these lines


SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);


Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,

BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);



// A small helper

void error(const __FlashStringHelper*err) {

Serial.println(err);

while (1);

}


/**************************************************************************/

/*!

@brief Sets up the HW an the BLE module (this function is called

automatically on startup)

*/

/**************************************************************************/

void setup(void)

{

while (!Serial); // required for Flora & Micro

delay(500);


Serial.begin(115200);

Serial.println(F("Smart Keys Example with Adafruit BLE UART"));

Serial.println(F("---------------------------------------"));


/* Initialise the module */

Serial.print(F("Initialising the Bluefruit LE module: "));


if ( !ble.begin(VERBOSE_MODE) )

{

error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));

}

Serial.println( F("OK!") );


if ( FACTORYRESET_ENABLE )

{

/* Perform a factory reset to make sure everything is in a known state */

Serial.println(F("Performing a factory reset: "));

if ( ! ble.factoryReset() ){

error(F("Couldn't factory reset"));

}

}


/* Disable command echo from Bluefruit */

ble.echo(false);


Serial.println("Requesting Bluefruit info:");

/* Print Bluefruit information */

ble.info();


Serial.println(F("Please use SmartKeys app to connect in UART mode"));

Serial.println(F("Then press keys to play sound"));

Serial.println();


ble.verbose(false); // debug info is a little annoying after this point!


/* Wait for connection */

while (! ble.isConnected()) {

delay(500);

}


// LED Activity command is only supported from 0.6.6

if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )

{

// Change Mode LED Activity

Serial.println(F("******************************"));

Serial.println(F("Change LED activity to " MODE_LED_BEHAVIOUR));

ble.sendCommandCheckOK("AT+HWModeLED=" MODE_LED_BEHAVIOUR);

Serial.println(F("******************************"));

}

}


/**************************************************************************/

/*!

@brief Constantly poll for new command or response data

*/

/**************************************************************************/

void loop(void)

{

// Check for user input

char inputs[BUFSIZE+1];


if ( getUserInput(inputs, BUFSIZE) )

{

// Send characters to Bluefruit

Serial.print("[Send] ");

Serial.println(inputs);


ble.print("AT+BLEUARTTX=");

ble.println(inputs);


if (inputs[0] == '0') {

for (int i = 0; i < numTones; i++) {

tone(speakerPin, tones[i]);

delay(500);

}

noTone(speakerPin);

}

}


// check response stastus

if (! ble.waitForOK() ) {

Serial.println(F("Failed to send?"));

}


// Check for incoming characters from Bluefruit

ble.println("AT+BLEUARTRX");

ble.readline();

if (strcmp(ble.buffer, "OK") == 0) {

// no data

return;

}

// Some data was found, its in the buffer

Serial.print(F("[Recv] "));

Serial.println(ble.buffer);

if (ble.buffer[0] >= 'A' && ble.buffer[0] <= 'G') {

tone(speakerPin, blackTones[ble.buffer[0] - 'A']);

} else if (ble.buffer[0] >= '0' && ble.buffer[0] <= '6') {

tone(speakerPin, whiteTones[ble.buffer[0] - '0']);

}

delay(200);

noTone(speakerPin);

ble.waitForOK();

}


/**************************************************************************/

/*!

@brief Checks for user input (via the Serial Monitor)

*/

/**************************************************************************/

bool getUserInput(char buffer[], uint8_t maxSize)

{

// timeout in 100 milliseconds

TimeoutTimer timeout(100);


memset(buffer, 0, maxSize);

while( (Serial.peek() < 0) && !timeout.expired() ) {}


if ( timeout.expired() ) return false;


delay(2);

uint8_t count=0;

do

{

count += Serial.readBytes(buffer+count, maxSize);

delay(2);

} while( (count < maxSize) && !(Serial.peek() < 0) );


return true;

}