# Circuit Playground D6 Dice

## Overview

[Dice](https://en.wikipedia.org/wiki/Dice) are another one of those game related items that have been around for a long time. They come in a wide variety of shapes and sizes, but the most common is the basic 6 sided dice, otherwise known as the D6.

In this guide, we'll show how we can simulate a D6 dice on the&nbsp; Circuit Playground using the NeoPixels to represent the various patterns of the dice face. We'll also use the accelerometer to simulate "rolling the dice" by detecting shaking. And because we can, we'll add a tap detect feature for quick and easy rolling.

# Required Parts

This project uses the sensors already included on the Circuit Playground, either a [Classic](https://www.adafruit.com/products/3000) or an [Express](https://www.adafruit.com/products/3333). The only additional items needed are batteries for power and a holder for the batteries.

- Circuit Playground

  - [Classic](https://www.adafruit.com/products/3000)
  - [Express](https://www.adafruit.com/products/3333)

- [3 x AAA Battery Holder](https://www.adafruit.com/products/727)
- 3 x AAA Batteries (NiMH work great!)

![circuit_playground_items.jpg](https://cdn-learn.adafruit.com/assets/assets/000/037/856/medium640/circuit_playground_items.jpg?1481062216)

# Before Starting

If you are new to the Circuit Playground, you may want to first read these overview guides.

## Circuit Playground Classic

- [Overview](../../../introducing-circuit-playground)
- [Lesson #0](../../../circuit-playground-lesson-number-0)

## Circuit Playground Express

- [Overview](../../../adafruit-circuit-playground-express/)

# Circuit Playground D6 Dice

## Arduino

The following pages go over developing the D6 Dice using the Arduino IDE.

# Circuit Playground D6 Dice

## Random, or Not?

The whole point of a dice is to provide a way to randomly come up with a number. In the case of a D6 dice, this would be a number from 1 to 6. The Arduino library provides a [random](https://www.arduino.cc/en/Reference/Random) function we can use, but let's take a look at how it behaves.

Try running the simple sketch below.

```
///////////////////////////////////////////////////////////////////////////////
// Circuit Playground Random Demo
//
// Author: Carter Nelson
// MIT License (https://opensource.org/licenses/MIT)

#include &lt;Adafruit_CircuitPlayground.h&gt;

///////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);

  CircuitPlayground.begin();  
}

///////////////////////////////////////////////////////////////////////////////
void loop() {
  // Wait for button press
  while (!CircuitPlayground.leftButton()   &amp;&amp; 
         !CircuitPlayground.rightButton())  {
    // Do nothing, just waiting for a button press...
  }

  // Print a random number
  Serial.println(random(1,7));

  // Debounce delay
  delay(500);
}
```

With this code loaded and running on the Circuit Playground, open the Serial Monitor.

**Tools -\> Serial Monitor**

and then press either button. Each time, a random number from 1 to 6 will be printed out. Let me guess, you got the same sequence I did as shown below.

![](https://cdn-learn.adafruit.com/assets/assets/000/037/857/medium800/circuit_playground_random_sequence1.png?1481063582)

And if you reset the Circuit Playground and try this again, you will get the same sequence again. So what's going on?

In turns out that the `random()` function implemented in the Arduino library is only a pseudo-random function. This simply means it isn't fully random (pseudo = false). It just produces a random like sequence of numbers, and the same sequence every time.

To get around this, we need to initialize the random function with a random value. Which, to be honest, sounds a little...unusual! I mean, if we _had_ a random value why use random() at all? But it really does make sense: if it were possible to get one random value, maybe in a round-about way, we could then take advantage of the simple built in function.

This is called _seeding the function_ and the value is called the _seed_. You plant a _seed_ of randomness, and then we can harvest any number of random numbers we need, forever!

But where can we come up with a random seed value? One way is to use some unused sensor that is (hopefully) reporting random and changing values of whatever it is meant to sense. Like light. Hey, we got a light sensor. Let's use that. We simply need to make a call to `lightSensor()` and feed that value into `randomSeed()`.

Here's a new version of the code that includes a call to `randomSeed()` in the `setup()`. This seed is generated by reading the light sensor.

```
///////////////////////////////////////////////////////////////////////////////
// Circuit Playground Random Demo with Seed
//
// Author: Carter Nelson
// MIT License (https://opensource.org/licenses/MIT)

#include &lt;Adafruit_CircuitPlayground.h&gt;

///////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);

  CircuitPlayground.begin();

  // Seed the random function with light sensor value
  randomSeed(CircuitPlayground.lightSensor());
}

///////////////////////////////////////////////////////////////////////////////
void loop() {
  // Wait for button press
  while (!CircuitPlayground.leftButton()   &amp;&amp; 
         !CircuitPlayground.rightButton())  {
    // Do nothing, just waiting for a button press...
  }

  // Print a random number
  Serial.println(random(1,7));

  // Debounce delay
  delay(500);
}
```

Load this code, open the Serial Monitor, and try again by pressing the buttons. Hopefully you get a different sequence this time, and it's different than the one I got.

![](https://cdn-learn.adafruit.com/assets/assets/000/037/858/medium800/circuit_playground_random_sequence2.png?1481064426)

While this isn't perfect, it will work for our needs. This is what we will use to generate the random number to simulate a dice roll

# Circuit Playground D6 Dice

## Dice Faces

A D6 dice has 6 different patterns of dots on each of its 6 faces to represent the values 1 through 6. We have 10 NeoPixels on our Circuit Playground, so we've got enough lights. We'll turn 1 light on for a roll of 1, 2 lights for 2, etc. We just need to come up with which NeoPixels to use.

The NeoPixel layout could be anything, but the following attempts to match the D6 dice face patterns as much as possible.

 **ROLL = 1**

NeoPixels: 2

![circuit_playground_d6_face_1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/037/861/medium640/circuit_playground_d6_face_1.jpg?1481066021)

 **ROLL = 2**

NeoPixels: 4, 9

![circuit_playground_d6_face_2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/037/862/medium640/circuit_playground_d6_face_2.jpg?1481066067)

 **ROLL = 3**

NeoPixels: 0, 4, 7

![circuit_playground_d6_face_3.jpg](https://cdn-learn.adafruit.com/assets/assets/000/037/863/medium640/circuit_playground_d6_face_3.jpg?1481066088)

 **ROLL = 4**

NeoPixels: 1, 3, 6, 8

![circuit_playground_d6_face_4.jpg](https://cdn-learn.adafruit.com/assets/assets/000/037/864/medium640/circuit_playground_d6_face_4.jpg?1481066180)

 **ROLL = 5**

NeoPixels: 0, 2, 4, 5, 9

![circuit_playground_d6_face_5.jpg](https://cdn-learn.adafruit.com/assets/assets/000/037/865/medium640/circuit_playground_d6_face_5.jpg?1481066214)

 **ROLL = 6**

NeoPixels: 0, 2, 4, 5, 7, 9

![circuit_playground_d6_face_6.jpg](https://cdn-learn.adafruit.com/assets/assets/000/037/866/medium640/circuit_playground_d6_face_6.jpg?1481066265)

# Storing the Face Patterns

Here's a simple approach for storing the above patterns of NeoPixels. The idea is to use a two dimensional (2D) array. The first dimension is simply the number of the roll, i.e. 1 through 6, so we'll need 6 entries. The second dimension of the array specifies the NeoPixels to light up for the dice roll. Since we are lighting up 1 NeoPixel per dice value, this will also need to have 6 entries.

So, we can do something like this:

```
uint8_t dicePixels[6][6] = {  // Pixel pattern for dice roll
  { 2, 0, 0, 0, 0, 0 } ,      // Roll = 1
  { 4, 9, 0, 0, 0, 0 } ,      //        2
  { 0, 4, 7, 0, 0, 0 } ,      //        3
  { 1, 3, 6, 8, 0, 0 } ,      //        4
  { 0, 2, 4, 5, 9, 0 } ,      //        5
  { 0, 2, 4, 5, 7, 9 } ,      //        6
};
```

You'll see this get used later in the final code.

# Circuit Playground D6 Dice

## Shake Detect

To roll a dice, you pick it up and shake it. Then you toss it down and see where it lands. We'll want to do this with our Circuit Playground dice as well. Let's see if we can use the accelerometer to sense when the Circuit Playground is being shaken.

For an overview of how the accelerometer works on the Circuit Playground, check out [this guide](../../../../how-tall-is-it/hello-accelerometer). You will see the following plot shown there.

![](https://cdn-learn.adafruit.com/assets/assets/000/037/867/medium800/circuit_playground_accelerometer_time_history1.png?1481066880)

What we are interested in is the **SHAKE IT UP!** part. That's where the Circuit Playground is being shaken. The lines are the return values from `motionX()`, `motionY()`, and `motionZ()`. This is a mess of positive and negative values with little hope of using simple logic to determine what is going on.

For detecting shaking, all we really care about is the magnitude of the acceleration. We don't care what direction it is being shaken. Therefore, we can use the total acceleration magnitude.

You can use the simple sketch below to try this out.

```
///////////////////////////////////////////////////////////////////////////////
// Circuit Playground Total Acceleration
//
// Author: Carter Nelson
// MIT License (https://opensource.org/licenses/MIT)

#include &lt;Adafruit_CircuitPlayground.h&gt;

float X, Y, Z, totalAccel;
  
///////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);

  CircuitPlayground.begin();
  CircuitPlayground.setAccelRange(LIS3DH_RANGE_8_G);
}

///////////////////////////////////////////////////////////////////////////////
void loop() {
  X = 0;
  Y = 0;
  Z = 0;
  for (int i=0; i&lt;10; i++) {
    X += CircuitPlayground.motionX();
    Y += CircuitPlayground.motionY();
    Z += CircuitPlayground.motionZ();
    delay(1);
  }
  X /= 10;
  Y /= 10;
  Z /= 10;

  totalAccel = sqrt(X*X + Y*Y + Z*Z);

  Serial.println(totalAccel);

  delay(100);
}
```

To smooth things out, we take 10 readings and average them. Then the total acceleration is computed with:

`totalAccel = sqrt(X*X + Y*Y + Z*Z);`

With the above sketch loaded and running on the Circuit Playground, open the Serial Plotter

**Tools -\> Serial Plotter**

and give the Circuit Playground a shake. You should see something like what is shown in the figure below.

![](https://cdn-learn.adafruit.com/assets/assets/000/037/869/medium800/circuit_playground_totalGs_time_hist.png?1481067953)

It still looks noisy, but if we pick an appropriate value for **ROLL\_THRESHOLD** , then we can detect shaking by simply comparing it to the total acceleration value.

The sketch below uses this idea to play a sound if it detects shaking.

```
///////////////////////////////////////////////////////////////////////////////
// Circuit Playground Shake Detect
//
// Author: Carter Nelson
// MIT License (https://opensource.org/licenses/MIT)

#include &lt;Adafruit_CircuitPlayground.h&gt;

#define ROLL_THRESHOLD  30 // Total acceleration threshold for roll detect

float X, Y, Z, totalAccel;

///////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);

  CircuitPlayground.begin();
  CircuitPlayground.setAccelRange(LIS3DH_RANGE_8_G);
}

///////////////////////////////////////////////////////////////////////////////
void loop() {
  // Compute total acceleration
  X = 0;
  Y = 0;
  Z = 0;
  for (int i=0; i&lt;10; i++) {
    X += CircuitPlayground.motionX();
    Y += CircuitPlayground.motionY();
    Z += CircuitPlayground.motionZ();
    delay(1);
  }
  X /= 10;
  Y /= 10;
  Z /= 10;

  totalAccel = sqrt(X*X + Y*Y + Z*Z);

  // Play sound if rolling
  if (totalAccel &gt; ROLL_THRESHOLD) {
    CircuitPlayground.playTone(800, 100);
  }
}
```

Play around with different values of **ROLL\_THRESHOLD**. If it's too low, the detect is too sensitive. If it's too high, you'll break your arm trying to get it to beep. The value of 30 in the above sketch seemed to work OK for me.

# Circuit Playground D6 Dice

## Tap Detect

After a lot of shaking, you might wear your arm out. So let's add another way to roll the dice. The accelerometer on the Circuit Playground has a built in tap detect function. Let's use that to allow the dice to be rolled by taping the Circuit Playground.

There are two library functions associated with this feature:

- `setAccelTap();`
- `getAccelTap();`

There are also a couple of example sketches that you can look at to explore the tap detect feature. You can access them via:

**File -\> Examples -\> Adafruit Circuit Playground -\> accelTap**

and

**File -\> Examples -\> Adafruit Circuit Playground -\> comm\_badge**

In each of these you will see something like this cryptic line:

```
attachInterrupt(digitalPinToInterrupt(7), myFunction, RISING);
```

This is setting up a function callback for an interrupt. This is somewhat of an advanced topic, but you can think of it as off loading the tap detection work to the accelerometer hardware. What the above line of code does is set things up so that when the accelerometer detects tap(s), the function `myFunction` will be called. It's up to you to create `myFunction` to do what you want, and the name can be any valid name.

If you look at the code in the **accelTap** example, you will see that there is no code in the `loop()` function. That's because the function `tapTime()` is being called via the interrupt.

You can still put code in the `loop()` function if you want. In fact, we'll be doing that for our D6 Dice. Here's another example that will be more like how we will use the tap detect for our dice. The callback function simply sets a flag. We then look for the state of that flag in `loop()`.

Info: 

```
///////////////////////////////////////////////////////////////////////////////
// Circuit Playground Tap Detect
//
// Author: Carter Nelson
// MIT License (https://opensource.org/licenses/MIT)

#include &lt;Adafruit_CircuitPlayground.h&gt;

#define TAP_THRESHOLD       10          // Tap detect threshold

bool tapDetected;

///////////////////////////////////////////////////////////////////////////////
void tapCallback() {
  tapDetected = true;
}

///////////////////////////////////////////////////////////////////////////////
void setup(void) {
  Serial.begin(9600);

  CircuitPlayground.begin();
  CircuitPlayground.setAccelRange(LIS3DH_RANGE_8_G);
  CircuitPlayground.setAccelTap(2, TAP_THRESHOLD);
  
  attachInterrupt(digitalPinToInterrupt(7), tapCallback, FALLING);

  tapDetected = false;
}

///////////////////////////////////////////////////////////////////////////////
void loop() {
  if (tapDetected) {
    Serial.println("TAP!");
    tapDetected = false;
  }
}
```

Note that we set up the detect for double tap by passing in a 2 in the `setup()` function:

```
CircuitPlayground.setAccelTap(2, TAP_THRESHOLD);
```

The way this works it that in the `loop()` function we look for a boolean value which is set to true in the interrupt callback function `tapCallback()`. This boolean is then set to false so that the print statement only happens once, until another double tap causes it to be true. Etc. Etc.

# Circuit Playground D6 Dice

## D6 Dice Code

OK, let's put all the pieces together. Here's the final D6 Dice code. With this code loaded and running on the Circuit Playground you can pick it up and shake it to make a roll. You can also just double tap it.

```
///////////////////////////////////////////////////////////////////////////////
// Circuit Playground D6 Dice
// 
// Roll them bones.
//
// Author: Carter Nelson
// MIT License (https://opensource.org/licenses/MIT)

#include &lt;Adafruit_CircuitPlayground.h&gt;

#define ROLL_THRESHOLD      30          // Total acceleration threshold for roll detect
#define TAP_THRESHOLD       10          // Tap detect threshold
#define DICE_COLOR          0xEA6292    // Dice digits color

unsigned long rollStartTime;
bool rolling;
bool newRoll;
bool tapDetected;
uint8_t rollNumber;
float X, Y, Z, totalAccel;

uint8_t dicePixels[6][6] = {  // Pixel pattern for dice roll
  { 2, 0, 0, 0, 0, 0 } ,      // Roll = 1
  { 4, 9, 0, 0, 0, 0 } ,      //        2
  { 0, 4, 7, 0, 0, 0 } ,      //        3
  { 1, 3, 6, 8, 0, 0 } ,      //        4
  { 0, 2, 4, 5, 9, 0 } ,      //        5
  { 0, 2, 4, 5, 7, 9 } ,      //        6
};

///////////////////////////////////////////////////////////////////////////////
void tapCallback() {
  tapDetected = true;
}

///////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);
  
  CircuitPlayground.begin();
  CircuitPlayground.setBrightness(100);
  CircuitPlayground.setAccelRange(LIS3DH_RANGE_8_G);
  CircuitPlayground.setAccelTap(2, TAP_THRESHOLD);
  
  // Setup tap detection and callback function
  attachInterrupt(digitalPinToInterrupt(7), tapCallback, RISING);
  
  // Seed the random function with light sensor value
  randomSeed(CircuitPlayground.lightSensor());

  // Initialize the global states
  newRoll = false;
  rolling = false;
  tapDetected = false;
}

///////////////////////////////////////////////////////////////////////////////
void loop() {
  // Compute total acceleration
  X = 0;
  Y = 0;
  Z = 0;
  for (int i=0; i&lt;10; i++) {
    X += CircuitPlayground.motionX();
    Y += CircuitPlayground.motionY();
    Z += CircuitPlayground.motionZ();
    delay(1);
  }
  X /= 10;
  Y /= 10;
  Z /= 10;

  totalAccel = sqrt(X*X + Y*Y + Z*Z);
  
  // Check for rolling
  if ((totalAccel &gt; ROLL_THRESHOLD) || tapDetected) {
    rollStartTime = millis();
    newRoll = true;
    rolling = true;
    tapDetected = false;
  }
  
  // Rolling momentum
  // Keep rolling for a period of time even after shaking has stopped.
  if (newRoll) {
    if (millis() - rollStartTime &gt; 1000) rolling = false;
  }

  // Compute a random number from 1 to 6
  rollNumber = random(1,7);

  // Display status on NeoPixels
  if (rolling) {
    // Make some noise and show the dice roll number
    CircuitPlayground.playTone(random(400,2000), 20, false);        
    CircuitPlayground.clearPixels();
    for (int p=0; p&lt;rollNumber; p++) {
      CircuitPlayground.setPixelColor(dicePixels[rollNumber-1][p], DICE_COLOR);
    }    
    delay(20);    
  } else if (newRoll) {
    // Show the dice roll number
    newRoll = false;
    CircuitPlayground.clearPixels();
    for (int p=0; p&lt;rollNumber; p++) {
      CircuitPlayground.setPixelColor(dicePixels[rollNumber-1][p], DICE_COLOR);
    }
  }
}
```

# Circuit Playground D6 Dice

## CircuitPython

The following pages go over creating the D6 Dice using [CircuitPython](../../../../adafruit-circuit-playground-express/arduino).

Info: 

# Circuit Playground D6 Dice

## Dice Faces

We'll reuse the same approach taken in the Arduino section for representing the dice roll using patterns of NeoPixels.

## Storing the Face Patterns

Here's a simple approach for storing the patterns of the NeoPixels for the dice rolls. We can use a dictionary, which is a storage class in CircuitPython that can store any amount of **values** which are accessed by using their associated **keys**. These are called key-value pairs, and a dictionary can hold any number of them. We will use the dice roll number as our key and then a tuple of NeoPixels values associated with the number to represent the dice face patterns.

Like this:

```
dice_pixels = {
 1 : (2,),
 2 : (4, 9),
 3 : (0, 4, 7),
 4 : (1, 3, 6, 8),
 5 : (0, 2, 4, 5, 9),
 6 : (0, 2, 4, 5, 7, 9)
}
```

You'll see this get used later in the final code.

# Circuit Playground D6 Dice

## Shake Detect

We can use the same approach for detecting shake as discussed in the Arduino section. See that section for a more complete discussion.

Here's a simple demonstration that will play a tone when shake is detected:

```
# Circuit Playground Express Shake Detect
#
# Author: Carter Nelson
# MIT License (https://opensource.org/licenses/MIT)
import time
import math
from adafruit_circuitplayground.express import cpx

# Total acceleration threshold
ROLL_THRESHOLD = 30

# Loop forever
while True:
    # Compute total acceleration
    X = 0
    Y = 0
    Z = 0
    for i in range(10):
        x, y, z = cpx.acceleration
        X = X + x
        Y = Y + y
        Z = Z + z
        time.sleep(0.001)
    X = X / 10
    Y = Y / 10
    Z = Z / 10
    
    total_accel = math.sqrt(X*X + Y*Y + Z*Z)
    
    # Play sound if rolling
    if total_accel &gt; ROLL_THRESHOLD:
        cpx.play_tone(800, 1)
```

Play around with different values of **ROLL\_THRESHOLD**. If it's too low, the detect is too sensitive. If it's too high, you'll break your arm trying to get it to beep. The value of 30 in the above sketch seemed to work OK for me.

## Or Just Use The Library

The shake detect approach above is so useful that it was added to the CircuitPython library for Circuit Playground Express. Under the hood, it's doing the exact same thing. But now the code becomes as simple as:

```
# Circuit Playground Express Shake Detect Using Library
#
# Author: Carter Nelson
# MIT License (https://opensource.org/licenses/MIT)
from adafruit_circuitplayground.express import cpx

# Loop forever
while True:
    # Play sound if rolling
    if cpx.shake(): 
        cpx.play_tone(800, 1)
```

Running that should work just like the first example. But now the code is much more readable. Sweet.

# Circuit Playground D6 Dice

## D6 Dice Code

Here is the CircuitPython version of the D6 dice code. With this code loaded and running on the Circuit Playground Express you can pick it up and shake it to make a roll. You can also just double tap it.

```
# Circuit Playground Express D6 Dice
# 
# Roll them bones.
#
# Author: Carter Nelson
# MIT License (https://opensource.org/licenses/MIT)
import time
import random
from adafruit_circuitplayground.express import cpx

ROLL_THRESHOLD  = 30        # Total acceleration 
DICE_COLOR      = 0xEA6292  # Dice digits color

dice_pixels = {
 1 : (2,),
 2 : (4, 9),
 3 : (0, 4, 7),
 4 : (1, 3, 6, 8),
 5 : (0, 2, 4, 5, 9),
 6 : (0, 2, 4, 5, 7, 9)
}

# Configure double tap detection
cpx.detect_taps = 2

# Seed the random function with light sensor value
# (try commenting this out and see if it matters)
random.seed(cpx.light)

# Initialize the global states
new_roll = False
rolling = False

# Loop forever
while True:
    # Check for rolling
    if cpx.shake() or cpx.tapped:
        roll_start_time = time.monotonic()
        new_roll = True
        rolling = True
        
    # Rolling momentum
    # Keep rolling for a period of time even after shaking stops
    if new_roll:
        if time.monotonic() - roll_start_time &gt; 1:
            rolling = False
    
    # Compute a random number from 1 to 6
    roll_number = random.randrange(1,7)
    
    # Display status on NeoPixels
    if rolling:
        # Make some noise and show the dice roll number
        cpx.start_tone(random.randrange(400,2000))
        cpx.pixels.fill(0)
        for p in dice_pixels[roll_number]:
            cpx.pixels[p] = DICE_COLOR
        time.sleep(0.02)
        cpx.stop_tone()
    elif new_roll:
        # Show the dice roll number
        new_roll = False
        cpx.pixels.fill(0)
        for p in dice_pixels[roll_number]:
            cpx.pixels[p] = DICE_COLOR
```

# Circuit Playground D6 Dice

## Questions and Code Challenges

The following are some questions related to this project along with some suggested code challenges. The idea is to provoke thought, test your understanding, and get you coding!

While the sketches provided in this guide work, there is room for improvement and additional features. Have fun playing with the provided code to see what you can do with it.

# Questions

- Why do you think it was necessary to call the `setAccelRange()` function in `setup()`? (hint: 1G = 9.8 m/s<sup>2</sup>)
- Can you think of a way to cheat the dice? (hint: think about that seed)

# Code Challenges

- Come up with your own NeoPixel patterns for the dice face numbers.
- Change the dice color.
- Change the double tap to a single tap.
- Can you turn the 6-sided die into a _10_ sided die?


## Featured Products

### Circuit Playground Express

[Circuit Playground Express](https://www.adafruit.com/product/3333)
 **Circuit Playground Express** is the next step towards a perfect introduction to electronics and programming. We've taken the original Circuit Playground Classic and made it even better! Not only did we pack even more sensors in, we also made it even easier to...

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

[Circuit Playground Classic](https://www.adafruit.com/product/3000)
Would you like to learn electronics, with an all-in-one board that has sensors and LEDs built in? **Circuit Playground** is here - and it's the best way to practice programming on real hardware with no soldering or sewing required!

This is the **Classic**...

In Stock
[Buy Now](https://www.adafruit.com/product/3000)
[Related Guides to the Product](https://learn.adafruit.com/products/3000/guides)
### 3 x AAA Battery Holder with On/Off Switch and 2-Pin JST

[3 x AAA Battery Holder with On/Off Switch and 2-Pin JST](https://www.adafruit.com/product/727)
This battery holder connects 3 AAA batteries together in series for powering all kinds of projects. We spec'd these out because the box is slim, and 3 AAA's add up to about 3.3-4.5V, a very similar range to Lithium Ion/polymer (Li-Ion) batteries and have an on-off switch. That makes...

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

## Related Guides

- [Introducing Circuit Playground](https://learn.adafruit.com/introducing-circuit-playground.md)
- [Adafruit Circuit Playground Express](https://learn.adafruit.com/adafruit-circuit-playground-express.md)
- [Combo Dial Safe with Circuit Playground Express](https://learn.adafruit.com/combo-dial-safe-with-circuit-playground-express.md)
- [Light Paintbrush with Circuit Playground](https://learn.adafruit.com/lightpaint-cplay.md)
- [Halloween Sentry-Bot with CRICKIT for CPX](https://learn.adafruit.com/halloween-sentry-bot.md)
- [Sparky the Blue Smoke Monster Automaton](https://learn.adafruit.com/sparky-automaton.md)
- [Circuit Playground Express Spinner Game in MakeCode](https://learn.adafruit.com/circuit-playground-makecode-spinner-game.md)
- [No-Touch Hand Wash Timer for Circuit Playground Express and CLUE](https://learn.adafruit.com/no-touch-hand-wash-timer-for-cpx-and-clue.md)
- [Easy Sparkle Pocket T-Shirt](https://learn.adafruit.com/easy-sparkle-pocket-t-shirt.md)
- [UFO Flying Saucer with Circuit Playground Express](https://learn.adafruit.com/ufo-circuit-playground-express.md)
- [MakeCode Course for Circuit Playground Express](https://learn.adafruit.com/makecode-circuit-playground-express-course.md)
- [Glowing Slime Lunchbox](https://learn.adafruit.com/glowing-slime-lunchbox.md)
- [Jack-o-Theremin](https://learn.adafruit.com/jack-o-theremin.md)
- [Circuit Playground Morse Code Flasher](https://learn.adafruit.com/circuitplayground-morse-code-flasher-makecode-circuit-python.md)
- [Circuit Playground Express Head-Tilt Ears](https://learn.adafruit.com/circuit-playground-express-head-tilt-ears.md)
- [Light Up Paper Dragon Wall Sconce](https://learn.adafruit.com/light-up-paper-dragon-wall-sconce.md)
- [Circuit Playground Digital Input](https://learn.adafruit.com/circuit-playground-digital-input.md)
