sowbug / G35Arduino

An Arduino library for GE Color Effects G-35 holiday lights.
Other
64 stars 24 forks source link

Stepping back through programs (Not an issue - but unsure how to use GitHub - sorry!!) #13

Closed MarkEMarkEMark closed 12 years ago

MarkEMarkEMark commented 12 years ago

Hi Sowbug,

I'm glad to see that you are still working on this with the Hallowe'en additions recently.

I've been putting a lot of work into ammending your code for my needs, and new programs.

I've added in code that allows the polling of 9 buttons (using adafruits interupt version in blog: http://www.adafruit.com/blog/2009/10/20/example-code-for-multi-button-checker-with-debouncing/), and it works a treat.

I'm using the first button to step up the programs (with a very long 86400 timeout value, i.e. 24 hours) However, when I try to step down the values with another button, it works down to program zero, but then resets the Arduino when tries to go backwards. I've tried everything I can think of to wrap around, but to no avail.

void switch_program(bool up) {
unsigned long now = millis();
next_switch_millis_ = now + program_duration_seconds_ * 1000;
next_do_millis_ = now;

if (up)
{
    if (++program_index_ == program_count_) {
        program_index_ = 0;
    }
} else { //down - doesn't work at boundry
    //Serial.print("** "); Serial.println(program_index_);
    if (program_index_ == 0)
    {
        //Serial.println("******");
        program_index_ = program_count_;
    } else {
        --program_index_;
    }
}

I'm going to use the other buttons to change colours and speed. I'm pretty excited to be able to do this in time for Xmas like a 42 year old kid!!

Also, I've adapted a nice rainbow function (with a lot of effort) from a different LED strip from Adafruit (thouroughly recommended - I've 10m of these - 320 lights! I got cheap from China). It works brilliantly, but the program has to finish before it will switch programs. I can't get my head around your 'fill_sequence' function which allow you to switch programs immediately. If you any ideas on how to convert this to your way, it'd be really great. (It's a really nice program that cycles through the color wheel)

//colour cycle, based on Adafruits's LED strip: https://github.com/adafruit/LPD8806
MEORainbowCycleString::MEORainbowCycleString(G35& g35)
   : LightProgram(g35), wait_(50) {}

uint32_t MEORainbowCycleString::Do() {
    for (int myColor=0; myColor < 48; myColor++) {     // all 48 colors in the wheel
        for (int i=0; i < light_count_; i++) {
            g35_.fill_color(i, 1, G35::MAX_INTENSITY, MEORainbowCycleString::Wheel(((i * 48 / light_count_) + myColor) % 48));
        }
        delay(wait_);
    }
    return bulb_frame_;
}

uint32_t MEORainbowCycleString::Wheel(uint16_t WheelPos) {
    byte r, g, b;
    switch(WheelPos / 16)
    {
        case 0:
            r = 15 - WheelPos % 16; // red down
            g = WheelPos % 16;       // green up
            b = 0;                    // blue off
            break;
        case 1:
            g = 15 - WheelPos % 16; // green down
            b = WheelPos % 16;       // blue up
            r = 0;                    // red off
            break;
        case 2:
            b = 15 - WheelPos % 16; // blue down
            r = WheelPos % 16;       // red up
            g = 0;                    // green off
            break;
        }
        return(COLOR(r,g,b));
}

Thanks, and sorry to ask questions in the issues - but I couldn't see any other way of asking you questions.

sowbug commented 12 years ago

Mark, great work! The bug in the first block is that you're setting the index variable past the range of the programs. You want to set index to count - 1, not count. The programs are numbered starting with zero, so if there are 10 they're really 0 through 9.

Also, for clarity you might want to separate the index updating from the range checking. E.g. if up then ++ else --; and after that, if index >= count then index %= count (I am pretty sure index is unsigned so that single range check works for both ends of the range).

sowbug commented 12 years ago

On the second question, fillsequence has nothing to do with this. You want to change Do to do just one slice of work and then return whatever value you're using for wait. Basically instead of running through your whole for loop each time Do gets called, do just one iteration of that loop. You will have to change your myColor and i index variables into member variables so that their values are preserved across successive Do calls. I'd also advise getting rid of wait_ and just keeping the return bulbframe.

sowbug commented 12 years ago

Oops, looks like GitHub read the underscores as Markdown. Hope you can figure it out.

MarkEMarkEMark commented 12 years ago

Hi sowbug - as usual, the answer came to me not long after posting (this always happens!). Anyway - you are right about the -1, but the main problem was with having stock and plus programs. It works if I just stick to one of these. I don't mind, as I'll recreate all my programs in a single new one. I'll post my other program, when I've converted it from the LEDstrip version that I wrote - it's like a random strobe like you can see on the Eiffel Tower at night. I'll try your suggestion for my the rainbow program. Thanks for your help!

MarkEMarkEMark commented 12 years ago

PS - the Adafruit LEDStrip code has some great examples using alpha channels in that the programs can fade smoothly into each other! It wouldn't be as smooth with the fewer colors of the G35, but I intend to give it a go anyway...