#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;
}