Project tutorial
Hackster Live March 2017 Workshop

Hackster Live March 2017 Workshop

Learn to voice control LEDs using Web Bluetooth and Arduino/Genuino 101.

  • 1,619 views
  • 1 comment
  • 14 respects

Components and supplies

Apps and online services

About this project

Introduction:

For our March Hackster Live workshop we will be using Greg V.’s "Lend me your ears" project as our inspiration. After creating this project you should be able to turn on and off an led, or other ***low voltage (<12 volts) device*** of your choosing through low energy bluetooth using voice commands. A big thank you goes out to our sponsors, Intel and Mikroelektronika, for providing the hardware that we will be using for this project.

***WARNING - Do NOT attempt to control any high voltage AC or DC devices or expose the wires of high voltage AC or DC device. Do NOT use any device over 12 volts as this could lead to strong electric shock if used improperly!***

Hackster has modified the original version of this project to be achievable for beginners with an option to extend the project using the original project outlined here. If you choose to do the extended edition of this project you need to be aware the of the warning above. Please do not attempt the extended edition if you are unfamiliar with the basics of electrical engineering. **Hackster is not responsible for any damages or injuries sustained while completing this project.**

What you will need for this project:

Mac with Yosemite or newer operating system, chromebook, or linux. For chromebook instructions see Greg’s project here.

See steps below to find out which operating system you have on your Mac

1. Click the apple icon and go to “about this mac”

2. The version will pop up on your screen, make sure the version is Yosemite (vs. 10.10), El Captain (vs. 10.11) or Sierra (vs. 10.12). If you have a version older than 10.10 you will need to download the newest version to complete this project.

3. For a good overview of how to backup your mac and install the newest operating system check out this article here.

Computer that supports bluetooth.

See steps below to check if your mac supports bluetooth

1. Go to the apple icon and click about this mac.

2. Click the system report button.

3. Click Bluetooth in the left column and look at the 4th row and make sure it says “Bluetooth Low Energy Supported” - “Yes” . If Bluetooth Low Energy is not supported you will not be able to complete this project using this device.

Updated Chrome Web Browser - You should have version 53 or higher

If you don’t have the chrome web browser download it here.

If you have chrome, see the steps below to find out which version you have on your Mac:

1. Go to the dock at the bottom of your desktop and click on the chrome icon to open chrome.

2. Now go to the menu bar on your desktop and go to “chrome” and click “About google chrome”

3. You will see the version you are using and whether your version is up to date. If you have a version of Chrome less than version 53, follow the prompts to install the latest version.

Arduino IDE with Arduino/Genuino 101 installed

Download Arduino IDE here.

Once you have downloaded the Arduino IDE, make sure it has the drivers for the Arduino/Genuino 101 by following these steps

1. Click Tools → Board → Boards manager.

2. Scroll down the list and find the “Intel Curie Boards” by Intel. If it is not installed, click “install” and follow the prompts making sure to allow the app to make changes on your device.

3. Once installed, go to the Arduino IDE, click Tools → Board → Arduino/Genuino 101 at the bottom of the dropdown menu.

Instructions: Basic LEDs without the relay

We recommend starting with this basic sketch first to make sure that your Arduino code and the voice control through the website is working properly. Once you have completed this basic LED tutorial, we encourage you to follow Greg’s instructions here to create your own project using the click shields provided and a low voltage (<12 volts) device of your choice.

Hardware Setup

  • Connect LED 1 (this matches relay one when using the relay) to pin 6 and LED 2 (this matches relay two when using the relay) to pin 10. Follow the Fritzing diagram and picture below:

*Note, the Fritzing diagram above shows an arduino UNO. This is NOT the board we are using. You should be using an Arduino/Genuino 101. The UNO does not have BLE capabilities and will not work for this project.

Arduino Code

  • Open your Arduino IDE and connect your Arduino/Genuino 101 to your computer
  • Make sure you’re board is set to Arduino/Genuino 101 and you have selected the correct USB port
  • Go to Greg’s github page here and click on the folder arduino sketch
  • Click relayClick5.ino link
  • You should now see the arduino code for this project. Copy and paste this code into your Arduino IDE window.
  • Scroll down to line 126 of your code, where it says “blePeripheral.setLocalName("relays");”. The line numbers are displayed on the bottom left hand corner of your Arduino IDE screen.
  • Change “relays” to a unique name of your choice containing 8 characters or less. Since there will be multiple bluetooth connections in one room, this will allow you to identify and pair with the your device and not your neighbor’s. I changed my local name to “katie”.
  • Now upload your code to your arduino.

Using BLE with voice control

  • If you would like to find out more about how to make your own website visit Greg’s project here. Greg used github to host his website. I chose to host my modified version of his website using Amazon’s AWS S3 services.
  • Click the bluetooth icon and choose the device that matches the local name that you changed in your arduino code. In my case this was “katie” so I click “katie” and click pair.
  • Once your device has paired you will see a green “paired” under your device name.
  • Now you have a choice, you can use the pre-coded commands below:

