element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • 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
Personal Blogs
  • Community Hub
  • More
Personal Blogs
Legacy Personal Blogs Smart Home: Let the Party Begin
  • Blog
  • Documents
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: djfraz
  • Date Created: 22 May 2018 4:42 PM Date Created
  • Views 953 views
  • Likes 5 likes
  • Comments 4 comments
Related
Recommended

Smart Home: Let the Party Begin

djfraz
djfraz
22 May 2018

I decided today to try and work on the programming for the Party Ball. I had already written a c++ program to decode the MQTT messages and am using the LED Controller from MK Smart House as a basis for the code.

image

I wanted to keep the MQTT commands relatively simple, and easy to decode in software, this is the list I decided on. I am also going to try and keep this standard throughout my projects using my openhab server to try and keep things simpler.

 

MQTT CommandDescription
AAuto Mode
M&XChange Motor Speed to X
&R:G:BChange Neopixels to RGB Value
OFFTurn off

UPDATE: After Testing it turns out that the String Value is too small to handle the colour commands when all three values are three digits ie: C&100:100:100, and would remove the last digit so the "C" has been removed from the Command

Openhab Configuration

Items

 

//Party Ball Controls Switch
Party_Ball   "Party Ball"                 ["Switchable"]  
Color  Party_BColor "Party Ball Colour"              
Dimmer Party_BSpeed "Party Ball Speed"  
Switch Party_BAuto  "Party Ball Auto"    
//Party Ball Commnad String       
String Party_BCom   "Party Ball Command"  {mqtt=">[broker:DF/Party/Ball:command:*:default"}

 

For the items associated with the party ball I created several different items.

  • Party_Ball : the power button
  • Party_BAuto : Auto mode for the Party Ball
  • Party_BColor : For setting all the neopixel Colours
  • Party_BSpeed : the motor Speed of the kaleidoscope
  • Party_BComm :  the command string sent to the device

 

I used a seperate string for sending the commands as to not have to mess around with mappings for the MQTT binding in openhab, as it would have made making modifications to commands harder. It also would not have allowed me to send the colour value as RGB as openhab stores the colour as an HSB value. So all of the commands sent to the device are constructed using rules

 

Sitemap

Switch  item=Party_Ball     visibility=[Party_Time==ON] labelcolor=[ON="green"]//Party Ball Settings
Text    label="Party Ball Setings"  icon="settings"     visibility=[Party_Ball==ON] {
     Switch          item=Party_BAuto    label="Auto"
     Colorpicker     item=Party_BColor   label="Colour"  visibility=[Party_BAuto==OFF]
     Switch          item=Party_BSpeed   label="Speed"   mappings=[0="Off", 20="Slow", 60="Half", 100="Full"]    visibility=[Party_BAuto==OFF]
        }

I wanted to make the Sitemap more dynamic, so the controls are hidden when Party Mode is turned off, and the settings controls are hidden when the Party ball is turned off.

 

imageimageimage

 

Rules

 

//=============Party Ball===================
rule"Party Ball ON"
when
Item Party_Ball changed to ON
then
Party_BAuto.sendCommand("ON")
end

rule"Party Ball OFF"
when
Item Party_Ball changed to OFF
then
Party_BCom.sendCommand("OFF")
Party_BAuto.sendCommand(OFF)
end

rule"Party Ball Colour Change"
when
Item Party_BColor received command
then
//Turn Off Auto When Selecting Colour
Party_BAuto.sendCommand("OFF")

var HSBType hsbvalue
var int redval
var int greenval
var int blueval

    hsbvalue = Party_BColor.state as HSBType
    redval = hsbvalue.red.intValue
    greenval = hsbvalue.green.intValue
    blueval = hsbvalue.blue.intValue

Party_BCom.sendCommand("C&" + redval + ":" + greenval + ":" + blueval)
end

rule"Party Ball Auto ON"
when
Item Party_BAuto changed to ON
then
Party_BCom.sendCommand("A")
end

rule"Ball Speed Changed"
when
Item Party_BSpeed received update
then
if (Party_BAuto.state == OFF)
    {
var bspeed = Party_BSpeed.state
Party_BCom.sendCommand("M&" + bspeed)
    }
end

The Rules take the values of the other items and feed them into the Command String.

 

The Colour and Speed commands will only send their values when the Auto mode is turned off.

 

Arduino

The arduino code needs to take the MQTT commands, decode them to find the mode to operate in and extract the values (if any) from the message. it does this by using the indexOf() and substring() functions to look for the "&" between the mode and the value, then looking for ":" between the rgb values

 

String InCommand = payload;Serial.println(InCommand);
String mode = InCommand.substring(0, InCommand.indexOf("&"));

String msg = InCommand.substring(InCommand.indexOf("&") + 1, sizeof(InCommand));


String MSpeed;
String Rval;
String Gval;
String Bval;
size_t  found = msg.indexOf(":");

if(found == -1){
if(mode.equals("M")){
M_Speed(msg.toInt());
  }
else if(msg.equals("A")){
M_Auto();
  }
else if(msg.equals("OFF")){
M_Colour(0,0,0);
M_Speed(0);
  }
  }
if(found!= -1){
  MSpeed = 50;
  Rval = msg.substring(0, found);

String intval = msg.substring(found +1, sizeof(msg));
  Gval = intval.substring(0, intval.indexOf(":"));
  Bval = intval.substring(intval.indexOf(":") + 1, sizeof(msg));

Serial.println("colour mode: R=" + Rval + " G=" + Gval + " B=" + Bval);
M_Colour(Rval.toInt(), Gval.toInt(), Bval.toInt());
  }

 

The code is still a bit messy, and still has some references to the initial c++ code i used to test the functionality.

The code will fist look for the ampersand "&" in the payload of the MQTT message (InCommand). then looks for the semicolon ":", if it doesn't find the semicolon there are three possibilities of what the command is;

  1. Auto
  2. Motor Speed change
  3. OFF

and so compares the mode string to these. For turning of the ball, the colour is set to black (0,0,0) and motor speed to zero, as I wasn't sure of how to turn of neopixels using the Adafruit Library.

 

The colour values are extracted by repeated looking for a semicolon and taking the value between them, then sending the values to the colour function.

 

There are three functions for controlling the Party Ball

 

void M_Auto()
{M_Speed(50);
  pixels.setPixelColor(0, pixels.Color(255,0,0));
  pixels.setPixelColor(1, pixels.Color(0,255,0));
  pixels.setPixelColor(2, pixels.Color(0,0,255));
  pixels.show();
}

void M_Speed(int speedVal){
analogWrite(14, speedVal*10.23);
}

void M_Colour(int red, int green, int blue){
for(int i=0;i<numpixels;i++){
  pixels.setPixelColor(i, pixels.Color(red * 2.55 ,green * 2.55 ,blue * 2.55)); 
  pixels.show();  
  }
}

M_Auto sets the three leds to show one red, one green and one blue, along with setting the speed to 50%. This is to match with how the device currently operates, with one led for each colour.

 

M_Speed sets the speed using the anlogWrite function to one of the pins, it is multiplied by 10.23 as the value passed to the function is a percentage value of motor speed.

 

M_Colour is the Adafruit Simple example sketch without the delay. The values passed to the Pixels.Color() are all multiplied by 2.55 as the RGB values received from Openhab are in the range of 0-100, i can only assume it the percentage value for the RGB.

 

Test Circuit

