Julio G / Mbed 2 deprecated LedStrip

Dependencies:   mbed

Fork of LedStrip_test by Balazs Racz

Committer:
juliogerchman
Date:
Sat Sep 21 19:10:43 2013 +0000
Revision:
2:590e99f4a313
Parent:
1:1a0d5a780e57
Child:
3:42efa00ffef4
region bucket drop working

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bracz 0:109a7a5e3e6e 1 #include <queue>
bracz 0:109a7a5e3e6e 2
bracz 0:109a7a5e3e6e 3 #include "mbed.h"
bracz 0:109a7a5e3e6e 4
bracz 0:109a7a5e3e6e 5 DigitalOut myled(LED1);
bracz 0:109a7a5e3e6e 6
bracz 0:109a7a5e3e6e 7 Serial pc(USBTX, USBRX);
bracz 0:109a7a5e3e6e 8
bracz 0:109a7a5e3e6e 9 SPI spi(p5, p6, p20); // mosi, miso, sclk
bracz 0:109a7a5e3e6e 10 DigitalOut latch(p16);
bracz 0:109a7a5e3e6e 11 DigitalOut strobe(p17);
bracz 0:109a7a5e3e6e 12
juliogerchman 2:590e99f4a313 13 Ticker g_ticker;
juliogerchman 2:590e99f4a313 14
juliogerchman 2:590e99f4a313 15
bracz 1:1a0d5a780e57 16 #define LENGTH 160
bracz 1:1a0d5a780e57 17
bracz 0:109a7a5e3e6e 18 uint8_t strip[160];
bracz 0:109a7a5e3e6e 19
bracz 0:109a7a5e3e6e 20 #define BLACK 0x80
bracz 0:109a7a5e3e6e 21 #define BLUE (BLACK | 0x10)
bracz 0:109a7a5e3e6e 22 #define RED (BLACK | 0x04)
bracz 0:109a7a5e3e6e 23 #define GREEN (BLACK | 0x01)
bracz 0:109a7a5e3e6e 24 #define YELLOW (RED | GREEN)
bracz 0:109a7a5e3e6e 25 #define CYAN (GREEN | BLUE)
bracz 0:109a7a5e3e6e 26 #define MAGENTA (RED | BLUE)
bracz 0:109a7a5e3e6e 27 #define WHITE (RED | GREEN | BLUE)
bracz 0:109a7a5e3e6e 28
juliogerchman 2:590e99f4a313 29 #define FAST 0x40
juliogerchman 2:590e99f4a313 30
bracz 0:109a7a5e3e6e 31 uint8_t fade_result[] =
bracz 0:109a7a5e3e6e 32 {0, 2, 3, 1};
bracz 0:109a7a5e3e6e 33
bracz 0:109a7a5e3e6e 34 uint8_t getbit(uint8_t from, uint8_t to) {
bracz 0:109a7a5e3e6e 35 return fade_result[((from&1) << 1) | (to & 1)];
bracz 0:109a7a5e3e6e 36 }
bracz 0:109a7a5e3e6e 37
bracz 0:109a7a5e3e6e 38 uint8_t getcolor(uint8_t from, uint8_t to) {
bracz 0:109a7a5e3e6e 39 uint8_t result = 0x80;
bracz 0:109a7a5e3e6e 40 result |= getbit(from >> 0, to >> 0) << 0;
bracz 0:109a7a5e3e6e 41 result |= getbit(from >> 2, to >> 2) << 2;
bracz 0:109a7a5e3e6e 42 result |= getbit(from >> 4, to >> 4) << 4;
bracz 0:109a7a5e3e6e 43 return result;
bracz 0:109a7a5e3e6e 44 }
bracz 0:109a7a5e3e6e 45
bracz 0:109a7a5e3e6e 46
bracz 0:109a7a5e3e6e 47 void write_strip(uint8_t* data, int len) {
bracz 0:109a7a5e3e6e 48 latch = 0;
bracz 0:109a7a5e3e6e 49 for (int i = len - 1; i >= 0; i--) {
bracz 0:109a7a5e3e6e 50 spi.write(data[i]);
bracz 0:109a7a5e3e6e 51 }
bracz 0:109a7a5e3e6e 52 latch = 1;
bracz 0:109a7a5e3e6e 53 wait_us(2);
bracz 0:109a7a5e3e6e 54 latch = 0;
bracz 0:109a7a5e3e6e 55 }
bracz 0:109a7a5e3e6e 56
bracz 0:109a7a5e3e6e 57 class Schedulable {
bracz 0:109a7a5e3e6e 58 public:
bracz 0:109a7a5e3e6e 59 int time_;
bracz 0:109a7a5e3e6e 60 virtual void Run() = 0;
bracz 0:109a7a5e3e6e 61
bracz 0:109a7a5e3e6e 62 bool operator<(const Schedulable& o) const {
bracz 0:109a7a5e3e6e 63 return time_ < o.time_;
bracz 0:109a7a5e3e6e 64 }
bracz 0:109a7a5e3e6e 65 };
bracz 0:109a7a5e3e6e 66
bracz 0:109a7a5e3e6e 67
bracz 0:109a7a5e3e6e 68 struct comp {
bracz 0:109a7a5e3e6e 69 bool operator()(const Schedulable* a, const Schedulable* b) {
bracz 0:109a7a5e3e6e 70 return *b < *a;
bracz 0:109a7a5e3e6e 71 }
bracz 0:109a7a5e3e6e 72 };
bracz 0:109a7a5e3e6e 73
bracz 0:109a7a5e3e6e 74 priority_queue<Schedulable*, vector<Schedulable*>, comp> task_list;
bracz 0:109a7a5e3e6e 75
bracz 0:109a7a5e3e6e 76 void Schedule(Schedulable* action) {
bracz 0:109a7a5e3e6e 77 task_list.push(action);
bracz 0:109a7a5e3e6e 78 }
bracz 0:109a7a5e3e6e 79
bracz 0:109a7a5e3e6e 80 int global_tick = 0;
bracz 0:109a7a5e3e6e 81 bool strip_changed;
bracz 0:109a7a5e3e6e 82
bracz 0:109a7a5e3e6e 83 void tick_cb() {
bracz 0:109a7a5e3e6e 84 ++global_tick;
bracz 0:109a7a5e3e6e 85 strobe = !strobe;
bracz 0:109a7a5e3e6e 86 }
bracz 0:109a7a5e3e6e 87
bracz 0:109a7a5e3e6e 88 class RepeatedFadeInOut : public Schedulable {
bracz 0:109a7a5e3e6e 89 public:
bracz 0:109a7a5e3e6e 90 RepeatedFadeInOut(int start_time, int led, uint8_t a, uint8_t b, bool fast)
bracz 0:109a7a5e3e6e 91 : led_(led), a_(a), b_(b), fast_(fast) {
bracz 0:109a7a5e3e6e 92 time_ = start_time;
bracz 0:109a7a5e3e6e 93 Schedule(this);
bracz 0:109a7a5e3e6e 94 }
bracz 0:109a7a5e3e6e 95
bracz 0:109a7a5e3e6e 96 virtual void Run() {
bracz 0:109a7a5e3e6e 97 strip[led_] = getcolor(a_, b_);
bracz 0:109a7a5e3e6e 98 if (fast_) {
juliogerchman 2:590e99f4a313 99 strip[led_] |= FAST;
bracz 0:109a7a5e3e6e 100 time_ += 128;
bracz 0:109a7a5e3e6e 101 } else {
bracz 0:109a7a5e3e6e 102 time_ += 256;
bracz 0:109a7a5e3e6e 103 }
bracz 0:109a7a5e3e6e 104 strip_changed = true;
bracz 0:109a7a5e3e6e 105 swap(a_,b_);
bracz 0:109a7a5e3e6e 106 Schedule(this);
bracz 0:109a7a5e3e6e 107 }
juliogerchman 2:590e99f4a313 108
bracz 0:109a7a5e3e6e 109 private:
bracz 0:109a7a5e3e6e 110 int led_;
bracz 0:109a7a5e3e6e 111 uint8_t a_,b_;
bracz 0:109a7a5e3e6e 112 bool fast_;
bracz 0:109a7a5e3e6e 113 };
bracz 0:109a7a5e3e6e 114
bracz 1:1a0d5a780e57 115 class WalkingFadeInOut : public Schedulable {
bracz 1:1a0d5a780e57 116 public:
bracz 1:1a0d5a780e57 117 WalkingFadeInOut(int start_time, int led, int stride, uint8_t a, uint8_t b, bool fast)
bracz 1:1a0d5a780e57 118 : led_(led - stride), stride_(stride), a_(a), b_(b), fast_(fast), step_(true) {
bracz 1:1a0d5a780e57 119 time_ = start_time;
bracz 1:1a0d5a780e57 120 Schedule(this);
bracz 1:1a0d5a780e57 121 }
bracz 1:1a0d5a780e57 122
bracz 1:1a0d5a780e57 123 virtual void Run() {
bracz 1:1a0d5a780e57 124 if (step_) {
bracz 1:1a0d5a780e57 125 step_ = false;
bracz 1:1a0d5a780e57 126 if (led_ >= 0) strip[led_] = a_;
bracz 1:1a0d5a780e57 127 led_ += stride_;
bracz 1:1a0d5a780e57 128 led_ %= LENGTH;
bracz 1:1a0d5a780e57 129 } else {
bracz 1:1a0d5a780e57 130 step_ = true;
bracz 1:1a0d5a780e57 131 }
bracz 1:1a0d5a780e57 132 strip[led_] = getcolor(a_, b_);
bracz 1:1a0d5a780e57 133 if (fast_) {
juliogerchman 2:590e99f4a313 134 strip[led_] |= FAST;
bracz 1:1a0d5a780e57 135 time_ += 128;
bracz 1:1a0d5a780e57 136 } else {
bracz 1:1a0d5a780e57 137 time_ += 256;
bracz 1:1a0d5a780e57 138 }
bracz 1:1a0d5a780e57 139 strip_changed = true;
bracz 1:1a0d5a780e57 140 swap(a_,b_);
bracz 1:1a0d5a780e57 141 Schedule(this);
bracz 1:1a0d5a780e57 142 }
juliogerchman 2:590e99f4a313 143
bracz 1:1a0d5a780e57 144 private:
bracz 1:1a0d5a780e57 145 int led_, stride_;
bracz 1:1a0d5a780e57 146 uint8_t a_,b_;
bracz 1:1a0d5a780e57 147 bool fast_, step_;
bracz 1:1a0d5a780e57 148
bracz 1:1a0d5a780e57 149 };
bracz 1:1a0d5a780e57 150
juliogerchman 2:590e99f4a313 151 class RegionWalkingFadeInOut : public Schedulable {
juliogerchman 2:590e99f4a313 152 public:
juliogerchman 2:590e99f4a313 153 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)
juliogerchman 2:590e99f4a313 154 : 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) {
juliogerchman 2:590e99f4a313 155 time_ = start_time;
juliogerchman 2:590e99f4a313 156 Schedule(this);
juliogerchman 2:590e99f4a313 157 }
bracz 1:1a0d5a780e57 158
juliogerchman 2:590e99f4a313 159 virtual void Run() {
juliogerchman 2:590e99f4a313 160 if (step_) {
juliogerchman 2:590e99f4a313 161 step_ = false;
juliogerchman 2:590e99f4a313 162 if (led_ >= 0) strip[led_ + start_led_] = a_;
juliogerchman 2:590e99f4a313 163 led_ += stride_;
juliogerchman 2:590e99f4a313 164 if (repeat_) {
juliogerchman 2:590e99f4a313 165 led_ %= length_;
juliogerchman 2:590e99f4a313 166 } else {
juliogerchman 2:590e99f4a313 167 if (led_ > length_) {
juliogerchman 2:590e99f4a313 168 if (next_ && led_ == (length_ + stride_)) {
juliogerchman 2:590e99f4a313 169 next_->time_ = global_tick + 1;
juliogerchman 2:590e99f4a313 170 Schedule(next_);
juliogerchman 2:590e99f4a313 171 }
juliogerchman 2:590e99f4a313 172 delete this;
juliogerchman 2:590e99f4a313 173 return;
juliogerchman 2:590e99f4a313 174 }
juliogerchman 2:590e99f4a313 175 }
juliogerchman 2:590e99f4a313 176 } else {
juliogerchman 2:590e99f4a313 177 if (led_ == length_ && drop_ && !repeat_) {
juliogerchman 2:590e99f4a313 178 if (next_) {
juliogerchman 2:590e99f4a313 179 next_->time_ = global_tick + 1;
juliogerchman 2:590e99f4a313 180 Schedule(next_);
juliogerchman 2:590e99f4a313 181 }
juliogerchman 2:590e99f4a313 182 delete this;
juliogerchman 2:590e99f4a313 183 return;
juliogerchman 2:590e99f4a313 184 }
juliogerchman 2:590e99f4a313 185 step_ = true;
juliogerchman 2:590e99f4a313 186 }
juliogerchman 2:590e99f4a313 187 strip[led_ + start_led_] = getcolor(a_, b_);
juliogerchman 2:590e99f4a313 188 if (fast_) {
juliogerchman 2:590e99f4a313 189 strip[led_ + start_led_] |= FAST;
juliogerchman 2:590e99f4a313 190 time_ += 128;
juliogerchman 2:590e99f4a313 191 } else {
juliogerchman 2:590e99f4a313 192 time_ += 256;
juliogerchman 2:590e99f4a313 193 }
juliogerchman 2:590e99f4a313 194 strip_changed = true;
juliogerchman 2:590e99f4a313 195 swap(a_,b_);
juliogerchman 2:590e99f4a313 196 Schedule(this);
juliogerchman 2:590e99f4a313 197 }
juliogerchman 2:590e99f4a313 198
juliogerchman 2:590e99f4a313 199 private:
juliogerchman 2:590e99f4a313 200 int led_, stride_;
juliogerchman 2:590e99f4a313 201 int start_led_, length_;
juliogerchman 2:590e99f4a313 202 uint8_t a_,b_;
juliogerchman 2:590e99f4a313 203 bool fast_, step_;
juliogerchman 2:590e99f4a313 204 bool repeat_, drop_;
juliogerchman 2:590e99f4a313 205 Schedulable* next_;
juliogerchman 2:590e99f4a313 206 };
juliogerchman 2:590e99f4a313 207
juliogerchman 2:590e99f4a313 208 /* Keep dropping water drops in a bucket, until it fills up. */
juliogerchman 2:590e99f4a313 209 class DropBucketFill : public Schedulable {
juliogerchman 2:590e99f4a313 210 public:
juliogerchman 2:590e99f4a313 211 DropBucketFill(int start_time, int start_led, int length, int drop_size, uint8_t from_color, uint8_t to_color)
juliogerchman 2:590e99f4a313 212 : start_led_(start_led), length_(length), drop_size_(drop_size), from_color_(from_color), to_color_(to_color) {
juliogerchman 2:590e99f4a313 213 time_ = start_time;
juliogerchman 2:590e99f4a313 214 Schedule(this);
juliogerchman 2:590e99f4a313 215 }
juliogerchman 2:590e99f4a313 216
juliogerchman 2:590e99f4a313 217 virtual void Run() {
juliogerchman 2:590e99f4a313 218 // The bucket starts with a drop at its end.
juliogerchman 2:590e99f4a313 219 //strip[start_led_ + length_] = to_color_;
juliogerchman 2:590e99f4a313 220 //strip[start_led_ + length_] = RED;
juliogerchman 2:590e99f4a313 221 if (length_ > 0) {
juliogerchman 2:590e99f4a313 222 // There's still space in the bucket. Drop a new drop.
juliogerchman 2:590e99f4a313 223 for (int i = 0; i < drop_size_; ++i) {
juliogerchman 2:590e99f4a313 224 Schedulable* next_drop = NULL;
juliogerchman 2:590e99f4a313 225 next_drop = this;
juliogerchman 2:590e99f4a313 226 new RegionWalkingFadeInOut(time_ + (256 * i / drop_size_), i, drop_size_, start_led_, length_ - 1, from_color_, to_color_, true, false, true, next_drop);
juliogerchman 2:590e99f4a313 227 }
juliogerchman 2:590e99f4a313 228 length_--;
juliogerchman 2:590e99f4a313 229 } else {
juliogerchman 2:590e99f4a313 230 // There's no more space in the bucket. Bail out.
juliogerchman 2:590e99f4a313 231 delete this;
juliogerchman 2:590e99f4a313 232 return;
juliogerchman 2:590e99f4a313 233 }
juliogerchman 2:590e99f4a313 234 }
juliogerchman 2:590e99f4a313 235
juliogerchman 2:590e99f4a313 236 private:
juliogerchman 2:590e99f4a313 237 int start_led_, length_;
juliogerchman 2:590e99f4a313 238 int drop_size_;
juliogerchman 2:590e99f4a313 239 uint8_t from_color_, to_color_;
juliogerchman 2:590e99f4a313 240 };
juliogerchman 2:590e99f4a313 241
juliogerchman 2:590e99f4a313 242 void init_board() {
bracz 0:109a7a5e3e6e 243 pc.baud(115200);
bracz 0:109a7a5e3e6e 244
bracz 0:109a7a5e3e6e 245 myled = 0;
bracz 0:109a7a5e3e6e 246 latch = 0;
bracz 0:109a7a5e3e6e 247
bracz 0:109a7a5e3e6e 248 spi.format(8, 0);
bracz 0:109a7a5e3e6e 249 spi.frequency(300000);
bracz 0:109a7a5e3e6e 250 wait_ms(500);
bracz 0:109a7a5e3e6e 251 myled = 1;
juliogerchman 2:590e99f4a313 252 memset(strip, BLACK, sizeof(strip));
bracz 0:109a7a5e3e6e 253 write_strip(strip, sizeof(strip));
juliogerchman 2:590e99f4a313 254 g_ticker.attach(&tick_cb, 1.0/1000);
bracz 0:109a7a5e3e6e 255
bracz 0:109a7a5e3e6e 256 memset(strip, 0x0, sizeof(strip));
juliogerchman 2:590e99f4a313 257 }
juliogerchman 2:590e99f4a313 258
juliogerchman 2:590e99f4a313 259 void run_loop() {
bracz 0:109a7a5e3e6e 260 while(1) {
bracz 0:109a7a5e3e6e 261 while (task_list.empty() || global_tick < task_list.top()->time_) {
bracz 0:109a7a5e3e6e 262 if (strip_changed) {
bracz 0:109a7a5e3e6e 263 write_strip(strip, sizeof(strip));
bracz 0:109a7a5e3e6e 264 strip_changed = false;
bracz 0:109a7a5e3e6e 265 memset(strip, 0x0, sizeof(strip));
bracz 0:109a7a5e3e6e 266 }
bracz 0:109a7a5e3e6e 267 }
bracz 0:109a7a5e3e6e 268 Schedulable* action = task_list.top();
bracz 0:109a7a5e3e6e 269 task_list.pop();
bracz 0:109a7a5e3e6e 270 action->Run();
bracz 0:109a7a5e3e6e 271 }
juliogerchman 2:590e99f4a313 272 }
bracz 0:109a7a5e3e6e 273
juliogerchman 2:590e99f4a313 274 int main() {
juliogerchman 2:590e99f4a313 275 init_board();
bracz 0:109a7a5e3e6e 276
juliogerchman 2:590e99f4a313 277 int stride = 7;
juliogerchman 2:590e99f4a313 278 for (int i = 0; i < stride; i++) {
juliogerchman 2:590e99f4a313 279 //new WalkingFadeInOut((256 * i / stride), i, stride, BLACK, RED, true);
juliogerchman 2:590e99f4a313 280 /* new RepeatedFadeInOut(0, i, BLACK, RED, false); */
juliogerchman 2:590e99f4a313 281 //new RegionWalkingFadeInOut((256 * i / stride), i, stride, 5, 30, BLACK, BLUE, true, false);
bracz 0:109a7a5e3e6e 282 }
juliogerchman 2:590e99f4a313 283
juliogerchman 2:590e99f4a313 284 new DropBucketFill(0, 10, 20, 3, BLACK, BLUE);
juliogerchman 2:590e99f4a313 285
juliogerchman 2:590e99f4a313 286 run_loop();
juliogerchman 2:590e99f4a313 287 }