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
Merry Boxes & LEDs
  • Challenges & Projects
  • Project14
  • Merry Boxes & LEDs
  • More
  • Cancel
Merry Boxes & LEDs
Blog Connected Christmas Trees - Finished!
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Merry Boxes & LEDs to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: ntewinkel
  • Date Created: 12 Jan 2019 10:24 PM Date Created
  • Views 2677 views
  • Likes 12 likes
  • Comments 20 comments
  • wifi
  • mqtt
  • merryboxesledsch
  • wemos d1 mini
  • xmas
  • arduino
  • wemos
Related
Recommended

Connected Christmas Trees - Finished!

ntewinkel
ntewinkel
12 Jan 2019

And now... time to unveil the finished project!

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

 

The last step was to hide the electronics from the trees in a semi-festive manner.

Using the little paper box imitations of Altoids tins that I created in my previous blog post, I was able to tuck all the pieces away nicely and create a little stand for the trees at the same time. The Christmas card box material added a bit of a festive touch.

 

This is where we left off in the previous blog post. The boxes showed great promise of being able to fit all the pieces:

image

 

Using a small hole punch I added a hole to fit the button, and firmly taped it into place.

I also added a hole to pass the USB power cable.

And near the top I added a small hole to pass the wires to the Christmas tree.

All the wires and bits fit quite nicely. I added another piece or card to make sure the wires wouldn't short out against the Wemos board.

As you may recall from a previous blog post, I did also have nail polish covering all the exposed solder joints.

image

 

The end result turned out nicer than I had imagined! Yay me!

image

 

I used iPhone chargers to power the trees. These are actual Apple chargers that provide a true 1Amp (the knock-offs tend to only handle about 600mA, I've noticed).

 

I took a moment to draw out the schematics. My earlier sketch was, well, rather sketchy...

image

image

I've added the fritzing file to my github folder too.

 

Here is the final source code (also available in my github folder)

 

/*
 * ConnectedXmas
 * 
 * Connected Xmas Trees
 * 
 * Using MQTT, motion sensed at one tree will light the other tree
 * 
 * Motion sensed also lights the tip of the local tree, to give indication to the local user.
 * Note that motion sensor will likely need external power. Or use a simple pushbutton
 * 
 * free service: https://www.hivemq.com/try-out/
  http://www.mqtt-dashboard.com/
  Use the browser based client for testing:
    http://www.hivemq.com/demos/websocket-client/


  On the browser client, remember to:
  1) connect (use defaults)
  2) Subscribe to the topic: ConnectedXmasTreeTopic


  From browser client, can send a 1 to turn on the tree, 0 to turn it off
    
  PubSubClient for Arduino - use Arduino Package Installer. -> see examples that are included in PubSubClient.
  Also see https://www.baldengineer.com/mqtt-tutorial.html
 * 
 */


#include <ESP8266WiFi.h>
#include <PubSubClient.h>


// WiFi connection
const char* ssid     = "yourWiFiName";  // replace with your own WiFi network name
const char* password = "YourWiFiPassword"; // replace with your own WiFi network password


// MQTT server
const char* mqtt_server = "broker.hivemq.com";
const char* mqtt_topic = "ConnectedXmasTreeTopic";
char mqtt_message[50];


const char myTreeID = '1';     // switch these two numbers for the second tree.
const char otherTreeID = '2';  //  ie, one WeMos gets programmed with myTreeID = 1 and otherTreeID = 2, the other WeMos gets 2 and 1.


// Use WiFiClient class to create TCP connections
WiFiClient espClient;
PubSubClient client(espClient);


// For Wemos D1 Mini, the built-in LED is D4
#define MOTION_SENSOR D2 // same as button on Witty  // D8 has *external, always-active* 10k pull-down, D3 has pull-up
#define LED_TREETOP D6   // same as Green RGB LED on Witty
#define LED_TREE    D8   // same as Red RGB LED on Witty


#define LED_ON  HIGH
#define LED_OFF LOW


#define SECOND 1000ul
#define MINUTE (60ul * SECOND)


#define TREE_ON_TIME 10*SECOND // 5*MINUTE
#define MIN_TIME_BETWEEN_MESSAGES 5*SECOND


unsigned long timeThisTreeTurnedOn;
unsigned long timeOtherTreeTurnedOn;


bool thisTreeIsOn = false;
bool otherTreeIsOn = false;


void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();


  Serial.println("\n\nStarting...\n");
  
  pinMode(LED_TREETOP, OUTPUT);
  pinMode(LED_TREE, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);


  flashBuiltInLED(2);


  digitalWrite(LED_TREETOP, LED_OFF);
  digitalWrite(LED_TREE, LED_OFF);


  pinMode(MOTION_SENSOR, INPUT);  // use a 10k external resistor to ground


  connectWiFi();
  flashBuiltInLED(5);


  Serial.println("Setting up MQTT connection");
  client.setServer(mqtt_server, 1883);
  client.setCallback(mqtt_callback);


  Serial.println("Setup is complete.\n");


  flashThisTree(2);
}


void connectWiFi() {
  delay(10);


  Serial.print("\n\nConnecting to WiFi: ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    flashBuiltInLED(1);
  }
 
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
//  Serial.print("Netmask: ");
//  Serial.println(WiFi.subnetMask());
//  Serial.print("Gateway: ");
//  Serial.println(WiFi.gatewayIP());
}


void mqtt_callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();


  // Switch on this tree if an 1 was received as first character
  if ((char)payload[0] == myTreeID) {
    flashThisTree(7);
    
    if (length == 1) {
      lightThisTree();
    }
  }


}


void mqtt_reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ConnectedXmasTreeClient-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      // this will cause the other tree to flash
      snprintf (mqtt_message, 50, "%c Hello world!", otherTreeID);
      client.publish(mqtt_topic, mqtt_message);
      // ... and resubscribe
      client.subscribe(mqtt_topic);
    }
    else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      // tree top flashes when waiting to reconnect
      for (int i=0; i<10; i++) {
        digitalWrite(LED_TREETOP, LED_ON);
        delay(250);
        digitalWrite(LED_TREETOP, LED_OFF);
        delay(250);
      }
    }
  }
}


void loop() {
  
  if (!client.connected()) {
    mqtt_reconnect();
  }
  client.loop();


  // check for motion, unless motion was already detected recently
  if (millis() - timeOtherTreeTurnedOn > MIN_TIME_BETWEEN_MESSAGES) {
    // instead of button, will have motion sensor
    if (digitalRead(MOTION_SENSOR) == HIGH) {
      Serial.println("Motion detected!");
      lightOtherTree();
    }
  }


  if (otherTreeIsOn && millis() - timeOtherTreeTurnedOn > TREE_ON_TIME) {
    // no message needed - other tree turns off at same kind of interval
    // turn off tree top indicator light
    digitalWrite(LED_TREETOP, LED_OFF);
    otherTreeIsOn = false;
  }


  if (thisTreeIsOn && millis() - timeThisTreeTurnedOn > TREE_ON_TIME) {
    digitalWrite(LED_TREE, LED_OFF);
    thisTreeIsOn = false;
  }
}


void lightOtherTree() {
  char msg[2];
  msg[0] = otherTreeID;
  msg[1] = '\0';
  digitalWrite(LED_TREETOP, LED_ON);  // turn on local tree top light. Green for testing
  Serial.println("Sending message to light the other tree");
  client.publish(mqtt_topic, msg);
  otherTreeIsOn = true;
  timeOtherTreeTurnedOn = millis();
}


void lightThisTree() {
  // flash the tree
  digitalWrite(LED_TREE, LED_ON);
  delay(200);
  digitalWrite(LED_TREE, LED_OFF);
  delay(200);


  digitalWrite(LED_TREE, LED_ON);
  thisTreeIsOn = true;
  timeThisTreeTurnedOn = millis();
}


void flashThisTree(int count) {
  for (int i=0; i<count; i++) {
    digitalWrite(LED_TREE, LED_ON);
    delay(100);
    digitalWrite(LED_TREE, LED_OFF);
    delay(100);
  }
}


void flashBuiltInLED(int count) {
    for (int i=0; i<count; i++) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(100);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(100);
  }


}

 

For the final real-life implementation you'd want to increase the TREE_ON_TIME to something more than 10 seconds - maybe a minute or 5 minutes.

 

I think I still would have liked having the motion sensors as part of the project, as that would keep a tree lit up as long as someone is near it setting off the sensor once in a while. With my button setup you have to press the button every so often.

However, I realized that I would need a separate power supply for the sensors to do that. This could probably be done with a little adapter placed at the micro-USB plug that taps into the incoming power supply so that power can be taken off the source, rather than after the diode and fuse that are on the Wemos D1 Mini.

 

I also learned that the Wemos D1 Mini has some minor details different from the average Arduino. Mainly the added external resistors and the lack of internal pull-up/pull-down. That had my head spinning for a bit.

The lesson there is that I need to check the schematics and not just assume things will be the same.

 

I'm very happy that I was able to find enough time scattered over the holidays and weekends to actually do a nice little project again. It almost didn't happen this year!

I also thought this project would have been much quicker to implement, but there were more "lessons" than I had anticipated image

Giving up would have been too easy, and I'm glad I stuck it out and learned a few new things along the way - and isn't that kind of the point of this hobby?

 

Cheers,

-Nico

 

Previous posts:

Connected Christmas Trees

Assembling the Trees

Finally! Two Trees Assembled

Two Trees by a Tree

Connecting the Tree to the Internet

Motion Sensor on Wemos

Trees! one with motion sickness...

Motion Sensor Issues, continued

The Connected Trees are Working!

Merry Boxes - A Project Within a Project

  • Sign in to reply

Top Comments

  • balearicdynamics
    balearicdynamics over 6 years ago +4
    Horayyyyyy!!! Enrico
  • shabaz
    shabaz over 6 years ago +4
    Hi Nico! Congrats on the project, and the detailed blog posts were great to see. Very cool how you transformed the basic tree into an Internet connected device!
  • three-phase
    three-phase over 6 years ago +4
    Congratulations on finishing the project - a very enjoyable set of blogs to read through. Kind regards.
  • dubbie
    dubbie over 6 years ago

    A truly impressive project and a worthy winner. One day I might be able to talk to trees as well!

     

    Dubbie

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • mcb1
    mcb1 over 6 years ago in reply to ntewinkel

    Sorry about the delayed response.

     

    Are you aiming to make it a connected tree too? or is that a different project you're working on?

    Will be very cool to spin it around the globe for sure!

    Yes I was intending to connect them.

    Not exactly sure how I would show, or react to the 'others'.

     

     

    Basically I've worked out that two LED's in series is achievable. You then need to decide how many separate channels you want.

    There is some time to spend doing the modifications to the board.

     

     

    I'm wondering if we get a design and software sorted, we could perhaps do a custom Tree ourselves.

     

     

    Mark

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • ntewinkel
    ntewinkel over 6 years ago in reply to Problemchild

    Yes! The Internet of Trees, in the World Wide Woods! image

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Problemchild
    Problemchild over 6 years ago in reply to ntewinkel

    Yeah I have one of them they are OK for Arduinos or similar,all stuff not the RPI though (At least the 3/3+) but may be enough for the Zero etc. Basically there is enough power to boot a PI but since you would probably want the PI to get a lick on and do a job it then falls over at that point. No doubt a range of jobs it could do even on a RPI but really good for a small device.

     

    For reference I use the Zendure power banks which are one of the few designs which actually charge and supply current to the load at the same time (Although some cheap £1 units can surprisingly)

    The Zendure units are expensive but more or less bomb proof..horses for courses and all that!

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • ntewinkel
    ntewinkel over 6 years ago in reply to Problemchild

    I so very recently wrote:

    >I recently saw a very cool module that can act like a power bank but also as an uninterruptible power supply... let me see if I can find that again.

     

    Here it is!

    The Guy With The Swiss Accent reviewed it:

    https://youtu.be/joAkJ9QA2bw

     

    Only about $3 CAD (1.50 for the UK-ians?)

    http://bit.ly/2RbEP1h

     

    I should really buy one already.

     

    -Nico

    • Cancel
    • Vote Up +2 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