# PixelDust Digital Sand Demos for Arcada

## Overview

PyGamer and PyBadge have built in accelerometers - which you can use in your games or demos to make nifty motion-activated effects. In this mini guide we'll show you some examples of [PaintYourDragon's PixelDust](https://github.com/adafruit/Adafruit_PixelDust) library but for Arcada boards

https://www.youtube.com/watch?v=GXRP9LKlqnA

# Supported Hardware

You'll need a board with [Adafruit Arcada](https://github.com/adafruit/Adafruit_Arcada) support + an accelerometer such as...

Featured
### Adafruit PyGamer Starter Kit

[Adafruit PyGamer Starter Kit](https://www.adafruit.com/product/4277)
**Please note: you may get a royal blue _or_ purple case with your starter kit (they're both lovely colors)**

What&nbsp;fits in your pocket, is fully Open Source, and can run CircuitPython, MakeCode Arcade or Arduino games you write yourself? That's right,...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4277)
[Related Guides to the Product](https://learn.adafruit.com/products/4277/guides)
![Adafruit PyGamer Starter Kit with PCB, enclosure, buttons, and storage bag](https://cdn-shop.adafruit.com/640x480/4277-08.jpg)

Featured
### Adafruit PyGamer for MakeCode Arcade, CircuitPython or Arduino

[Adafruit PyGamer for MakeCode Arcade, CircuitPython or Arduino](https://www.adafruit.com/product/4242)
What&nbsp;fits in your pocket, is fully Open Source, and can run CircuitPython, MakeCode Arcade or Arduino games you write yourself? That's right, it's the **Adafruit PyGamer!** We wanted to make an entry-level gaming handheld for DIY gaming, and maybe a little...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4242)
[Related Guides to the Product](https://learn.adafruit.com/products/4242/guides)
![Angled shot of Adafruit PyGamer for MakeCode Arcade, CircuitPython or Arduino.](https://cdn-shop.adafruit.com/640x480/4242-00.jpg)

Featured
### Adafruit PyBadge for MakeCode Arcade, CircuitPython, or Arduino

[Adafruit PyBadge for MakeCode Arcade, CircuitPython, or Arduino](https://www.adafruit.com/product/4200)
What's the size of a credit card and can run CircuitPython, MakeCode Arcade or Arduino? That's right, its the **Adafruit PyBadge!** We wanted to see how much we could cram into a ​3 3⁄8 × ​2 1⁄8 inch rounded rectangle, to make an all-in-one dev board with...

In Stock
[Buy Now](https://www.adafruit.com/product/4200)
[Related Guides to the Product](https://learn.adafruit.com/products/4200/guides)
![Angled shot of a Adafruit PyBadge for MakeCode Arcade, CircuitPython, or Arduino. ](https://cdn-shop.adafruit.com/640x480/4200-01.jpg)

Featured
### USB cable - USB A to Micro-B

[USB cable - USB A to Micro-B](https://www.adafruit.com/product/592)
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or microcontroller

Approximately 3 feet / 1 meter long

In Stock
[Buy Now](https://www.adafruit.com/product/592)
[Related Guides to the Product](https://learn.adafruit.com/products/592/guides)
![USB cable - USB A to Micro-B - 3 foot long](https://cdn-shop.adafruit.com/640x480/592-01.jpg)

# PixelDust Digital Sand Demos for Arcada

## Compile & Upload

Start by following your board's guide on installing Arduino IDE, and support for the board you have. [Then install the Adafruit Arcada libraries](https://learn.adafruit.com/adafruit-pybadge/arcada-libraries) (there's a _lot_ of em!)

Also install the [Adafruit PixelDust](https://github.com/adafruit/Adafruit_PixelDust) library

![](https://cdn-learn.adafruit.com/assets/assets/000/076/667/medium800thumb/sensors_ezgif-1-4b7d80e51b58.jpg?1560136205)

# Compilation Settings

As you get to a few thousand particles, you'll want to speed up your board as much as possible. Compile with _ultra-speed_ settings such as `200MHz overclock`, `-Ofast optimizations` and `Cache enabled`.

![](https://cdn-learn.adafruit.com/assets/assets/000/076/660/medium800/sensors_image.png?1560132947)

# Runtime Settings

There's not a lot of things you can adjust but here's a few common ones:

`#define CHUNKY_SAND`

If this is at the top of the code, it will make each particle a 2x2 pixel rather than a single pixel. this makes it look a little better, but you can't fit as many particles on the screen.

`#define N_FLAKES 2000`

How many particles to simulate. More look cooler but too many and it slows down! 1000-2000 seems to be a good number, especially with `CHUNKY_SAND` turned on.

On this line in the loop:

`pixeldust->iterate(xx * 3000.0, yy * 3000.0, zz * 3000.0);`

The multiplier affects the 'gravity' of the pixels. Larger numbers will drag the pixels down faster, smaller numbers will make the pixels float a little more.

# Snow Demo

Start with the **pixeldust\_demos-\>pixeldust\_snow** example, its the simplest demo - each pixel is the same white color.

![](https://cdn-learn.adafruit.com/assets/assets/000/076/661/medium800/sensors_image.png?1560133057)

Upload and enjoy!

![sensors_snow.jpg](https://cdn-learn.adafruit.com/assets/assets/000/076/662/medium640/sensors_snow.jpg?1560133972)

# Sand Demo
This demo builds on the snow version to add speckled yellow colors to each particle, to create a sand-effect!

![sensors_sand.jpg](https://cdn-learn.adafruit.com/assets/assets/000/076/665/medium640/sensors_sand.jpg?1560134798)

You can add color to each pixel by creating a new array of 16-bit colors as we do in this demo with the creation of `uint16_t *flake_colors;` and then later `flake_colors = (uint16_t *)malloc(N_FLAKES *2)`;

Then you can assign the colors, we'll use an HSV picker to find a hue we think is sandy...

![](https://cdn-learn.adafruit.com/assets/assets/000/076/664/medium800/sensors_image.png?1560134535)

And randomly assign brightness/saturations so we get a range of sandy colors!

```auto
  // randomize colors
  for (int i=0; i< N_FLAKES; i++) {
    flake_colors[i] = 
      __builtin_bswap16(arcada.ColorHSV565(40, // Hue (sandy)
                                           random(50, 100),  // saturation
                                           random(50, 100))); // brightness
  }
```

Note we use `__builtin_bswap16` on each color word. That's because we later use DMA to write out all the pixels and we need to have the high/low bytes of color swapped in order for it to run as fast as possible (its a weird effect of TFT DMA on Arduino)

Later on, when we draw the pixels, we'll look up the corresponding color before we draw the color to our framebuffer:

```auto
  for(int i=0; i<N_FLAKES; i++) {
    pixeldust->getPosition(i, &x, &y);
    //Serial.printf("(%d, %d) -> %d\n", x, y, x * width + y);
    uint16_t flakeColor = flake_colors[i];
#ifdef CHUNKY_SAND
    framebuffer[2*y * width + 2*x] = flakeColor;
    framebuffer[2*y * width + 2*x+1] = flakeColor;
    framebuffer[(2*y+1) * width + 2*x] = flakeColor;
    framebuffer[(2*y+1) * width + 2*x + 1] = flakeColor;
#else
    framebuffer[y * width + x] = flakeColor;
#endif
  }
```

# Logo Demo

Finally, the most advanced of the demos adds a logo 'obstacle' both as an image and a 'mask' that tells PixelDust where not to let pixels go. This makes for lovely effects as particles slide around.

![](https://cdn-learn.adafruit.com/assets/assets/000/076/666/medium800thumb/sensors_ezgif-1-247db949ce6f.jpg?1560136066)

For the logo, which is 8-bit grayscale and stored in the header, [you can use a tool like this that will take an image and convert it into a header file](https://littlevgl.com/image-to-c-array).

Like the sand demo we will store a color for each particle. Except this time instead of randomly placing them on the display, they are put into boxes along the bottom of the screen:

```auto
  // Set up initial sand coordinates, in 8x8 blocks
  int n = 0;
  for(int i=0; i<N_COLORS; i++) {
    int xx = i * play_width / N_COLORS;
    int yy =  play_height - BOX_HEIGHT;
    for(int y=0; y<BOX_HEIGHT; y++) {
      for(int x=0; x<play_width / N_COLORS; x++) {
        //Serial.printf("#%d -> (%d, %d)\n", n,  xx + x, yy + y);
        pixeldust->setPosition(n++, xx + x, yy + y);
      }
    }
  }
```

Since the chunks of particle divide up into 8 colors, we dont have to store the color of each one, we know that the index of the particle, divided by 8, gives the color index. Notes we have to `bswap16` the color here like we did before.

```auto
  colors[0] = arcada.color565(40 , 40, 40);   // Dark Gray
  colors[1] = arcada.color565(120, 79, 23);   // Brown
  colors[2] = arcada.color565(228,  3,  3);   // Red
  colors[3] = arcada.color565(255,140,  0);   // Orange
  colors[4] = arcada.color565(255,237,  0);   // Yellow
  colors[5] = arcada.color565(  0,128, 38);   // Green
  colors[6] = arcada.color565(  0, 77,255);   // Blue
  colors[7] = arcada.color565(117,  7,135); // Purple
  for (int i=0; i<N_COLORS; i++) {
    colors[i] = __builtin_bswap16(colors[i]);  // we swap the colors here to speed up DMA
  }
```

Then before we draw all the particles, we also have to draw the logo:

```auto
  int logo_origin_x = (width  - 2*LOGO_WIDTH ) / 2;
  int logo_origin_y = (height - 2*LOGO_HEIGHT ) / 2;
  // Draw the logo atop the background...
  for(int yl=0; yl<LOGO_HEIGHT; yl++) {
    for(int xl=0; xl<LOGO_WIDTH; xl++) {
      uint16_t c = 
         __builtin_bswap16(arcada.color565(logo_gray[yl][xl], logo_gray[yl][xl], logo_gray[yl][xl]));
      x = logo_origin_x + 2*xl;
      y = logo_origin_y + 2*yl; 
      
      framebuffer[y * width + x] = c;
      framebuffer[y * width + x+1] = c;
      framebuffer[(y+1) * width + x] = c;
      framebuffer[(y+1) * width + x+1] = c;
    }
  }
```


## Guide Products

### Adafruit PyGamer Starter Kit

[Adafruit PyGamer Starter Kit](https://www.adafruit.com/product/4277)
**Please note: you may get a royal blue _or_ purple case with your starter kit (they're both lovely colors)**

What&nbsp;fits in your pocket, is fully Open Source, and can run CircuitPython, MakeCode Arcade or Arduino games you write yourself? That's right,...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4277)
[Related Guides to the Product](https://learn.adafruit.com/products/4277/guides)
### Adafruit PyGamer for MakeCode Arcade, CircuitPython or Arduino

[Adafruit PyGamer for MakeCode Arcade, CircuitPython or Arduino](https://www.adafruit.com/product/4242)
What&nbsp;fits in your pocket, is fully Open Source, and can run CircuitPython, MakeCode Arcade or Arduino games you write yourself? That's right, it's the **Adafruit PyGamer!** We wanted to make an entry-level gaming handheld for DIY gaming, and maybe a little...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4242)
[Related Guides to the Product](https://learn.adafruit.com/products/4242/guides)
### Adafruit PyBadge for MakeCode Arcade, CircuitPython, or Arduino

[Adafruit PyBadge for MakeCode Arcade, CircuitPython, or Arduino](https://www.adafruit.com/product/4200)
What's the size of a credit card and can run CircuitPython, MakeCode Arcade or Arduino? That's right, its the **Adafruit PyBadge!** We wanted to see how much we could cram into a ​3 3⁄8 × ​2 1⁄8 inch rounded rectangle, to make an all-in-one dev board with...

In Stock
[Buy Now](https://www.adafruit.com/product/4200)
[Related Guides to the Product](https://learn.adafruit.com/products/4200/guides)
### USB cable - USB A to Micro-B

[USB cable - USB A to Micro-B](https://www.adafruit.com/product/592)
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or microcontroller

Approximately 3 feet / 1 meter long

In Stock
[Buy Now](https://www.adafruit.com/product/592)
[Related Guides to the Product](https://learn.adafruit.com/products/592/guides)

## Related Guides

- [Adafruit PyBadge and PyBadge LC](https://learn.adafruit.com/adafruit-pybadge.md)
- [Introducing Adafruit PyGamer](https://learn.adafruit.com/adafruit-pygamer.md)
- [PyBadge GamePad](https://learn.adafruit.com/pybadge-gamepad.md)
- [Oculus Quest Battery Counterweight](https://learn.adafruit.com/oculus-quest-battery-counterweight.md)
- [Sound Reactive Rapunzel Hair](https://learn.adafruit.com/sound-reactive-rapunzel-hair.md)
- [Simple Vertical Wordclock](https://learn.adafruit.com/vertical-wordclock.md)
- [MLX90640 Thermal Camera with Image Recording](https://learn.adafruit.com/mlx90640-thermal-image-recording.md)
- [CircuitScheme - Lisp on CircuitPython](https://learn.adafruit.com/scheme-in-circuitpython.md)
- [eInk / ePaper Weather Station](https://learn.adafruit.com/epaper-weather-station.md)
- [Multi-tasking with CircuitPython](https://learn.adafruit.com/multi-tasking-with-circuitpython.md)
- [Bluetooth Cycling Speed & Cadence Sensor Display with Clue](https://learn.adafruit.com/bluetooth-bicycle-speed-cadence-sensor-display-with-clue.md)
- [Christmas Soundboard with NeoTrellis M4](https://learn.adafruit.com/xmas-sound-board.md)
- [Tappy Robotic Hand](https://learn.adafruit.com/robotic-tapping-hand-with-cpx.md)
- [Snake Charmer Box](https://learn.adafruit.com/snakecharmer.md)
- [PyPortal Word of the Day Display](https://learn.adafruit.com/pyportal-word-of-the-day-display.md)
- [Crickit Powered Mini Chair Swing Ride!](https://learn.adafruit.com/mini-chair-swing-ride.md)
- [Crawling Baby Sea Turtle Robot](https://learn.adafruit.com/baby-turtle-makecode.md)
