I built a RGB LED strip controllable via mysensor, based on a 12V RGB LED strip and three IRF540 MOSFETs. The arduino is a 5V pro mini clone that I feed with 12V on the RAW pin.
I followed the guide on https://learn.adafruit.com/rgb-led-strips/usage for wiring the MOSFETS and the LED strip. I used the Newbie PCB by @sundberg84 for holding the arduino and the radio, but put the MOSFETs on a separate prototyping board (maybe next time I'll try to solder them to the prototyping area of the Newbie PCB).
I implemented a fading feature in the sketch, so it can fade slowly between colors or on/off. The speed is controlled by sending a V_VAR1 message with the speed (typical value could be around 200-300 for a nice effect). Speed = 0 means fading is off.
Here is the code:
/**
* 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.
*
* LED STRIP sketch for Mysensors
*******************************
*
* REVISION HISTORY
* 1.0
* Based on the example sketch in mysensors
* 1.1
* fadespeed parameter (send as V_VAR1 message)
* HomeAssistant compatible (send status to ack)
*/
#define MY_OTA_FIRMWARE_FEATURE
#define MY_NODE_ID AUTO
#define MY_RADIO_NRF24
#include <MySensors.h>
#define CHILD_ID_LIGHT 1
#define SN "LED Strip"
#define SV "1.1"
MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
MyMessage rgbMsg(CHILD_ID_LIGHT, V_RGB);
MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
byte red = 255;
byte green = 255;
byte blue = 255;
byte r0 = 255;
byte g0 = 255;
byte b0 = 255;
char rgbstring[] = "ffffff";
int on_off_status = 0;
int dimmerlevel = 100;
int fadespeed = 0;
#define REDPIN 6
#define GREENPIN 5
#define BLUEPIN 3
void setup()
{
// Fix the PWM timer. Without this the LEDs will flicker.
TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00);
// Output pins
pinMode(REDPIN, OUTPUT);
pinMode(GREENPIN, OUTPUT);
pinMode(BLUEPIN, OUTPUT);
}
void presentation()
{
// Send the Sketch Version Information to the Gateway
sendSketchInfo(SN, SV);
present(CHILD_ID_LIGHT, S_RGB_LIGHT);
}
void loop()
{
static bool first_message_sent = false;
if ( first_message_sent == false ) {
Serial.println( "Sending initial state..." );
set_hw_status();
send_status();
first_message_sent = true;
}
}
void receive(const MyMessage &message)
{
int val;
if (message.type == V_RGB) {
Serial.println( "V_RGB command: " );
Serial.println(message.data);
long number = (long) strtol( message.data, NULL, 16);
// Save old value
strcpy(rgbstring, message.data);
// Split it up into r, g, b values
red = number >> 16;
green = number >> 8 & 0xFF;
blue = number & 0xFF;
send_status();
set_hw_status();
} else if (message.type == V_LIGHT || message.type == V_STATUS) {
Serial.println( "V_LIGHT command: " );
Serial.println(message.data);
val = atoi(message.data);
if (val == 0 or val == 1) {
on_off_status = val;
send_status();
set_hw_status();
}
} else if (message.type == V_DIMMER || message.type == V_PERCENTAGE) {
Serial.print( "V_DIMMER command: " );
Serial.println(message.data);
val = atoi(message.data);
if (val >= 0 and val <=100) {
dimmerlevel = val;
send_status();
set_hw_status();
}
} else if (message.type == V_VAR1 ) {
Serial.print( "V_VAR1 command: " );
Serial.println(message.data);
val = atoi(message.data);
if (val >= 0 and val <= 2000) {
fadespeed = val;
}
} else {
Serial.println( "Invalid command received..." );
return;
}
}
void set_rgb(int r, int g, int b) {
analogWrite(REDPIN, r);
analogWrite(GREENPIN, g);
analogWrite(BLUEPIN, b);
}
void set_hw_status() {
int r = on_off_status * (int)(red * dimmerlevel/100.0);
int g = on_off_status * (int)(green * dimmerlevel/100.0);
int b = on_off_status * (int)(blue * dimmerlevel/100.0);
if (fadespeed >0) {
float dr = (r - r0) / float(fadespeed);
float db = (b - b0) / float(fadespeed);
float dg = (g - g0) / float(fadespeed);
for (int x = 0; x < fadespeed; x++) {
set_rgb(r0 + dr*x, g0 + dg*x, b0 + db*x);
delay(100);
}
}
set_rgb(r, g, b);
r0 = r;
b0 = b;
g0 = g;
}
void send_status() {
send(rgbMsg.set(rgbstring));
send(lightMsg.set(on_off_status));
send(dimmerMsg.set(dimmerlevel));
}
I have a MQTT gateway and I can turn the strip on, set the color to pink and fade speed to 500 by the following commands:
mosquitto_pub -t mysensors-in/240/1/1/0/40 -m ff6060
mosquitto_pub -t mysensors-in/240/1/1/0/24 -m 500
mosquitto_pub -t mysensors-in/240/1/1/0/2 -m 1
A couple of pics: