Here we'll code the board in Arduino to change colors using the Bluefruit app on iOS and Android, as well as to react to tilting your MUNNY to change to a random color.

There's a lot of info to digest on the Feather M0 Bluefruit LE, so check out the guide here if you have questions.

First, get set up with Arduino IDE as detailed here.

Next, follow these instructions on getting the proper libraries installed. In this code we use the following libraries:

  • Adafruit_BLE
  • Adafruit_Bluefruit_SPI
  • Adafruit_BluefruitLE_UART
  • Adafruit_LIS3DH

The first three come from installing the Adafruit BluefruitLE nRF51 library.

The other library to install is Adafruit LIS3DH, which is for the accelerometer built onto the Prop-Maker Wing.

Once you've updated the board definitions as shown, you'll be able to select Adafruit Feather M0 as your board for compiling and uploading.

Before you continue, make sure you can plug in your Feather over USB and upload the Blink sketch found in Arduino IDE menu Examples > 01.Basics > Blink

If everything is set up properly, the Feather should now be blinking the onboard LED every second.

Once that's working, try running the Bluefruit example sketch, as detailed here.

MUNNY Code

Next, we'll get the Munny_Lamp.ino code to upload to the Feather. First, download the Adafruit_Learning_Systems_Guides repo here.

You'll need to unzip the file and then navigate it to get to the Munny_Lamp directory. Move this directory it to your Arduino sketches directory.

Inside of the Arduino IDE, open the Munny_Lamp.ino sketch.

Note how Arduino automatically opens the associated BluefruitConfig.h file and the packetParser.cpp file. You won't need to worry about these, but they do need to be there for everything to function!

Upload the code to your Feather M0 Bluefruit LE now, so we can try out the remote color changing and tilt functions!

// MUNNY BLUEFRUIT LAMP
// Feather M0 Bluefruit + Prop-Maker Wing and 3W RDB LED
#include <string.h>
#include <Arduino.h>
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#if SOFTWARE_SERIAL_AVAILABLE
  #include <SoftwareSerial.h>
#endif

// pin definitions for using Prop-Maker FeatherWing
//#define NEOPIXEL_PIN 5
//#define SWITCH_PIN   9
#define POWER_PIN    10
#define RED_LED      11
#define GREEN_LED    12
#define BLUE_LED     13
int red = 0;
int green = 0;
int blue = 0;
#include "BluefruitConfig.h"
Adafruit_LIS3DH lis = Adafruit_LIS3DH();

/*=========================================================================
    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.
    PIN                       Which pin on the Arduino is connected to the NeoPixels?
    NUMPIXELS                 How many NeoPixels are attached to the Arduino?
    -----------------------------------------------------------------------*/
    #define FACTORYRESET_ENABLE     0
/*=========================================================================*/


// Create the bluefruit object, either software serial...uncomment these lines
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

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

// function prototypes over in packetparser.cpp
uint8_t readPacket(Adafruit_BLE *ble, uint16_t timeout);
float parsefloat(uint8_t *buffer);
void printHex(const uint8_t * data, const uint32_t numBytes);

// the packet buffer
extern uint8_t packetbuffer[];


/**************************************************************************/
/*!
    @brief  Sets up the HW an the BLE module (this function is called
            automatically on startup)
*/
/**************************************************************************/
void setup(void)
{
  delay(500);
  pinMode(POWER_PIN, OUTPUT);
  digitalWrite(POWER_PIN, HIGH);
  pinMode(RED_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  pinMode(BLUE_LED, OUTPUT);

  analogWrite(RED_LED, 0);
  analogWrite(GREEN_LED, 0);
  analogWrite(BLUE_LED, 255);  // startup color, waiting for BLE connection

  if (! lis.begin(0x18)) {   // change this to 0x19 for alternative i2c address
    Serial.println("Couldnt start LIS3DH");
    while (1);
  }

  Serial.begin(115200);
  Serial.println(F("Adafruit Bluefruit MUNNY LED Color Picker"));
  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 Controller mode"));
  Serial.println(F("Then activate/use the sensors, color picker, game controller, etc!"));
  Serial.println();

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

  /* Wait for connection */
  while (! ble.isConnected()) {
      delay(500);
  }

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

  // Set Bluefruit to DATA mode
  Serial.println( F("Switching to DATA mode!") );
  ble.setMode(BLUEFRUIT_MODE_DATA);

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

}

/**************************************************************************/
/*!
    @brief  Constantly poll for new command or response data
*/
/**************************************************************************/
void loop(void)
{
  digitalWrite(POWER_PIN, HIGH);

  /* Wait for new data to arrive */
  uint8_t len = readPacket(&ble, BLE_READPACKET_TIMEOUT);
  if (len == 0) {
    accelerometer_check();
    return;
    delay(10);
  }

  /* Got a packet! */
  // printHex(packetbuffer, len);

  // Color
  if (packetbuffer[1] == 'C') {
    uint8_t red = packetbuffer[2];
    uint8_t green = packetbuffer[3];
    uint8_t blue = packetbuffer[4];
    Serial.print ("RGB #");
    if (red < 0x10) Serial.print("0");
    Serial.print(red, HEX);
    if (green < 0x10) Serial.print("0");
    Serial.print(green, HEX);
    if (blue < 0x10) Serial.print("0");
    Serial.println(blue, HEX);

    analogWrite(RED_LED, red);
    analogWrite(GREEN_LED, green);
    analogWrite(BLUE_LED, blue);
  }

}

void accelerometer_check() {
  // Accelerometer
  sensors_event_t event;
  lis.getEvent(&event);
  Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
  Serial.print(" \tY: "); Serial.print(event.acceleration.y);
  Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
  Serial.println(" m/s^2 ");

  if (event.acceleration.y < 0) {
    analogWrite(RED_LED, random(0, 255));
    analogWrite(GREEN_LED, random(0, 255));
    analogWrite(BLUE_LED, random(0, 255));
    Serial.println("TILTED");
    delay(100);
  }
}

Testing

The LED will light up blue upon startup. The Feather is now waiting for you to connect to it with the Bluefruit app.

Connect

Launch the app and after a moment you'll see a list of BLE devices to which you can connect. Click the 'Connect' button next to the Adafruit Bluefruit LE device.

Controller

Now that you're connected, you can click on the 'Controller' module.

Color Picker

There are a number of choices in the Controller module, we'll use the 'Color Picker'.

Color Wheel

Now, you can pick on any color in the color wheel! Press 'Send selected color' when you want to change the RGB LED color wirelessly through the air!!

Note, you can also adjust the brightness by using the slider just below the color wheel.

This guide was first published on Nov 06, 2018. It was last updated on Nov 06, 2018.

This page (Code in Arduino) was last updated on Oct 23, 2021.

Text editor powered by tinymce.