#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;
}
}
Comments
Please log in or sign up to comment.