Julio G / Mbed 2 deprecated LedStrip

Dependencies:   mbed

Fork of LedStrip_test by Balazs Racz

Committer:
juliogerchman
Date:
Sat Sep 21 19:39:02 2013 +0000
Revision:
3:42efa00ffef4
Parent:
2:590e99f4a313
Child:
4:e3b6f5741d9d
Child:
5:5a2af711d510
bounds working fine

Who changed what in which revision?

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