fireflies.ino 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include <EEPROM.h>
  2. #include <SPI.h>
  3. #include <GD2.h>
  4. void setup()
  5. {
  6. GD.begin(~GD_STORAGE);
  7. bitmap();
  8. }
  9. // Make a 32x32 "soft glow" bitmap
  10. void bitmap()
  11. {
  12. GD.cmd_setbitmap(0, L8, 32, 32);
  13. for (int i = 0; i < 32; i++)
  14. for (int j = 0; j < 32; j++) {
  15. int x = i - 16, y = j - 16;
  16. float d = sqrt((x * x) + (y * y));
  17. float t = constrain(1.0 - d / 16, 0, 1);
  18. GD.wr(32 * i + j, 255 * t * t);
  19. }
  20. }
  21. // Catmull-Rom spline
  22. float spline(float t, float p_1, float p0, float p1, float p2)
  23. {
  24. return (
  25. t*((2-t)*t - 1) * p_1
  26. + (t*t*(3*t - 5) + 2) * p0
  27. + t*((4 - 3*t)*t + 1) * p1
  28. + (t-1)*t*t * p2 ) / 2;
  29. }
  30. // Return a point on path p
  31. xy &path(float t, xy p[])
  32. {
  33. static xy pos;
  34. pos.set(spline(t, p[0].x, p[1].x, p[2].x, p[3].x),
  35. spline(t, p[0].y, p[1].y, p[2].y, p[3].y));
  36. return pos;
  37. }
  38. void loop()
  39. {
  40. GD.Clear();
  41. GD.Begin(BITMAPS);
  42. GD.ColorRGB(0x335020); // Greenish
  43. GD.BlendFunc(SRC_ALPHA, ONE); // Additive blending
  44. xy p[4]; // random control points
  45. int allon; // true if the whole path is onscreen
  46. do {
  47. p[1].set(GD.random(PIXELS(GD.w - 32)), GD.random(PIXELS(GD.h - 32)));
  48. p[2].set(GD.random(PIXELS(GD.w - 32)), GD.random(PIXELS(GD.h - 32)));
  49. p[0] = p[1];
  50. p[0].rmove(PIXELS(300), GD.random());
  51. p[3] = p[2];
  52. p[3].rmove(PIXELS(300), GD.random());
  53. allon = 1;
  54. for (int i = 0; i < 100; i++)
  55. allon &= path(i * .01, p).onscreen();
  56. } while (!allon);
  57. for (int i = 0; i < 100; i++)
  58. path(i * .01, p).draw();
  59. GD.swap();
  60. delay(100);
  61. GD.wr(REG_PWM_DUTY, 128);
  62. delay(GD.random(20, 50)); // range of times to light up, in ms
  63. GD.wr(REG_PWM_DUTY, 0);
  64. delay(GD.random(300, 500)); // range of times to remain dark, in ms
  65. }