element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Blog [Christmas Wreath of Things] Internet of Holiday Lights : post Christmas blues
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 8 Jan 2015 11:37 AM Date Created
  • Views 788 views
  • Likes 0 likes
  • Comments 1 comment
  • mqtt
  • sketch
  • wreath_of_things
  • iot_holidaylights
  • eclipse
  • eclipse_paho
  • paho
  • internet-of-things
  • iot
  • arduino
Related
Recommended

[Christmas Wreath of Things] Internet of Holiday Lights : post Christmas blues

Jan Cumps
Jan Cumps
8 Jan 2015

XMAS is over

 

On January 6, we remove our Christmas tree and lights in Belgium. So it's also time for my Christmas Wreath of Things to switch off.

But we still have our Secret IoT Service going on - and I want to enjoy that for a little longer.

 

So I switched over to a low profile design: an LCD that glows when one of my Secret IoT Service partners is alive,

and shows the name of the last person that sent me an I'm alive message.

In the picture below, it was Robert Peter Oakes.

 

image

 

What's happening?

 

If no one but me is on-line, the display is blank, and the backlight off.

Once I receive a message from one of my friends, the Thing wakes up:

It sets a seconds counter to 120 seconds, and remembers the name of the sender.

 

The display lights up, and shows who was broadcasting:

 

image

 

 

Left upper corner shows my countdown timer. Each second the timer decreases.

Right lower corner shows the sender (in this case fvan).

 

If I receive no new message within 120 seconds, the backlight switches off, the display is blanked

and we go back to sleep.

 

Code:

 

 

// needed for MQTT and Process lib
#include <Bridge.h>








// MQTT  includes start




#include <SPI.h>
#include <YunClient.h>
#include <IPStack.h>
#include <Countdown.h>
#include <MQTTClient.h>


#include <string.h>
// MQTT includes end




// include the library code:
#include <LiquidCrystal.h>
#define PIN_LCDLIGHT 10




// start MQTT declarations
char printbuf[100];


YunClient c; // replace by a YunClient if running on a Yun
IPStack ipstack(c);
MQTT::Client<IPStack, Countdown> client = MQTT::Client<IPStack, Countdown>(ipstack);
char payLoadBuf[] = {'j', 'a', 'n', 'c', 'u', 'm', 'p', 's', 0};
const char* send_topic = "element14_IoT";
const char* subscribe_topic = "element14_IoT";
const char* _id = "1cfee8dd0afc_yun";
// end MQTT declarations




// start frederick declarations
unsigned int uFrederickIsAlive = 0;
// end frederick declarations


// initialize the library with the numbers of the interface pins
// LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);




char lastPayload[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};






// start timer functionality ============================================================
boolean bRunSeconds = false;
boolean bIsRunningSeconds = false;
boolean bRunMinutes = false;
boolean bIsRunningMinutes = false;
boolean bRunHours = false;
boolean bIsRunningHours = false;


void runSeconds() {
  bIsRunningSeconds = true;

  // // Serial.print("s"); // remove when confident


  // task: keep MQTT alive
  client.yield(30); // this takes 30 ms. May reduce the parameter // if you get duplicates, increase

  // task: handle frederick alive functionality
  // task: every minute; we take one live away from frederick
  if (uFrederickIsAlive) {
    uFrederickIsAlive--;
    sprintf(printbuf, "%3u%c", uFrederickIsAlive, 0);
    lcd.setCursor(0, 0);
    lcd.print(printbuf);
    lcd.setCursor(0, 1);
    lcd.print(lastPayload);
    pinMode(PIN_LCDLIGHT, INPUT);   // high impedance turns on light
  } else {
    pinMode(PIN_LCDLIGHT, OUTPUT);   // low impedance LOW turns off light
    sprintf(printbuf, "                %c", 0);
    lcd.setCursor(0, 0);
    lcd.print(printbuf);
    lcd.setCursor(0, 1);
    lcd.print(printbuf);
  }
  Serial.println(uFrederickIsAlive);



  bRunSeconds = false;
  bIsRunningSeconds = false;
}


void runMinutes() {
  bIsRunningMinutes = true;

  // // Serial.println("m"); // remove when confident

  // task: flag to Frederick that I'm alive
  sendAliveMessage();



  bRunMinutes = false;
  bIsRunningMinutes = false;
}


void runHours() {
  bIsRunningHours = true;

  // // Serial.println("h"); // remove when confident

  bRunHours = false;
  bIsRunningHours = false;
}


void timerInit() {
  // initialize timer1 for 1 second ticks; ISR(TIMER1_COMPA_vect) will be called as interrupt handler
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;


  OCR1A = 62500;            // compare match register 16MHz/256/1Hz
  TCCR1B |= (1 << WGM12);   // CTC mode
  TCCR1B |= (1 << CS12);    // 256 prescaler
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  interrupts();             // enable all interrupts
}


ISR(TIMER1_COMPA_vect)          // timer compare interrupt service routine
{
  static unsigned int uSeconds = 0;
  uSeconds++; // every call is a second
  bRunSeconds = true; // so yes, flag that the seconds handler should be called
  bRunMinutes = ! (uSeconds % 60); // each 60th second, flag that the minutes handler should be called
  if (uSeconds > 3599) { // every hour
    bRunHours = true; // flag that the hours handler should be called
    uSeconds = 0; // and start over
  }
}


void timerTasks() {
  if (bRunSeconds && ! bIsRunningSeconds) { // timer interrupt flagged that seconds handler should be called
    runSeconds(); // but we only run it if it's not active
  }
  if (bRunMinutes && ! bIsRunningMinutes) { // timer interrupt flagged that minutes handler should be called
    runMinutes(); // but we only run it if it's not active
  }
  if (bRunHours && ! bIsRunningHours) { // timer interrupt flagged that hours handler should be called
    runHours(); // but we only run it if it's not active
  }
}


// end timer functionality =====================================




// start MQTT functionality ====================================




void mqttInit() {
//  Ethernet.begin(mac); // replace by Bridge.begin() if running on a Yun
  Bridge.begin();


  // // Serial.println("MQTT Internet of Holiday Lights example");
  connect();
}


void messageArrived(MQTT::MessageData& md) // this handler is called when a subscribed MQTT message arrives
{
  MQTT::Message &message = md.message;

  // debug code
  sprintf(printbuf, "Message arrived: qos %d, retained %d, dup %d, packetid %d\n",
  message.qos, message.retained, message.dup, message.id);
  Serial.print(printbuf);
  sprintf(printbuf, "Payload %s\n", (char*)message.payload);


  Serial.print(printbuf);

  /*
  // sprintf(printbuf, "Topic len %d\n", md.topicName.lenstring);
  int i;
  for (i = 0; i < (md.topicName.lenstring.len); i++) {
    printbuf[i] = md.topicName.lenstring.data[i];
  }
  printbuf[(md.topicName.lenstring.len)]=  '\n';
  printbuf[md.topicName.lenstring.len + 1]=  0;
  */
  int iPlCheck = strncmp(payLoadBuf, (char*)message.payload,8);

  if (iPlCheck) {
    Serial.print(printbuf);
    sprintf(lastPayload, "%16s", (char*)message.payload);
  
  
  
    uFrederickIsAlive = 120; // we give frederick two lives (minutes) to send an 'I am alive' live message.
  } else {
    Serial.println("it's my own message");
  }
}


void connect()  // connect to the MQTT broker
{
  char hostname[] = "iot.eclipse.org";
  int port = 1883;
  sprintf(printbuf, "Connecting to %s:%d\n", hostname, port);
  // // Serial.print(printbuf);
  int rc = ipstack.connect(hostname, port);
  if (rc != 1)
  {
    sprintf(printbuf, "rc from TCP connect is %d\n", rc);
    // // Serial.print(printbuf);
  }

  // // Serial.println("MQTT connecting");
  MQTTPacket_connectData data = MQTTPacket_connectData_initializer;     
  data.MQTTVersion = 3;
  data.clientID.cstring = (char*)_id;
  rc = client.connect(data);
  if (rc != 0)
  {
    sprintf(printbuf, "rc from MQTT connect is %d\n", rc);
    // // Serial.print(printbuf);
  }
  // // Serial.println("MQTT connected");

  rc = client.subscribe(subscribe_topic, MQTT::QOS1, messageArrived); 
  if (rc != 0)
  {
    sprintf(printbuf, "rc from MQTT subscribe is %d\n", rc);
    // // Serial.print(printbuf);
  }
  // // Serial.println("MQTT subscribed");
}


void sendAliveMessage() {
  if (!client.isConnected())
    connect();

  MQTT::Message message;



  char buf[100];
  int rc;
  // Send QoS 1 message
  // // Serial.println(payLoadBuf);
  message.qos = MQTT::QOS1;
  message.retained = false;
  message.dup = false;
  message.payload = (void*)payLoadBuf;
  message.payloadlen = strlen(payLoadBuf)+1;
  rc = client.publish(send_topic, message);
}


// end MQTT functionality ==============================


// start LCD functionality ===========================








void setupLCD() {

  pinMode(PIN_LCDLIGHT, OUTPUT);  //Set control pins to be outputs
  digitalWrite(PIN_LCDLIGHT, LOW);

  lcd.begin(16, 2);
//     lcd.setCursor(0, 0);
}


// end LCD functionality ===========================




void setup()
{


  Serial.begin(9600);
  delay(10000); // give me time to start the yun monitor


  // MQTT related tasks
  mqttInit();

  // initialise LCD
  setupLCD();


  // timer related tasks
  timerInit();
}


void loop()
{

  timerTasks();

  // non timer related functionality comes here





}

  • Sign in to reply
  • mcb1
    mcb1 over 10 years ago

    Jan

    That's not a bad way to display "who is there".

    My Yun is still in transit somewhere so I might have to look at an alternative in the meantime.

     

    Mark

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube