Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of LedStrip_test by
main.cpp
- Committer:
- juliogerchman
- Date:
- 2013-09-21
- Revision:
- 3:42efa00ffef4
- Parent:
- 2:590e99f4a313
- Child:
- 4:e3b6f5741d9d
- Child:
- 5:5a2af711d510
File content as of revision 3:42efa00ffef4:
#include <queue> #include <algorithm> #include "mbed.h" DigitalOut myled(LED1); Serial pc(USBTX, USBRX); SPI spi(p5, p6, p20); // mosi, miso, sclk DigitalOut latch(p16); DigitalOut strobe(p17); Ticker g_ticker; #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) #define FAST 0x40 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_] |= FAST; 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_] |= FAST; time_ += 128; } else { time_ += 256; } strip_changed = true; swap(a_,b_); Schedule(this); } private: int led_, stride_; uint8_t a_,b_; bool fast_, step_; }; class RegionWalkingFadeInOut : public Schedulable { public: RegionWalkingFadeInOut(int start_time, int led, int stride, int start_led, int length, uint8_t a, uint8_t b, bool fast, bool repeat, bool drop, Schedulable* next) : led_(led - stride), stride_(stride), start_led_(start_led), length_(length), a_(a), b_(b), fast_(fast), step_(true), repeat_(repeat), drop_(drop), next_(next) { time_ = start_time; Schedule(this); } virtual void Run() { if (step_) { step_ = false; if (led_ >= 0) strip[led_ + start_led_] = a_; led_ += stride_; if (repeat_) { led_ %= length_; } else { if (led_ >= length_) { /*if (next_ && led_ == (length_ + stride_)) { next_->time_ = global_tick + 1; Schedule(next_); }*/ delete this; return; } } } else { if (led_ == (length_ - 1) && drop_ && !repeat_) { if (next_) { next_->time_ = global_tick + 257; Schedule(next_); } delete this; return; } step_ = true; } strip[led_ + start_led_] = getcolor(a_, b_); if (fast_) { strip[led_ + start_led_] |= FAST; time_ += 128; } else { time_ += 256; } strip_changed = true; swap(a_,b_); Schedule(this); } private: int led_, stride_; int start_led_, length_; uint8_t a_,b_; bool fast_, step_; bool repeat_, drop_; Schedulable* next_; }; /* Keep dropping water drops in a bucket, until it fills up. */ class DropBucketFill : public Schedulable { public: DropBucketFill(int start_time, int start_led, int length, int drop_size, uint8_t from_color, uint8_t to_color) : start_led_(start_led), length_(length), drop_size_(drop_size), from_color_(from_color), to_color_(to_color) { time_ = start_time; Schedule(this); } virtual void Run() { // The bucket starts with a drop at its end. //strip[start_led_ + length_] = to_color_; //strip[start_led_ + length_] = RED; if (length_ > 0) { // There's still space in the bucket. Drop a new drop. for (int i = 0; i < min(drop_size_, length_); ++i) { Schedulable* next_drop = NULL; next_drop = this; new RegionWalkingFadeInOut(time_ + (256 * i / drop_size_), i, drop_size_, start_led_, length_, from_color_, to_color_, true, false, true, next_drop); } length_--; } else { // There's no more space in the bucket. Bail out. delete this; return; } } private: int start_led_, length_; int drop_size_; uint8_t from_color_, to_color_; }; void init_board() { pc.baud(115200); myled = 0; latch = 0; spi.format(8, 0); spi.frequency(300000); wait_ms(500); myled = 1; memset(strip, BLACK, sizeof(strip)); write_strip(strip, sizeof(strip)); g_ticker.attach(&tick_cb, 1.0/1000); memset(strip, 0x0, sizeof(strip)); } void run_loop() { 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(); } } int main() { init_board(); int stride = 7; for (int i = 0; i < stride; i++) { //new WalkingFadeInOut((256 * i / stride), i, stride, BLACK, RED, true); /* new RepeatedFadeInOut(0, i, BLACK, RED, false); */ //new RegionWalkingFadeInOut((256 * i / stride), i, stride, 5, 30, BLACK, BLUE, true, false); } new DropBucketFill(0, 10, 20, 3, BLACK, BLUE); new DropBucketFill(0, 30, 20, 11, BLACK, GREEN); run_loop(); }