Writing the code is all fun and games, but it is much better to see the results of the code in the real world. So I made up a quick test circuit using a Neopixel Strip and an led to simulate the motor (I couldn't be bothered wiring up a motor so troubleshooting the code).

They are connected to a NodeMCU ESP-12 development Board.

 

imageimage

Here showing both the Auto mode on the left and (what should be) Red on the right.

 

I say what should be red as although in the image, it shows up more red the leds look more pink in person, the actual value sent to the device is 255,0,22. I Am not sure the reason, i may not even matter once installed in the body

What Next?

The next thing i want to do with the device is;

  1. Tidy up the code and add error catching
  2. Add presets into Openhab Sitemap for common colours, such as red, green and blue. Most likely with expandability for more presets
  3. Put in into the body, mount on the wall and get the beers on ice.

 

I may eventually want to add more functionality to the code once installed within the body, maybe moving the position of the coloured leds for auto mode may create different effects, maybe even fade between them. but this will need to wait until I have ordered some parts for installing within the body. Mainly acrylic for the mounting internal mounting bracket and some stand alone Neopixels which are easily solderable and can be hot glued onto the mounting plate. And designing some simple circuitry for driving the motor, i may make my own or order a cheap motor controller off of eBay, as i am not wanting to just use a Transistor to drive the motor as I am not sure how it would handle being driven for long periods of time with the motor in the unit I will give this some more testing when the time comes to install.

 

  • Sign in to reply

Top Comments

  • genebren
    genebren over 7 years ago +2
    Nice update on your lighting system. This looks like a fun little project. Keep up the good work! Gene
  • mcb1
    mcb1 over 7 years ago +2
    Looks great. the actual value sent to the device is 255,0,22. I Am not sure the reason I'm not the software expert here, but I suspect the error might be here. String intval = msg.substring(found +1, sizeof…
  • djfraz
    djfraz over 7 years ago in reply to mcb1 +1
    thanks for the suggestions, I had not noticed the wrong string there, i will change it and see if it helps. But having done some testing by sending MQTT commands through a MQTT client on my computer the…
  • mcb1
    mcb1 over 7 years ago in reply to djfraz

    it may also just be as I was looking right into the LEDs at the time

    I was looking at the comment " .... the actual value sent to the device is 255,0,22. I Am not sure the reason ...." which I assumed was via the serial.

     

    Keep us informed, it's all great learning.

    Mark

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • djfraz
    djfraz over 7 years ago in reply to mcb1

    thanks for the suggestions, I had not noticed the wrong string there, i will change it and see if it helps. But having done some testing by sending MQTT commands through a MQTT client on my computer the base colour values work fine, it may also just be as I was looking right into the LEDs at the time, as the image does show a color closer to what it should be.

     

    I will also try using the map function, as i know that i didn't want to do the multiplication at the server side as it was creating a float with several decimal points, and as i discovered the input command was too long for some commands so it would have never worked that way. I mostly did the multiplication method as an afterthought, i will also probably do it for the motor speed as i have been working on that just now. As it currently accepts a percentage speed and in the analogwrite i just multiply by 10.23 to get to the 0-1023 value.

     

    Ill let you know if these help, thanks again

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • mcb1
    mcb1 over 7 years ago

    Looks great.

     

    the actual value sent to the device is 255,0,22. I Am not sure the reason

    I'm not the software expert here, but I suspect the error might be here.

     

    String intval = msg.substring(found +1, sizeof(msg));  
      Gval = intval.substring(0, intval.indexOf(":"));  
      Bval = intval.substring(intval.indexOf(":") + 1, sizeof(msg));

    You've created a new string (intval) which has a new length, but you're still using the length of the old string (msg) to determine the end point.

     

    I suspect it should read

    Bval = intval.substring(intval.indexOf(":") + 1, sizeof(intval));

     

     

     

    The values passed to the Pixels.Color() are all multiplied by 2.55 as the RGB values received from Openhab are in the range of 0-100

    You may want to look at the command 'map'. https://www.arduino.cc/reference/en/language/functions/math/map/

    it allows a smoother adjustment of 0-100 to 0-255 (or any other range you wish)

     

    Mark

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • genebren
    genebren over 7 years ago

    Nice update on your lighting system.  This looks like a fun little project.

    Keep up the good work!

    Gene

    • 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