Things used in this project

Hardware components:
Ardgen 101
Arduino 101 & Genuino 101
×1
09590 01
LED (generic)
×1
08377 02 l
Resistor 330 ohm
×1
12002 04
Breadboard (generic)
×1
11026 02
Jumper wires (generic)
×1
Software apps and online services:
Ide web
Arduino IDE

Schematics

lend_me_your_ears_snip_png_37ZEnEswIn.jpeg
Lend me your ears snip png 37zeneswin

Code

Untitled fileArduino
#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;     
  }
}  

Credits

C98775f523b7da6542fa6d4be148ea48
Liren Yeo

Web Developer

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

3D-Printed Prank Vibrating Cup
Easy
  • 1,401
  • 14

Full instructions

The instant your prankee lifts up this 3D-printed cup it starts violently vibrating! The electronics separate from the cup for easy washing.

The Magic Display With Arduino - The Mind Reader
Easy
  • 1,605
  • 6

Full instructions

The Magic Display With Arduino can figure out with a few clues what is your choose on a card with 64 options of numbers, letters or symbols.

Get Connected! WiFi Registration Using AP Mode!
Easy
  • 1,581
  • 16

Full instructions

Stop reflashing your devices everytime the WiFi password changes! Learn how to use anduinoWiFi and AP mode to initiate WiFi registration!

Car Blinker
Easy
  • 271
  • 4

Protip

Blink for Vehicles, such as bikes and skates. Easy.

The Soldering Iron Controller for Hakko T12 Tips
Easy
  • 8,903
  • 27

Full instructions

Per-tip calibration and high-frequency temperature check by Timer1.

Voltmeter Using Arduino
Easy
  • 3,281
  • 45

Protip

If you can't find a voltmeter at home or anywhere else, then this hack is for you!

Voltmeter Using Arduino

Team Next Tech Lab

ProjectsCommunitiesContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login
Respect project
Feedback