fbpx

Neosensory Arduino SDK example project

Have an idea for building a sensory substitution project using Buzz and Arduino… but don’t know where to start? Here’s an example project for you to get started with our Neosensory Arduino Bluefruit SDK. With this SDK you can send any data stream you can gather via a sensor on an Arduino to your Buzz. 

Here, we’ll walk you through the example script that comes with our library. To learn more about the Neosensory Arduino SDK, visit the “Get started” section of this post.

This example script will cause the Arduino to connect to any powered-on Buzz and send vibration commands, causing Buzz to create vibrational patterns. While this example does not show you how to get data from a sensor, it demonstrates the code necessary to turn that data into vibrations on the wristband.

Let’s walk through each part of the example script so you can best understand how to make your own project. Start by opening the example script called connect_and_vibrate.ino. Once you’ve installed the library, you can find the example script in your Arduino IDE under File > Examples > NeosensoryBluefruit. 

Declarations

#include <neosensory_bluefruit.h>

This include statement imports our library into your script. You’ll need it in your script to use our SDK. 

NeosensoryBluefruit NeoBluefruit;

This declares a new instance of the NeosensoryBluefruit object, which is what you’ll use to communicate with your Buzz. If you are near multiple Buzz wristbands and need to connect to a specific one (rather than the first Buzz found), include the Device ID in your declaration statement, like this:

NeosensoryBluefruit NeoBluefruit("F2 CD 50 E2 96 31");
int motor = 0;
float intensity = 0;
float **rumble_frames;

These variables are specific to our example. We’ll use them to make Buzz vibrate in a specific way. When you build your own project you’ll use your own variables based on your sensor data to define the functionality to make Buzz vibrate.

Set up

void setup() {
  Serial.begin(9600);
  NeoBluefruit.begin();
  NeoBluefruit.setConnectedCallback(onConnected);
  NeoBluefruit.setDisconnectedCallback(onDisconnected);
  NeoBluefruit.setReadNotifyCallback(onReadNotify);
  NeoBluefruit.startScan();
  set_rumble_frames();
  while (!NeoBluefruit.isConnected() || !NeoBluefruit.isAuthorized()) {}
  NeoBluefruit.deviceInfo();
  NeoBluefruit.deviceBattery();
}

There’s a lot going on here, but it’s not difficult to understand each line. As a reminder, the code in your setup function runs only once, each time you power on your Arduino board.

Serial.begin(9600);

This starts the Serial connection, meaning you can open your Serial Monitor in the Arduino IDE and see debug statements being printed out. This is not strictly necessary. 

NeoBluefruit.begin();

This initializes our instance of NeosensoryBluefruit. You’ll need to run this before you use any other functionality from the NeoBluefruit object.

NeoBluefruit.setConnectedCallback(onConnected);
NeoBluefruit.setDisconnectedCallback(onDisconnected);
NeoBluefruit.setReadNotifyCallback(onReadNotify);

These lines set the functions that should be called on specific events. We define onConnected, onDisconnected, and onReadNotify ourselves and they get called whenever the microcontroller connects or disconnects from Buzz or receives data from Buzz. 

NeoBluefruit.startScan();

This tells your instance of NeosensoryBluefruit to start looking for a Buzz (or the specific Buzz, if you’ve supplied a Device ID). If it finds a Buzz, it will attempt to connect and will call the onConnected callback. 

set_rumble_frames();

This is also specific to our example. We are calling a function that will initialize a variable we will use later to demonstrate vibrating Buzz.

while (!NeoBluefruit.isConnected() || !NeoBluefruit.isAuthorized()) {}

We choose to wait to move on until we’re connected and have a successfully authorized Buzz. You can certainly omit this line and move on with your code before connection has happened – just don’t expect to be able to vibrate Buzz until connected and authorized.

NeoBluefruit.deviceInfo();
NeoBluefruit.deviceBattery();

Once we’ve connected to our Buzz, we print out some basic info about the wristband as well as the battery life on the band. You can see this in the Arduino Serial Monitor. 

And that’s all we’re doing in setup! Onto our loop.

Loop

Once the code inside setup has run once (when your board powers on), the code inside loop will execute repeatedly as long as your Arduino is on.

void loop() {
  if (NeoBluefruit.isConnected() && NeoBluefruit.isAuthorized()) {
    NeoBluefruit.vibrateMotor(motor, intensity);
    intensity += 0.1;
    if (intensity > 1) {
      intensity = 0;
      motor++;
      if (motor >= NeoBluefruit.num_motors()) {
        motor = 0;
        rumble();
        rumble();
        rumble();
      }
    }
    delay(50);
  }
}

In our loop, we’re first checking if we’ve connected and authorized our Buzz. If not, we do nothing. If so, we call NeoBluefruit.vibrateMotor(motor, intensity);, which vibrates Buzz at the given motor and intensity. Remember, we initialized motor to be 0, meaning the first vibrating motor will vibrate (Buzz has four motors: 0, 1, 2, and 3). However, we also initialized intensity to be 0, which is off. 

Why is intensity 0? Because we’ll start there, and then increase intensity by 0.1 (10%) each loop, until we’ve gotten to an intensity of 1 (full intensity). When we cannot increase the intensity any higher, we set it back to 0 and move on to our next motor. That’s what the following segment is doing: 

if (intensity > 1) {
  intensity = 0;
  motor++;
rumble();

Once we’ve moved through all four motors, we call our function rumble(), which is unique to this example and shows how to send multiple frames of motor intensities to the wristband. This is very useful for times when you cannot send Bluetooth frames quickly enough to give the desired level of vibration detail to your Buzz. Sending multiple frames causes the wristband to play out those frames sequentially, for 16 milliseconds each. See vibrateMotors() for more.

delay(50);

Finally, we wait 50 milliseconds before looping again. 

Helper Functions and Callbacks

void set_rumble_frames() {...}
void rumble() {...}

These two functions handle our example of sending multiple frames at once.

void onConnected(bool success) {...}

This is the function we determined would get called if the microcontroller connected to Buzz. Here, we print if we successfully connected or not and then, if connected, send the following commands to Buzz: 

NeoBluefruit.authorizeDeveloper();
NeoBluefruit.acceptTermsAndConditions();
NeoBluefruit.stopAlgorithm();

The first function, authorizeDeveloper(), tells Buzz to ask for developer access. Without this, we will only be able to do the most basic interactions with Buzz, such as get its Device ID. 

Upon sending this command, Buzz requests for the developer to accept the terms and conditions, which we do by calling acceptTermsAndConditions(). Please read our developer terms of service and only run acceptTermsAndConditions() if you accept these terms of service. 

Finally, we send stopAlgorithm(), since our Buzz is likely vibrating in response to audio. 

void onDisconnected(...) {...}

This function prints a notice to the Serial Monitor that Buzz has disconnected.

void onReadNotify(...) {...}

This function is called whenever Buzz has sent data to our microcontroller. This function prints out the data received.

You’ve now seen the in’s and out’s of the connect_and_vibrate.ino example script. You’re now ready to create a script of your own that vibrates Buzz in whatever manner you wish. Happy hacking!

Check back soon to read about some of the projects the Neosensory team has created with the Neosensory Arduino SDK. 

We also want to see what you create. Interested in sharing? Just drop us a line at developers@neosensory.com or visit the Neosensory developer Slack. We’ll feature select projects on our site.

By Mike Perrotta, Scientist