Keresés

Ú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 ]

Új hozzászólás Aktív témák