The first thing is to go out and read this: https://learn.adafruit.com/getting-started-with-the-nrf8001-bluefruit-le-breakout/introduction
or this: https://learn.adafruit.com/downloads/pdf/getting-started-with-the-nrf8001-bluefruit-le-breakout.pdf
Done? Good.
Previous tutorials have worked with the SainSmart OLED which uses a 1306 SSD (the code for this can also be found at Adafruit for their graphics – https://learn.adafruit.com/monochrome-oled-breakouts/arduino-library-and-examples).
The nrf8001 and the 1306 are fantastic together.
This is a very simple sketch to put together. I take the echoDemo from Adafruit and add some custom code for the OLED (which most comes from Adafruit as well).
You can see that i added the Adafruit_GFX.h and Adafruit_SSD1306.h to the includes, but I didn’t add them to the libraries so they’re local to the sketch. I did this so i could work on any code changes before putting them in the libraries directory of Arduino. You can do whatever you want with the libraries.
The only other modifications I did to the code was add a method to print a string to the OLED and I concat the chars together into a string that persists as long as we’re connected.
The result is sending data from my phone to the BLE which is displayed on the OLED.
This will come in handy for future reporting from the arduino to my phone or sending commands to the arduino or the HUD I’m working on now. Eventually, I’ll swap this for an Arduino Nano and write the Appcelerator code for a custom app to manage the HUD.
/*********************************************************************
This is an example for our nRF8001 Bluetooth Low Energy Breakout
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/1697
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Kevin Townsend/KTOWN for Adafruit Industries.
MIT license, check LICENSE for more information
All text above, and the splash screen below must be included in any redistribution
*********************************************************************/
// This version uses the internal data queing so you can treat it like Serial (kinda)!
#include
#include
#include "Adafruit_BLE_UART.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
// Connect CLK/MISO/MOSI to hardware SPI
// e.g. On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 2 // This should be an interrupt pin, on Uno thats #2 or #3
#define ADAFRUITBLE_RST 9
Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
#define OLED_RESET 6
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
/**************************************************************************/
/*!
Configure the Arduino and start advertising with the radio
*/
/**************************************************************************/
void setup(void)
{
Serial.begin(9600);
while(!Serial); // Leonardo/Micro should wait for serial init
Serial.println(F("Adafruit Bluefruit Low Energy nRF8001 Print echo demo"));
// BTLEserial.setDeviceName("NEWNAME"); /* 7 characters max! */
BTLEserial.begin();
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS); // initialize with the I2C addr 0x3C (for the 128x32)
// init done
display.clearDisplay();
display.display();
//testLoop();
}
/**************************************************************************/
/*!
Constantly checks for new events on the nRF8001
*/
/**************************************************************************/
aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;
String tmp = "";
void loop()
{
// Tell the nRF8001 to do whatever it should be working on.
BTLEserial.pollACI();
// Ask what is our current status
aci_evt_opcode_t status = BTLEserial.getState();
// If the status changed....
if (status != laststatus) {
// print it out!
if (status == ACI_EVT_DEVICE_STARTED) {
Serial.println(F("* Advertising started"));
//printOLED("$* Advertising started");
}
if (status == ACI_EVT_CONNECTED) {
Serial.println(F("* Connected!"));
}
if (status == ACI_EVT_DISCONNECTED) {
Serial.println(F("* Disconnected or advertising timed out"));
}
// OK set the last status change to this one
laststatus = status;
}
if (status == ACI_EVT_CONNECTED) {
// Lets see if there's any data for us!
if (BTLEserial.available()) {
Serial.print("* "); Serial.print(BTLEserial.available()); Serial.println(F(" bytes available from BTLE"));
tmp = "";
}
// OK while we still have something to read, get a character and print it out
while (BTLEserial.available()) {
char c = BTLEserial.read();
tmp.concat(c);
Serial.print(c);
}
printOLED(tmp);
// Next up, see if we have any data to get from the Serial console
if (Serial.available()) {
// Read a line from Serial
Serial.setTimeout(100); // 100 millisecond timeout
String s = Serial.readString();
// We need to convert the line to bytes, no more than 20 at this time
uint8_t sendbuffer[20];
s.getBytes(sendbuffer, 20);
char sendbuffersize = min(20, s.length());
Serial.print(F("\n* Sending -> \"")); Serial.print((char *)sendbuffer); Serial.println("\"");
// write the data
BTLEserial.write(sendbuffer, sendbuffersize);
}
}
}
void printOLED(String sendBuffer) {
display.clearDisplay();
// text display tests
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(sendBuffer);
display.display();
}