-
GAMEPOD.hu
Okos Otthon összefoglaló
Új hozzászólás Aktív témák
-
krisztián28
csendes tag
válasz Yoshida #4285 üzenetére
Szia!
Ha RGBW szalagot szeretnél vezérelni nézd meg ezt a kódot!
Ezt a programot még nem próbáltam, de szerintem jó lehet!/**
* 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
* prgspeed parameter (send as V_VAR1 message)
* HomeAssistant compatible (send status to ack)
* 1.2
* OTA support
* 1.3
* Power-on self test
* 1.4
* Bug fix
* 1.5
* Other default values
* 1.6
* Repeater feature
* 1.7
* Multitasking. Alarm and RELAX modes.
* 1.8
* Reengineered programs/modes logic.
* RGBW variant. Requires 4 PWM pins, so we need to move use a different pin for one of radio connections.
*/
#define MY_OTA_FIRMWARE_FEATURE
// #define MY_REPEATER_FEATURE
#define MY_NODE_ID AUTO
#define MY_RADIO_NRF24
//#define MY_DEBUG
// Normally the radio uses pin 9 for CE
#define MY_RF24_CE_PIN 8
#include <MySensors.h>
#define CHILD_ID_LIGHT 1
#define SN "LED Strip"
#define SV "1.8"
MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
MyMessage rgbwMsg(CHILD_ID_LIGHT, V_RGBW);
MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
MyMessage prgspeedMsg(CHILD_ID_LIGHT, V_VAR1);
MyMessage programMsg(CHILD_ID_LIGHT, V_VAR2);
#define RR 0
#define GG 1
#define BB 2
#define WW 3
byte current[] = {255, 255, 255, 255};
byte target[] = {255, 255, 255, 255};
byte save[] = {0, 0, 0, 0};
byte temp[] = {0, 0, 0, 0};
float delta[] = {0.0, 0.0, 0.0, 0.0};
char rgbwstring[] = "000000ff";
int on_off_status = 0;
int dimmerlevel = 100;
int prgspeed = 20;
unsigned long last_update = 0;
unsigned long tick_length = 5;
int fade_step = 0;
int program_timer;
int program_cycle;
int program_step;
// Make sure these are PWM pins
#define REDPIN 6
#define GREENPIN 5
#define BLUEPIN 3
#define WHITEPIN 9
#define LIGHT_NORMAL 0
#define LIGHT_FADING 1
#define PROGRAM_NOP 0
int light_mode = LIGHT_NORMAL;
int program_mode = PROGRAM_NOP;
#define SET 0
#define SET_AND_WAIT 1
#define SET_RANDOM 2
#define SET_RANDOM_AND_WAIT 3
#define FADE 4
#define FADE_RANDOM 5
#define WAIT 6
typedef struct rgb_cmd {
byte cmd;
int p;
byte rgbw[4];
} rgb_cmd;
rgb_cmd program_ALARM[] = {
{SET_AND_WAIT, 25, {255, 255, 255, 0}},
{SET_AND_WAIT, 25, {0, 0, 0, 0}},
{SET_AND_WAIT, 25, {0, 0, 0, 255}},
{SET_AND_WAIT, 25, {0, 0, 0, 0}}
};
rgb_cmd program_RELAX[] = {
{FADE, 1000, {255, 32, 0, 0}},
{FADE, 1000, {255, 32, 16, 0}},
{FADE, 1000, {255, 16, 32, 0}},
{FADE, 1000, {255, 128, 0, 0}},
{FADE, 1000, {255, 32, 0, 0}},
{FADE, 1000, {255, 32, 32, 0}},
{FADE, 1000, {255, 0, 32, 0}}
};
rgb_cmd program_PARTY[] = {
{SET_AND_WAIT, 10, {255, 0, 0, 0}},
{SET_AND_WAIT, 10, {0, 0, 0, 255}},
{SET_AND_WAIT, 10, {255, 0, 0, 0}},
{SET_AND_WAIT, 10, {0, 0, 0, 255}},
{SET_AND_WAIT, 10, {255, 0, 0,0}},
{SET_AND_WAIT, 10, {0, 0, 0, 255}},
{SET_AND_WAIT, 10, {255, 0, 0,0}},
{SET_AND_WAIT, 10, {0, 0, 0, 255}},
{SET_AND_WAIT, 10, {255, 0, 0, 0}},
{SET_AND_WAIT, 10, {0, 0, 0, 255}},
{FADE_RANDOM, 50, {255, 255, 255, 0}},
{FADE_RANDOM, 50, {255, 255, 255, 0}},
{FADE_RANDOM, 50, {255, 255, 255, 0}},
{FADE_RANDOM, 50, {255, 255, 255, 0}},
{SET_AND_WAIT, 50, {0, 0, 255, 0}},
{SET_AND_WAIT, 50, {0, 255, 255 ,0}},
{SET_AND_WAIT, 50, {255, 255, 0, 0}},
{SET_AND_WAIT, 50, {0, 255, 0, 0}},
{FADE_RANDOM, 50, {255, 255, 255, 0}},
{FADE_RANDOM, 50, {255, 255, 255, 0}},
{FADE_RANDOM, 50, {255, 255, 255, 0}},
{FADE_RANDOM, 50, {255, 255, 255, 0}},
{FADE_RANDOM, 50, {255, 255, 255, 0}}
};
rgb_cmd* programs[] = {
&program_ALARM[0], &program_RELAX[0], &program_PARTY[0]
};
const int program_steps[] = {
sizeof(program_ALARM)/sizeof(rgb_cmd),
7,
22
};
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);
pinMode(WHITEPIN, OUTPUT);
}
void presentation()
{
// Send the Sketch Version Information to the Gateway
sendSketchInfo(SN, SV);
present(CHILD_ID_LIGHT, S_RGBW_LIGHT);
}
void selftest() {
on_off_status = 1;
current[RR] = 255;
current[GG] = 0;
current[BB] = 0;
current[WW] = 0;
set_hw_status();
wait(200);
current[RR] = 0;
current[GG] = 255;
set_hw_status();
wait(200);
current[GG] = 0;
current[BB] = 255;
set_hw_status();
wait(200);
current[BB] = 0;
current[WW] = 255;
set_hw_status();
wait(200);
current[RR] = 0;
current[GG] = 0;
current[BB] = 0;
set_hw_status();
wait(200);
on_off_status = 0;
}
void loop()
{
static bool first_message_sent = false;
if ( first_message_sent == false ) {
selftest();
set_hw_status();
send(rgbwMsg.set(rgbwstring));
send(lightMsg.set(on_off_status));
send(dimmerMsg.set(dimmerlevel));
send(prgspeedMsg.set(prgspeed));
send(programMsg.set(program_mode));
first_message_sent = true;
}
unsigned long now = millis();
// Maybe we wrapped around? Then reset last_update to 0.
if (now < last_update) {
last_update = 0;
}
if (now - last_update > tick_length) {
last_update = now;
// If we're fading, finish that before we do anything else
if (light_mode == LIGHT_FADING) {
calc_fade();
} else {
if (program_mode > PROGRAM_NOP) {
handle_program();
}
}
}
set_hw_status();
}
void receive(const MyMessage &message)
{
int val;
if (message.type == V_RGBW) {
for (int i=0; i<=3; i++) {
temp[i] = hextoint(message.data[i*2]) * 16 + hextoint(message.data[i*2+1]);
}
// Save old value
strcpy(rgbwstring, message.data);
init_fade(prgspeed, temp);
send(rgbwMsg.set(rgbwstring));
} else if (message.type == V_LIGHT || message.type == V_STATUS) {
val = atoi(message.data);
if (val == 0 or val == 1) {
on_off_status = val;
send(lightMsg.set(on_off_status));
}
} else if (message.type == V_PERCENTAGE) {
val = atoi(message.data);
if (val >= 0 and val <=100) {
dimmerlevel = val;
send(dimmerMsg.set(dimmerlevel));
}
} else if (message.type == V_VAR1 ) {
val = atoi(message.data);
if (val >= 0 and val <= 2000) {
prgspeed = val;
send(prgspeedMsg.set(val));
}
} else if (message.type == V_VAR2 ) {
val = atoi(message.data);
if (val == PROGRAM_NOP) {
stop_program();
send(programMsg.set(val));
} else {
init_program(val);
send(programMsg.set(val));
}
} else {
return;
}
}
void execute_step(rgb_cmd cmd) {
if (cmd.cmd == SET) {
set_rgb(cmd.rgbw);
} else if (cmd.cmd == SET_AND_WAIT) {
set_rgb(cmd.rgbw);
program_timer = cmd.p;
} else if (cmd.cmd == SET_RANDOM) {
set_rgb_random(cmd.rgbw);
} else if (cmd.cmd == SET_RANDOM_AND_WAIT) {
set_rgb_random(cmd.rgbw);
program_timer = cmd.p;
} else if (cmd.cmd == FADE) {
init_fade(cmd.p, cmd.rgbw);
} else if (cmd.cmd == FADE_RANDOM) {
init_fade_random(cmd.p, cmd.rgbw);
} else if (cmd.cmd == WAIT) {
program_timer = cmd.p;
}
}
void init_program(int program) {
program_mode = program;
program_step = 0;
program_timer = 0;
save_state();
execute_step(programs[program_mode-1][0]);
}
void handle_program() {
if (program_timer > 0) {
program_timer--;
}
if (program_timer == 0) {
program_step++;
if (program_step == program_steps[program_mode-1]) {
program_step = 0;
}
execute_step(programs[program_mode-1][program_step]);
}
}
void stop_program() {
restore_state();
light_mode = LIGHT_NORMAL;
program_mode = PROGRAM_NOP;
}
void save_state() {
memcpy(save, current, 4 );
}
void restore_state() {
memcpy(current, save, 4 );
}
void set_rgb (byte rgbw[]) {
light_mode = LIGHT_NORMAL;
memcpy(current, rgbw, 4);
}
void set_rgb_random (byte rgbw[]) {
light_mode = LIGHT_NORMAL;
for (int i=0; i <= 3; i++){
current[i] = random(rgbw[i]);
}
}
void init_fade(int t, byte rgbw[]) {
light_mode = LIGHT_FADING;
fade_step = t;
memcpy(target, rgbw, 4);
for (int i=0; i<=3; i++) {
delta[i] = (target[i] - current[i]) / float(fade_step);
}
}
void init_fade_random(int t, byte rgbw[]) {
light_mode = LIGHT_FADING;
fade_step = t;
for (int i=0; i<=3; i++) {
target[i] = random(rgbw[i]);
delta[i] = (target[i] - current[i]) / float(fade_step);
}
}
void calc_fade() {
if (fade_step > 0) {
fade_step--;
for (int i=0; i<=3; i++) {
current[i] = target[i] - delta[i] * fade_step;
}
} else {
light_mode = LIGHT_NORMAL;
}
}
void set_hw_status() {
analogWrite(REDPIN, on_off_status * (int)(current[RR] * dimmerlevel/100.0));
analogWrite(GREENPIN, on_off_status * (int)(current[GG] * dimmerlevel/100.0));
analogWrite(BLUEPIN, on_off_status * (int)(current[BB] * dimmerlevel/100.0));
analogWrite(WHITEPIN, on_off_status * (int)(current[WW] * dimmerlevel/100.0));
}
byte hextoint (byte c) {
if ((c >= '0') && (c <= '9')) return c - '0';
if ((c >= 'A') && (c <= 'F')) return c - 'A' + 10;
if ((c >= 'a') && (c <= 'f')) return c - 'a' + 10;
return 0;
}[ Szerkesztve ]