We'll use Microsoft's drag-and-drop code editor to create the magic. MakeCode is an easy way to get up and running with the Circuit Playground Express. No prior coding knowledge is needed, and it's an easy way to experiment and learn to think like a coder.
To get started, go to makecode.adafruit.com and then choose New Project. You'll find yourself in the MakeCode Editor. From here, you can click on any of the colored tabs and drag blocks of code onto your workspace, then preview it using the Circuit Playground Express pictured on the left.
Once your code is written, plug your Circuit Playground Express into your computer via its USB port and click the "reset" button. All the lights will turn green and your Circuit Playground will appear as a drive on your computer called CPLAYBOOT. Simply drag your downloaded code onto this drive to program the Circuit Playground Express. Easy!
Head over to this Intro to MakeCode guide for more info on getting started with MakeCode.
If you want to skip right to the end and work backwards, here's the completed MakeCode project.
Set Up the Lights
First, let's tell the Circuit Playground that we have a strand of lights wired up to pin A1. We'll also set the brightness of our lights.
Click on the "Loops" tab and drag an instance of
on start onto the workspace. Anything inside this bracket will happen just once, when the Circuit Playground is powered up.
Click on the "Light" tab and find
set brightness 0and drag it out into your
on start loop. Set the brightness to something moderate, maybe 140. This will set the brightness of the lights on the front of the Circuit Playground Express.
Click on the LIGHT tab again, and the NEOPIXEL tab will appear right under it. From NEOPIXEL, drag an instance of
set strip to create stripinto your
on start loop.
+ next to create strip and MakeCode will add some modifiers. Be sure
A1 is selected (since that's the pad we soldered our lights to), then click the next
+ to expand the tab further, giving you the option to specify how many pixels are in your strip.
It's good practice to make this number a variable. That way if you decide to change the number of pixels in your strip later on, or if we want to reference it later in the code, we can do so easily.
Click the VARIABLES tab and make a new variable. Call it
numpixels. Drag it out into your workspace and into the
create strip instance, replacing the
Drag an instance of
set numpixels to 0 into your
on start loop above
set strip. Enter the number of pixels you've added to your project -- I have 7.
Then, go back to your NEOPIXELS tab (under the LIGHTS tab) and drag an instance of
strip set brightness
0. Change this to
Each time we "drop" a magic light into the bag, we want one light to turn on. We've got ten lights on the face of the Circuit Playground, and seven more spread out along the inside of the bag. But if we used all ten of the Circuit Playground's lights, it wouldn't look quite right. Dropping random lights into a bag would never light up a perfect circle! So we'll just use a few of the Circuit Playground's lights, to make it seem more random and jumbled, and then move on to our light strip.
Decide how you want to trigger your effect. You can use the buttons on the face of the Circuit Playground, or the capacitive touch pads around the edge. Capacitive touch works great with sheer fabric, but if you're using fun fur, the fabric is too thick to trigger the capacitive touch -- so maybe not the best option in this case. You could also use the "tilt" or "shake" features. It's all dependent on your magician's flair and style. You could even use multiple triggers to make it even more mysterious!
I decided to use "shake" -- so each time I shake the bag, another light will appear.
First we need to create a couple more variables. Go to your VARIABLES tab and create a variable called
nextlight. We'll use this one to refer to the lights on the strip. Create one more called
nextcplight. We'll use this one to refer to the lights on the Circuit Playground Express.
From the INPUT tab, drag an instance of
on shake (or whatever your preferred trigger is) onto the workspace. From the LIGHT tab, drag
set pixel color at 0 to red into this loop. Then go grab the
nextcplight variable you just made and drag it into this block to replace the
0. Finally, change the color to whatever color you'd like the light to be. My magic thumb tip is red, so I'll leave mine red.
Now we'll add some code that changes the variable
nextcplight to refer to a different light. I want to use just 3 of the Circuit Playground Express' lights (to avoid the perfect circle look), so I'll tell it to start at light 1 and then skip ahead lights -- so we'll light up pixels 1, 4, and 7.
Go to the VARIABLES tab and drag an instance of
set nextcplight to 0 into your
on start loop. Set this to
1. Then drag an instance of
change nextcplight by 1 into your on shake loop and set this to
Try downloading the code and see if it works. Plug your Circuit Playground Express into your computer and press the reset button. Drag the downloaded code file onto the CPLAYBOOT drive that appears. Try shaking / triggering your effects and watch your lights come on.
Now let's do the same thing for the light strip. We want to use the same trigger (on shake) but we don't want these lights to come on until all three lights on the Circuit Playground face have come on. We'll need to add a conditional statement (if/then) to make this work.
Under the LOGIC tab, drag an
if true then loop into your
on shake loop. Then drag a comparison block to replace the
Change the first
0 in the comparison block to your
nextcplight variable. Then change the second
12 (because we're counting by 3s, remember?). Finally, change the operator
> (greater than). Now the code means "if the last light-number we lit is greater than the number of lights onboard the Circuit Playground Express, move on to the next thing".
The next thing is to light the lights on your LED strip. So let's repeat the same idea, only using the blocks and values that will work for our strip.
strip set pixel color at 0 to red under the NEOPIXEL tab. (Remember, the NEOPIXEL tab will change your light strip, whereas the LIGHT tab changes the lights on the face of the Circuit Playground Express).
Drag in your
nextlight variable (the one we made to refer to the light strip), and a
change nextlight by 0 block from the VARIABLES tab. Change the
0 to a
1 to light up the lights sequentially.
Try downloading this code again and see if it works the way you want.
Hooray! We've gotten the bag to fill up with magic lights each time it's shaken. Now let's add a function that makes it appear to empty out when we're done.
We'll use the "tilt" input for this part. I want the bag to empty out when I turn it completely upside down, so the "tilt down" input is the one I'll use.
You could also make it trigger with a loud sound, a fast swing, or if you shine a bright light at the outside of the bag. So many possibilities!
Drag another instance of
on shake to your workspace, and change the input to
tilt down. Under LOOPS, drag an instance of
repeat 4 times into this loop. Change
4 to a number about twice as big as your total number of lights. I have 10 lights total (3 on the Circuit Playground Express and 7 in my strip) so I chose 20.
From LIGHT drag an instance of
set pixel color at 0 to red, and from NEOPIXEL drag an instance of
strip set pixel color at 0 to red. Change both to black -- this will turn the pixels off.
Then, we'll add some randomness so the lights go off in a random order. Under the MATH tab, drag two instances of
pick random 0 to 10 and replace both the
0s in the previous two blocks. For the
strip block, change the 10 to your
numpixels variable (remember, that is defined as the number of pixels in your strip). For the other, we can leave it as
10 since there are 10 NeoPixels on the face of the Circuit Playground Express.
Then we'll slow it down a little. Drag an instance of
pause 100ms from the LOOPS tab. You can change this variable to something pleasing -- I chose
15ms for a fairly quick-fire emptying animation.
Let's add a failsafe just in case the random numbers don't turn all the lights off. After the
repeat loop, drag an instance of
set all pixels to red and
strip set all pixels to red, and change both to
black. This will make sure every single light gets turned off, and none appear to get "stuck" in the bag.
One last thing to add! We want the trick to reset itself after the bag is emptied out, so you can immediately fill it again. To do this, we have to reset the
nextcplight variables back to their original state of
1. Do this in the
on tilt down loop, OUTSIDE the
repeat loop, so the animation finishes before the variables get reset.