relayOne: relay one, one, lamp, desklamp

relayTwo: relay two, two

Or you can create your own trigger words. I decided to create my own trigger words and made relay one “green” for my green LED, and relay two “red” for my red LED. Now when I say “green” my green light will turn on and if I say “green” again it will turn off. And “red” will turn on and off my red LED.

  • If you want to make sure that the web bluetooth is hearing you and capturing your words correctly, turn on the development tools on the right hand side of the screen by going to chrome’s menu→ more tools → developer tools.

Now you can see read what the web bluetooth hears. It will also allow you to troubleshoot any problems you run into.

Code

Lend me your ears CodeArduino
#include <CurieBLE.h>
/**
 * Example demonstrating the use of the relay click and arduino uno click shield from
 * MikroElektronika.
 * 
 * Uplaod this sketch to your arduino/genuino101, complete the circuit and access from the web!
 * Web Bluetoooth goodness!
 * 
 * To be added:
 *    2) BLE control. Done
 *    3) relay object. Done
 *    4) relay interval function. Done
 *    5) RTC "alarm clock" function. Yet to be done . . .
 */

/**
 * pins for each relay specified here. 
 * depend on the Arduino click shield specifications, with the relay click board 
 * plugged into slot 1
 */
#define RELAY1 6 
#define RELAY2 10

/**
 * The Relay object will model the relay state and help with control flow in the loop()
 * function.
 */

class Relay
{

  int relayID;
  int pinAssignment;
  boolean relayState;
  boolean intervalState;
  long interval;
  boolean intervalToggle;

  public:

  Relay(int id, int pin )
  {
    relayID = id;
    pinAssignment = pin;
    relayState = false;  
    intervalState = false;
    interval = 0;
    intervalToggle = false;
  }

  /*
   * The relay is initialized to the physical pin assigned to it and 
   * this pin is set to low.
   * Not the relay intial states are set in the relay constructor.
   */
  void initialize()
  {
    pinMode( pinAssignment, OUTPUT);
    digitalWrite(pinAssignment,LOW);
  }
  
  int getRelayID() {return relayID;}
  void setRelayId(int id) {relayID = id;}

  int getPinAssignment() {return pinAssignment;}
  void setPinAssignment(int pin) {pinAssignment = pin;}

  boolean getRelayState() {return relayState;}
  void setRelayState(boolean state ) {relayState = state;}

  boolean getIntervalState() {return intervalState;}
  void setIntervalState(boolean state) { intervalState = state;}

  long getInterval(){return interval;}
  void setInterval(long i) {interval = i;}

  boolean getIntervalToggle() {return intervalToggle;}
  void setIntervalToggle(boolean tog){intervalToggle = tog;}

  void toggle() 
  { 
    intervalToggle = !intervalToggle;
    digitalWrite(pinAssignment, intervalToggle);
  }

  void turnOn()
  {
    digitalWrite(pinAssignment,HIGH);
  }

  void turnOff()
  {
    digitalWrite(pinAssignment,LOW);
  }

};

Relay relay1(1, RELAY1);
Relay relay2(2, RELAY2);

// timing parameters
long currentMillis, previousMillisRelay1, previousMillisRelay2;

union
{
  long interval;
  unsigned char bytes[4];  
} relaySettings;

/* establish BLE service & characteristics */
BLEPeripheral blePeripheral;
BLEService relayService("917649A0-D98E-11E5-9EEC-0002A5D5C51B");
BLECharacteristic relayCharacteristic("917649A1-D98E-11E5-9EEC-0002A5D5C51B", BLEWrite, 5);
// BLEUnsignedCharCharacteristic relayCharacteristic("917649A1-D98E-11E5-9EEC-0002A5D5C51B", BLERead | BLEWrite);
BLEDescriptor relayDescriptor("2902","relay");

void setup() 
{
  // initiate serial communications for debugging
  Serial.begin(9600);
  Serial.println("click relay example");
 /** 
   *  BLE initilizations
   */

  blePeripheral.setLocalName("relays");
  blePeripheral.setAdvertisedServiceUuid(relayService.uuid());
  blePeripheral.addAttribute(relayService);
  blePeripheral.addAttribute(relayCharacteristic);
  blePeripheral.addAttribute(relayDescriptor);

  blePeripheral.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  blePeripheral.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
  relayCharacteristic.setEventHandler(BLEWritten, relayCharacteristicWritten);
  
  // All BLE characteristics should be initialized to a starting value prior
  // using them.

  const unsigned char relayInitializer[5] = {0,0,0,0,0};
  relayCharacteristic.setValue(relayInitializer,5);
  
  blePeripheral.begin();
  
  // Set relays to initial states
  relay1.initialize();
  relay2.initialize();

  // intialize timing paramters
  currentMillis = millis();
  previousMillisRelay1 = millis();
  previousMillisRelay2 = millis();
  
}

