BLE + OLED + Arduino MEGA + iPhone 4s

This is geared towards my iPhone 4s, but really any BLE (Bluetooth 4.0) enabled device will work.

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.