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.
main.cpp
- Committer:
- juliogerchman
- Date:
- 2013-09-21
- Revision:
- 2:590e99f4a313
- Parent:
- 1:1a0d5a780e57
- Child:
- 3:42efa00ffef4
File content as of revision 2:590e99f4a313:
#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); 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_ && drop_ && !repeat_) { if (next_) { next_->time_ = global_tick + 1; 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 < drop_size_; ++i) { Schedulable* next_drop = NULL; next_drop = this; new RegionWalkingFadeInOut(time_ + (256 * i / drop_size_), i, drop_size_, start_led_, length_ - 1, 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); run_loop(); }