void loop() 
{
  /**
   * The main loop() checks for the relays being set to intervals and
   * toggles then is so and the interval is exceeded.
   */

  currentMillis = millis();
  
  if (relay1.getIntervalState()) 
  {
    if ((currentMillis - previousMillisRelay1) > relay1.getInterval())
    {
      relay1.toggle();
      previousMillisRelay1 = currentMillis;
      Serial.println("toggle1");
    }
  }

  if (relay2.getIntervalState())
  {  
    if ((currentMillis - previousMillisRelay2) > relay2.getInterval())
    {
      relay2.toggle();
      previousMillisRelay2 = currentMillis;
      Serial.println("toggle2");
    }
  }
  
}

void blePeripheralConnectHandler(BLECentral& central) 
{
  // central connected event handler
  Serial.print("Connected event, central: ");
  Serial.println(central.address());
}

void blePeripheralDisconnectHandler(BLECentral& central) 
{
  // central disconnected event handler
  Serial.print("Disconnected event, central: ");
  Serial.println(central.address());
}

void relayCharacteristicWritten(BLECentral& central, BLECharacteristic& characteristic)
{
  /**
   * This function is called whenever the user changes the relayCharacteristic on the hybrid
   * web app. It is used to chage the state of the relay object, these changes are then
   * checked for in the loop. 
   * Why? Well if we wished to simply turn the relays off and on, this approach is unnecessary. 
   * we could just simply turn the relays off and on in the swtch/case statement. However
   * we would like to add other functionality to the relays, such as interval on/off timing.
   * Since we have 2 relays we can;t use the CurieTImer library, it has only one timer and we may
   * wish to have different timing intervals for each relay. Addtionally this approach will allow
   * us to more easily extend this app to many relays, which is is more realisitc for
   * a home automation system.
   */
  const unsigned char* relayData = relayCharacteristic.value();
  
  relaySettings.bytes[0] = relayData[4];
  relaySettings.bytes[1] = relayData[3];
  relaySettings.bytes[2] = relayData[2];
  relaySettings.bytes[3] = relayData[1];

  // convert interval byte array to long by casting;
  long interval = (long)relaySettings.interval;
  switch(relayData[0])
  {
    case 0:
      // 0 value, do nothing
      Serial.print(relayData[0]);
      Serial.print(" written ");Serial.print("interval: ");Serial.println(interval);
      break;
    case 1:
      // relay 1 selected
      Serial.print("relay1: ");Serial.print(relayData[0]);Serial.print(" interval: ");Serial.println(interval);
      if (interval != 0) 
      {
        relay1.setIntervalState(true);
        relay1.setRelayState(true);
        relay1.setInterval(interval);
      } else {
        if (relay1.getRelayState()) 
        { 
          relay1.setRelayState(false); 
          relay1.turnOff(); 
          relay1.setIntervalState(false);
          relay1.setInterval(0); 
        }
        else {
          relay1.setRelayState(true); 
          relay1.turnOn();
          relay1.setIntervalState(false);
          relay1.setInterval(0);
        }       
      }
      break;
    case 2:
      // relay 2 selected
      Serial.print("relay2: ");Serial.print(relayData[0]);Serial.print(" interval: ");Serial.println(interval);
      if (interval != 0) 
      {
        relay2.setIntervalState(true);
        relay2.setRelayState(true);
        relay2.setInterval(interval);
      } else {
        if (relay2.getRelayState()) 
        { 
          relay2.setRelayState(false); 
          relay2.turnOff(); 
          relay2.setIntervalState(false);
          relay2.setInterval(0); 
        }
        else {
          relay2.setRelayState(true); 
          relay2.turnOn();
          relay2.setIntervalState(false);
          relay2.setInterval(0);
        }       
      }
      break;     
  }
}  

Schematics

LED Circuit
Lend me your ears snip zmq4x4bsrd

Comments

Similar projects you might like

Hackster Live April 2017 Workshop - Optional - Easy Add-on

Project tutorial by Katie Kristoff

  • 883 views
  • 3 comments
  • 7 respects

Arduino 101 BLE App

Project in progress by Alexis Santiago Allende

  • 10,794 views
  • 26 comments
  • 51 respects

SMART CUBE: A New Way to Control Your Home

Project tutorial by Alberto Sartori

  • 13,527 views
  • 7 comments
  • 30 respects

Oled Display with Arduino 101

Project tutorial by Alexis Santiago Allende

  • 6,083 views
  • 1 comment
  • 25 respects

Very First Hands On Arduino - Voice Activated LED

Project tutorial by Liren Yeo

  • 3,732 views
  • 2 comments
  • 18 respects

Android Listen to Me

Project showcase by Gustavo Reynaga

  • 722 views
  • 2 comments
  • 6 respects
Add projectSign up / Login