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.

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>

Minecraft Painted Walls

Last modified April 10, 2023: more content (59f5057)