Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
|
I attended an Arduino 101 meet-up in KL organized by Vincent Wong.
Had my very first hands on experience with Arduino Genuino 101 and it was awesome!!
Based on these resources, my friends and I managed to create a voice activated LED - using a voice recognition website, we can turn the LED on/off using certain words.
First connect up breadboard and Arduino based on the schematics provided here.
Then, use Arduino IDE and flash the provided code. Here is a link to the original repo.
Lastly, visit this website using chrome: https://s3-us-west-2.amazonaws.com/lendmeyourears/Index.html
Think of 2 words, to turn on each of the LEDs.
On the website, do the following:
- Turn on the bluetooth on your laptap
- Put in those words as unique name and click save.
- Press the big bluetooth icon, a popup will appear
- Find "ConnectMe', and pair!
Voila! Speak out the magic words (the unique names you typed in) and see the LED turns on. Repeat those words to turn the same LED off!
#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("ConnectMe");
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;
}
}
Comments