Previous posts in this project:
- [Christmas Tree] Internet of Holiday Lights - Project Description
- [Christmas Tree] Internet of Holiday Lights - Getting Started
- [Christmas Tree] Internet of Holiday Lights - Control from openHAB
Introduction
I was approached by Jan Cumps some time ago, as he wanted to give the challenge an extra IoT twist.
After some messages going back and forth, the conclusion was that we would symbolise each other's project in our own design and have that component light up when the other design was online.
Heartbeat
Both our designs are making use of MQTT messages on the same broker (iot.eclipse.org).
We came up with the idea of having our designs send periodic messages (e.g. every minute) on a specific topic with a specific payload as a heartbeat mechanism.
Once a heartbeat is received, a timer is started and the symbol lit up. When a new heartbeat is received, the timer is reset, ensuring the symbol remains lit up.
However, if the timer expires because no heartbeat is received, the symbol is turned off as we assume the other design is offline.
Here's the code used to send my heartbeat (I removed the unrelated bits of code):
#include <Adafruit_NeoPixel.h> #include <SPI.h> #include <Ethernet.h> #include <PubSubClient.h> #include <Bridge.h> #include <YunClient.h> #include <Wire.h> #include <Infineon.h> #include <Console.h> long isAlive = 0; YunClient yunClient; PubSubClient client("iot.eclipse.org", 1883, callback, yunClient); void setup() { Bridge.begin(); Console.begin(); Console.println("Connected to console."); Wire.begin(); // connect to MQTT broker and subscribe to topic if (client.connect("arduinoYunClient")) { client.publish("19e5983adc0f","fvan"); isAlive = millis(); delay(50); } } void loop() { client.loop(); // send heartbeat sendHeartbeat(); } void sendHeartbeat() { if(millis() - isAlive >= 30000) { client.publish("19e5983adc0f","fvan"); isAlive = millis(); } }
And the code used to process Jan's heartbeat (unrelated bits removed as well):
#include <Adafruit_NeoPixel.h> #include <SPI.h> #include <Ethernet.h> #include <PubSubClient.h> #include <Bridge.h> #include <YunClient.h> #include <Wire.h> #include <Infineon.h> #include <Console.h> long checkAlive = 0; Adafruit_NeoPixel widget = Adafruit_NeoPixel(12, 7, NEO_GRB + NEO_KHZ800); YunClient yunClient; PubSubClient client("iot.eclipse.org", 1883, callback, yunClient); void callback(char* topic, byte* payload, unsigned int length) { // Check for messages on subscribed topics Console.print("Topic: "); Console.println(String(topic)); if(String(topic) == "1cfee8dd0afc") { String value = String((char*)payload); if(value == "jancumps"){ checkAlive = millis(); Console.println("Widget heartbeat received"); } } } void setup() { Bridge.begin(); Console.begin(); Console.println("Connected to console."); Wire.begin(); widget.begin(); widget.show(); // connect to MQTT broker and subscribe to topic if (client.connect("arduinoYunClient")) { client.subscribe("1cfee8dd0afc"); delay(50); } } void loop() { client.loop(); // check heartbeat receiveHeartbeat(); } void receiveHeartbeat() { if(millis() - checkAlive >= 120000) { // turn widget off for(uint16_t i=0; i<widget.numPixels(); i++) { widget.setPixelColor(i, widget.Color(0, 0, 0)); } widget.show(); } else { //turn widget on for(uint16_t i=0; i<widget.numPixels(); i++) { if(i%3 == 0) { widget.setPixelColor(i, widget.Color(255, 0, 0)); } else { widget.setPixelColor(i, widget.Color(0, 255, 0)); } } widget.show(); } }
Symbol
Jan's design is a Christmas wreath. To symbolise that in my own design, I chose a NeoPixel ring lighting up in green and red.
Testing
To test this new feature, I used MQTT Lens and the Console output of the Yun.
MQTT Lens allowed me to confirm both Jan's and my heartbeats were "on air", with the expected payload. The console output on the Yun then confirmed I received and processed Jan's heartbeat as expected.
Demonstration
Here's a video of my widget being activated by Jan's MQTT heartbeat.
I shortened the timeout interval for demo purposes to 30 seconds, so the widget would turn off between heartbeats which are sent every minute. The timeout is otherwise configured to 120 seconds.
Top Comments