Bluefruit LE UART Friend on Arduino Uno

So recently I bought some LED's (WS2812B if you were curious) and decided I wanted to be able to control them with my phone. I got the Bluefruit LE UART Friend and tried hooking it up. Current wiring:
MOD -> 12
CTS -> 11
TXO -> 10
RXI -> 9
RST -> 8
GND -> GND
Vin -> 5V
I downloaded the "Adafruit BluefruitLE nRF51" library and tried the "atcommand" and "bleuart_cmdmode" examples. Following instructions on the adafruit page I learned how to hook it up. However, on the site it says Arduino Uno is best for hardware UART and in the example it says it's best on software UART. Both don't seem to work for me and I was wondering if someone could lead me through the process of setting up this beast.

#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"

#include "BluefruitConfig.h"

#if SOFTWARE_SERIAL_AVAILABLE
  #include <SoftwareSerial.h>
#endif

/*=========================================================================
    APPLICATION SETTINGS

    FACTORYRESET_ENABLE       Perform a factory reset when running this sketch
   
                              Enabling this will put your Bluefruit LE module
                              in a 'known good' state and clear any config
                              data set in previous sketches or projects, so
                              running this at least once is a good idea.
   
                              When deploying your project, however, you will
                              want to disable factory reset by setting this
                              value to 0.  If you are making changes to your
                              Bluefruit LE device via AT commands, and those
                              changes aren't persisting across resets, this
                              is the reason why.  Factory reset will erase
                              the non-volatile memory where config data is
                              stored, setting it back to factory default
                              values.
       
                              Some sketches that require you to bond to a
                              central device (HID mouse, keyboard, etc.)
                              won't work at all with this feature enabled
                              since the factory reset will clear all of the
                              bonding data stored on the chip, meaning the
                              central device won't be able to reconnect.
    MINIMUM_FIRMWARE_VERSION  Minimum firmware version to have some new features
    MODE_LED_BEHAVIOUR        LED activity, valid options are
                              "DISABLE" or "MODE" or "BLEUART" or
                              "HWUART"  or "SPI"  or "MANUAL"
    -----------------------------------------------------------------------*/
    #define FACTORYRESET_ENABLE         0
    #define MINIMUM_FIRMWARE_VERSION    "0.6.6"
    #define MODE_LED_BEHAVIOUR          "MODE"
/*=========================================================================*/

// 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);
*/

/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */
// Adafruit_BluefruitLE_UART ble(Serial1, BLUEFRUIT_UART_MODE_PIN);

/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
//Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
//                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
//                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);


// 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("Adafruit Bluefruit Command Mode Example"));
  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 Adafruit Bluefruit LE app to connect in UART mode"));
  Serial.println(F("Then Enter characters to send to Bluefruit"));
  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);

    // 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);
  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.available()) && !timeout.expired() ) { delay(1); }

  if ( timeout.expired() ) return false;

  delay(2);
  uint8_t count=0;
  do
  {
    count += Serial.readBytes(buffer+count, maxSize);
    delay(2);
  } while( (count < maxSize) && (Serial.available()) );

  return true;
}

Replace that tabell with proper schematics. There is more information to show that often solves problems. Most helpers are not playing with those devices regularly.

Do you have an iphone or Android? If you have an Android phone you will find it much easier to use an HC05 and classic Bluetooth instead of BLE.

If you must use BLE with an iphone and want to use the Bluefruit LE UART Friend you must set it up for UART and not SPI.
You have created the wrong Bluefruit Object. With the Uno, use a software serial object and not the SPI objectg.

/ 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);
*/

/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */
// Adafruit_BluefruitLE_UART ble(Serial1, BLUEFRUIT_UART_MODE_PIN);

/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
//Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
//                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
//                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

// A small helper
void error(const __FlashStringHelper*err) {
  Serial.println(err);
  while (1);
}

How do I show it properly then?

I have an Android. What is an HC05?

If I set it up with software serial object, is that good for IOS or Android? (or both?)

So I uploaded it with the SPI line uncommented, but how would I make it send something in the UART Chat thingy for example?

Post the schematics, as already told. Pen and paper often works if You don't have access to any drawing program.


C'est mieux, monsieur ? (Better, sir?)

It is a very commonly used classic Bluetooth module with an Arduino. Given your evident confusion with the use of the Bluefruit LE UART friend I would recommend the classic Bluetooth route.

There are many tutorials online. Google "HC05 Arduino" for plenty of information.

There are many standard Android phone apps which can simply communicate with the module. I recommend Kai Morich's Serial Bluetooth Terminal

Does that mean I cannot use this bluetooth module and have to order an other one? :frowning:

If you want to use classic bluetooth you will need a new HC05 module.

If you are willing to climb the learning curve to use the Bluefruit LE UART Friend you can certainly use it. Unforunately, the Adafruit documentation and support is a good as it gets, and if you can't understand how to configure and use the device with the Adafruit tutorials then its best to take the more simple classic bluetooth route.

