Julio G / Mbed 2 deprecated LedStrip

Dependencies:   mbed

Fork of LedStrip_test by Balazs Racz

main.cpp

Committer:
bracz
Date:
2013-09-21
Revision:
1:1a0d5a780e57
Parent:
0:109a7a5e3e6e
Child:
2:590e99f4a313

File content as of revision 1:1a0d5a780e57:

#include <queue>

#include "mbed.h"

DigitalOut myled(LED1);

Serial pc(USBTX, USBRX);

SPI spi(p5, p6, p20); // mosi, miso, sclk
DigitalOut latch(p16);
DigitalOut strobe(p17);

#define LENGTH 160

uint8_t strip[160];

#define BLACK 0x80
#define BLUE (BLACK | 0x10)
#define RED (BLACK | 0x04)
#define GREEN (BLACK | 0x01)
#define YELLOW  (RED | GREEN)
#define CYAN (GREEN | BLUE)
#define MAGENTA (RED | BLUE)
#define WHITE (RED | GREEN | BLUE)

uint8_t fade_result[] =
    {0, 2, 3, 1};

uint8_t getbit(uint8_t from, uint8_t to) {
    return fade_result[((from&1) << 1) | (to & 1)];
}

uint8_t getcolor(uint8_t from, uint8_t to) {
    uint8_t result = 0x80;
    result |= getbit(from >> 0, to >> 0) << 0;
    result |= getbit(from >> 2, to >> 2) << 2;
    result |= getbit(from >> 4, to >> 4) << 4;
    return result;
}


void write_strip(uint8_t* data, int len) {
    latch = 0;
    for (int i = len - 1; i >= 0; i--) {
        spi.write(data[i]);
    }
    latch = 1;
    wait_us(2);
    latch = 0;
}

class Schedulable {
public:
    int time_;
    virtual void Run() = 0;
    
    bool operator<(const Schedulable& o) const {
        return time_ < o.time_;
    }
};


struct comp {
    bool operator()(const Schedulable* a, const Schedulable* b) {
        return *b < *a;
    }
};

priority_queue<Schedulable*, vector<Schedulable*>, comp> task_list;

void Schedule(Schedulable* action) {
    task_list.push(action);
}

int global_tick = 0;
bool strip_changed;

void tick_cb() {
    ++global_tick;
    strobe = !strobe;
}

class RepeatedFadeInOut : public Schedulable {
public:
    RepeatedFadeInOut(int start_time, int led, uint8_t a, uint8_t b, bool fast)
        : led_(led), a_(a), b_(b), fast_(fast) {
        time_ = start_time;
        Schedule(this);
    }  

    virtual void Run() {
        strip[led_] = getcolor(a_, b_);        
        if (fast_) {
            strip[led_] |= 0x40;
            time_ += 128;
        } else {
            time_ += 256;
        }
        strip_changed = true;
        swap(a_,b_);
        Schedule(this);
    }

private:
    int led_;
    uint8_t a_,b_;
    bool fast_;
};

class WalkingFadeInOut : public Schedulable {
public:
    WalkingFadeInOut(int start_time, int led, int stride, uint8_t a, uint8_t b, bool fast)
        : led_(led - stride), stride_(stride), a_(a), b_(b), fast_(fast), step_(true) {
        time_ = start_time;
        Schedule(this);
    }  

    virtual void Run() {
        if (step_) {
            step_ = false;
            if (led_ >= 0) strip[led_] = a_;
            led_ += stride_;
            led_ %= LENGTH;
        } else {
            step_ = true;
        }
        strip[led_] = getcolor(a_, b_);        
        if (fast_) {
            strip[led_] |= 0x40;
            time_ += 128;
        } else {
            time_ += 256;
        }
        strip_changed = true;
        swap(a_,b_);
        Schedule(this);
    }

private:
    int led_, stride_;
    uint8_t a_,b_;
    bool fast_, step_;
    
};


int main() {
    Ticker t;
    pc.baud(115200);

    myled = 0;
    latch = 0;
    
    spi.format(8, 0);
    spi.frequency(300000);
    wait_ms(500);
    myled = 1;
    memset(strip, 0x80, sizeof(strip));
    write_strip(strip, sizeof(strip));
    t.attach(&tick_cb, 1.0/1000);
    
    memset(strip, 0x0, sizeof(strip));
    
    /*new RepeatedFadeInOut(0, 0, BLACK, RED, false);
    new RepeatedFadeInOut(171, 1, BLACK, RED, false);
    new RepeatedFadeInOut(341, 2, BLACK, RED, false);
*/
    int stride = 7;
    for (int i = 0; i < stride; i++) {
        new WalkingFadeInOut((256 * i / stride), i, stride, BLACK, GREEN, true);
    }
    
    while(1) {
        while (task_list.empty() || global_tick < task_list.top()->time_) {
            if (strip_changed) {
                write_strip(strip, sizeof(strip));
                strip_changed = false;
                memset(strip, 0x0, sizeof(strip));
            }
        }
        Schedulable* action = task_list.top();
        task_list.pop();
        action->Run();
    }
    strip[0] = BLACK;
    strip[1] = GREEN;
    strip[2] = BLUE;
    strip[3] = getcolor(BLACK, RED);

    (strip, sizeof(strip));

    myled = 1;
    int count = 0;
    memset(strip, 0, sizeof(strip));
    while(1) {
        ++count;
        wait_us(300);
        strobe = !strobe;
        // count = 256 => one thing finished.
        if (count > 511) count = 0;
        bool flush = 0;
        if (count == 0) {
            strip[0] = getcolor(BLACK, RED);
            flush = true;
        }
        if (count== 256) {
            strip[0] = getcolor(RED, BLACK);
            flush = true;
        }
        if (count == 256+83) {
            strip[1] = getcolor(BLACK, RED);
            flush = true;
        }
        if (count== 83) {
            strip[1] = getcolor(RED, BLACK);
            flush = true;
        }
        if (count == 166) {
            strip[2] = getcolor(BLACK, RED);
            flush = true;
        }
        if (count== 256+166) {
            strip[2] = getcolor(RED, BLACK);
            flush = true;
        }
        if (flush) {
            write_strip(strip, sizeof(strip));
            memset(strip, 0, sizeof(strip));
        }
    }
}