Minecraft Lights
Much more than your average Minecraft Lights!
- OTT kids room.
- Replace batteries in Minecraft lights with power from MySensors node (original reason for this mod, so we don’t have to keep replacing/charging)
- Control off/on, brightness and random flicker effect
- Establish the start of a 12v power distribution point in the attic for additional nodes in the future.
- Drop from 12v to 5v/3.3v in the actual node.
- This way there’s no potential for voltage drop over distance to affect nodes.
You can’t buy the Minecraft pattern on the walls. It’s paint! Layer upon layer of hard slog!
Code
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
#define MY_NODE_ID 59
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
#include <MySensors.h>
#define SN "Minecraft Torches"
#define SV "1.1"
#define FADE_DELAY 10 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
int16_t currentLevels[6];
MyMessage light3Msg(3, V_DIMMER);
MyMessage light5Msg(5, V_DIMMER);
MyMessage rgbFlickerState(0, V_LIGHT);
// Arduino pin attached to MOSFET Gate pin
#define LIGHT_PIN_3 3
#define LIGHT_PIN_5 5
int isFlicker;
void setup()
{
// Pull the gateway's current dim level - restore light level upon sendor node power-up
request( 0, V_DIMMER );
//fadeAllToLevel(0);
}
void presentation()
{
// Register the LED Dimmable Light with the gateway
present(LIGHT_PIN_3, S_DIMMER, "Light on Pin 3", false);
present(LIGHT_PIN_5, S_DIMMER, "Light on Pin 5", false);
present(0, S_DIMMER, "All Lights", false);
present(0, S_LIGHT, "Flicker all", false);
sendSketchInfo(SN, SV);
}
void loop()
{
// Run RGB Flicker if is set
if (isFlicker==1)
{
flicker();
}
}
void receive(const MyMessage &message)
{
int lightState = message.getString()[0] == '1';
if (message.type == V_LIGHT ) {
Serial.println(lightState);
// if receive RGB Flicker On commands, start the Flicker
if (message.sensor==0 && lightState==1){
Serial.println("message.sensor==0 && lightState==1");
flickerOn();
}
// if receive RGB Flicker Off commands, stop the Flicker
else if (message.sensor==0 && lightState==0){
Serial.println("message.sensor==0 && lightState==0");
flickerOff();
}
}else if(message.type == V_DIMMER){
// Retrieve the power or dim level from the incoming request message
int requestedLevel = atoi( message.data );
// Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 );
// Clip incoming level to valid range of 0 to 100
requestedLevel = requestedLevel > 100 ? 100 : requestedLevel;
requestedLevel = requestedLevel < 0 ? 0 : requestedLevel;
// Stop the Flicker if it's running.
// Don't call flickerOff, as this restores to the previous values first e.g. perhaps off or on. We want to go straight to the new values.
isFlicker=0;
send( rgbFlickerState.set(0), false);
Serial.print( "Changing level for light " );
Serial.print( message.sensor );
Serial.print( " to " );
Serial.print( requestedLevel );
Serial.print( ", from " );
if(message.sensor==0){
// Sensor 0 is all lights
Serial.print( " n/a" );
fadeAllToLevel(requestedLevel);
}else{
// else just an individual one
Serial.println( currentLevels[message.sensor] );
fadeToLevel(message.sensor, requestedLevel);
}
}
}
/***
* This method provides a graceful fade up/down effect
*/
void fadeToLevel( int lightPin, int toLevel )
{
int delta = ( toLevel - currentLevels[lightPin] ) < 0 ? -1 : 1;
while ( currentLevels[lightPin] != toLevel ) {
currentLevels[lightPin] += delta;
analogWrite( lightPin, (int)(currentLevels[lightPin] / 100. * 255) );
analogWrite( lightPin, (int)(currentLevels[lightPin] / 100. * 255) );
delay( FADE_DELAY );
}
if(lightPin == 3){
send(light3Msg.set(currentLevels[lightPin] > 0));
}
if(lightPin == 5){
send(light5Msg.set(currentLevels[lightPin] > 0));
}
saveState(lightPin, toLevel);
}
void fadeAllToLevel(int toLevel )
{
int delta3 = ( toLevel - currentLevels[LIGHT_PIN_3] ) < 0 ? -1 : 1;
int delta5 = ( toLevel - currentLevels[LIGHT_PIN_5] ) < 0 ? -1 : 1;
int steps = 100;
for (int x=0;x<steps;x++) {
if(currentLevels[LIGHT_PIN_3] != toLevel){
currentLevels[LIGHT_PIN_3] += delta3;
analogWrite( LIGHT_PIN_3, (int)(currentLevels[LIGHT_PIN_3] / 100. * 255) );
}
if(currentLevels[LIGHT_PIN_5] != toLevel){
currentLevels[LIGHT_PIN_5] += delta5;
analogWrite( LIGHT_PIN_5, (int)(currentLevels[LIGHT_PIN_5] / 100. * 255) );
}
delay( FADE_DELAY );
}
send(light3Msg.set(currentLevels[LIGHT_PIN_3] > 0));
send(light5Msg.set(currentLevels[LIGHT_PIN_5] > 0));
saveState(LIGHT_PIN_3, toLevel);
saveState(LIGHT_PIN_5, toLevel);
}
void flickerOn()
{
// define Flicker On
isFlicker=1;
// Write some debug info
Serial.println("Flicker on");
}
void flickerOff()
{
//turn off Flicker
isFlicker=0;
//and restore previous value to light
fadeToLevel(LIGHT_PIN_3, loadState(LIGHT_PIN_3));
fadeToLevel(LIGHT_PIN_5, loadState(LIGHT_PIN_5));
Serial.println("Flicker off");
send( rgbFlickerState.set(0), false);
}
void flicker(){
int steps = 50;
int light3toLevel = random(10, 100);
int light5toLevel = random(10, 100);
// analogWrite( LIGHT_PIN_3, (int)(light3toLevel / 100. * 255) );
// analogWrite( LIGHT_PIN_5, (int)(light5toLevel / 100. * 255) );
// delay( 100);
int delta3 = (light3toLevel - currentLevels[LIGHT_PIN_3]) < 0 ? -1 : 1;
int delta5 = (light5toLevel - currentLevels[LIGHT_PIN_5]) < 0 ? -1 : 1;
for (int x=0;x<steps;x++) {
if(currentLevels[LIGHT_PIN_3] != light3toLevel){
currentLevels[LIGHT_PIN_3] += delta3;
analogWrite( LIGHT_PIN_3, (int)(currentLevels[LIGHT_PIN_3] / 100. * 255) );
}
if(currentLevels[LIGHT_PIN_5] != light5toLevel){
currentLevels[LIGHT_PIN_5] += delta5;
analogWrite( LIGHT_PIN_5, (int)(currentLevels[LIGHT_PIN_5] / 100. * 255) );
}
delay( FADE_DELAY/2);
}
}
<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1"></span>