I understand it is more difficult and wish to proceed anyways, improving my Arduino experience. :ballot_box_with_check:
Hahah, jokes aside, would you know how to fix my problem? The Serial Monitor says, "Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"
I did exactly as described here:
image

I think I solved it. The problem must have been the breadbord! I pulled it out and percuriously placed the wires so they wouldn't fall out and it now seems to work. Just not sure how to make it do what I want to. (Receive info and commands from my phone)

This is the tutorial for the basic phone connection
https://learn.adafruit.com/introducing-the-adafruit-bluefruit-le-uart-friend/bleuart

Can you find the example sketch bleuart_cmdmode in the library? Can you change from the default SPI mode to the software serial UART mode? Do you have the recommended Adafruit app on your phone?

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);

Okay alot of questions.

Thanks, checking that out right now.

Yup have it open now too.

Do you mean the same way as we just changed it on the other sketch? If so, yes.

Yup, have the Bluefruit Connect app downloaded and open. (Android)

Yes, but.... You forgot one important piece, the powering of the project. The BLE need quite some current when it is transmitting. Supplying that from controller might give You trouble. Extra capacitors, 100 uF or more, and 10-100nF, connected between +5 and GND near the BLE circuit..

It's just on my laptop for now. Will be from a 9v wall socket adapter as soon as i'm finished.
I have another question though.
I got it working, and I can chat back and forth, but what variable is my phone texts? (RX) I am trying to do something like:

If (phoneinput == "test") {
Serial.println("Yay, it works");
}

What do I put in the statement? It seems like ble.buffer would be the one, as it says "Serial.println(ble.buffer);", but I can't seem to get it to work.

I wouldn't try that. It makes the poor, not heatsinked, 5 volt converter of the controller supply the BLE. I doubt it will work.
Use a 5 volt producing supply and connect it to both the BLE and the controller, in parallell. I would not run the BLE current through the tine copper strips in the controller.

Great progress :grinning:

Yes, the message from the phone is in ble.buffer.

Using strcmp() is a way to test what is in the buffer.

if ((strcmp(ble.buffer, "test") == 0))
{Serial.println("Yay it works");}

Here is a sketch I wrote some time ago to manage an led blink with the SPI BLE friend so you'll have to change to the software serial object.

//#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
//#include "Adafruit_BluefruitLE_UART.h"

#include "BluefruitConfig.h"

/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

#define LED_PIN  13
unsigned long BLINKTIME = 1000;
unsigned long t_blink = 0L;
int blinkState = LOW;

void setup(void)
{
  pinMode(LED_PIN, OUTPUT);
  ble.begin();
  ble.factoryReset();

  Serial.begin(115200);
}

void loop(void)
{
 // static int val = 0;
  // Now Check for incoming characters from Bluefruit
  ble.println("AT+BLEUARTRX");
  ble.readline();

  if ((strcmp(ble.buffer, "STATUS") == 0))
  {
    ble.print("AT+BLEUARTTX=");
    if (t_blink) {
      ble.println("STATUS = BLINK");
    }
    else {
      if (blinkState)
        ble.println("STATUS = ON");
      else
        ble.println("STATUS = OFF");
    }
  }

  if ((strcmp(ble.buffer, "ON") == 0))
  {
    blinkState = HIGH;
    digitalWrite(LED_PIN, blinkState);
    t_blink = 0;
    ble.print("AT+BLEUARTTX=");
    ble.println("ON");
  }

  if ((strcmp(ble.buffer, "OFF") == 0))
  {
    blinkState = LOW;
    digitalWrite(LED_PIN, blinkState);
    t_blink = 0;
    ble.print("AT+BLEUARTTX=");
    ble.println("OFF");
  }

  if ((strcmp(ble.buffer, "BLINK") == 0))
  {
    if (!t_blink) t_blink = millis();
    ble.print("AT+BLEUARTTX=");
    delay(50);
    ble.println("BLINK");
  }

  //Terminal input to modify blink rate "Txxx" 
  if (ble.buffer[0] == 'T')//does terminal input start with "T"
  {
    //use memmove or create pointer and increment index to get to integer after 'T'
    //memmove(ble.buffer, ble.buffer+1, strlen(ble.buffer));//strlen does not include null terminator
    //int value = atoi(ble.buffer);
    char *bufferString = ble.buffer;
    bufferString++;
    int value = atoi(bufferString);
    BLINKTIME = value;
  }

  if (t_blink) {
    if (t_blink > millis()) t_blink = millis();
    if ((millis() - t_blink) > BLINKTIME) {
      blinkState = !blinkState;
      digitalWrite(LED_PIN, blinkState);
      t_blink = millis();
    }
  }
}

Thank you so much! It works! Finally :smiley:

Can I use a wall socket adapter that converts to 5V then?

Yes. That's what I would go for.

Perfect! I will order one asap. Any other technical suggestions before I plug in and explode my Arduino? :slight_smile: