[{"element_type":"text","content":"\n  \n  \n  \n        \u003cp\u003eAdd more fun to your board games by creating an electronic die!\u003c/p\u003e\n      \n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/897/original/img0004.gif?1717115245","metadata":{"caption":"Rolling... my first gif from my Memento!"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eMy grandkids love to play Monopoly, but sometimes they get a little carried away rolling the die. More than once the die goes skittering across the floor, sometimes never to be found. Since I've been learning to code with CircuitPython on a Raspberry Pi Pico, along with the magic of 3D printing, I thought building an electronic die for the game would be a great project to put all the skills together.\u003c/p\u003e\n\u003cp\u003eThe design concept was a 3D printed cube with 9 holes to slot in the LEDs, a tilt switch to trigger a roll, a piezo element to add a bit of sound, all run on a Raspberry Pi Pico powered by 3 AAA batteries. Using random function to generate a random integer between 1 and 6 would nicely emulate the single die used in the game. I also added a couple of specials - read on for more on those!\u003c/p\u003e\n\u003cp\u003eConsidering the size of the components that would need to fit inside the cube I decided to make a 70x70mm cube 85mm tall. Since the top face would be about 50x50mm, using 10mm jumbo LEDs made the most sense.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eParts\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eHere are the electronic components used:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/4864","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/4204","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/173","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/1739","metadata":{}},{"element_type":"parts","content":"\n  \u003cdiv class=\"parts-details\"\u003e\n    \u003cdiv\u003e\n      \u003cspan class=\"parts-quantity\"\u003e9\u003c/span\u003e\u003cspan\u003e x \u003c/span\u003e\n        \u003cspan class=\"parts-name\"\u003eResistor\u003c/span\u003e\n      \u003cdiv class=\"parts-description\"\u003e330 ohm through-hole resistor\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"parts-action\"\u003e\n  \u003cdiv\u003e\n\n  \u003c/div\u003e\n\u003c/div\u003e\n\n  \u003cdiv class=\"clearfix\"\u003e\u003c/div\u003e\n","metadata":{"name":"Resistor","url":null,"description":"330 ohm through-hole resistor","quantity":"9"}},{"element_type":"parts","content":"\n  \u003cdiv class=\"parts-details\"\u003e\n    \u003cdiv\u003e\n      \u003cspan class=\"parts-quantity\"\u003e2\u003c/span\u003e\u003cspan\u003e x \u003c/span\u003e\n        \u003cspan class=\"parts-name\"\u003eSlide Switch\u003c/span\u003e\n      \u003cdiv class=\"parts-description\"\u003eDPDT with mounting ears + 2mm screws\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"parts-action\"\u003e\n  \u003cdiv\u003e\n\n  \u003c/div\u003e\n\u003c/div\u003e\n\n  \u003cdiv class=\"clearfix\"\u003e\u003c/div\u003e\n","metadata":{"name":"Slide Switch","url":null,"description":"DPDT with mounting ears + 2mm screws","quantity":"2"}},{"element_type":"parts","content":"\n  \u003cdiv class=\"parts-details\"\u003e\n    \u003cdiv\u003e\n      \u003cspan class=\"parts-quantity\"\u003e1\u003c/span\u003e\u003cspan\u003e x \u003c/span\u003e\n        \u003cspan class=\"parts-name\"\u003eBattery Holder\u003c/span\u003e\n      \u003cdiv class=\"parts-description\"\u003e3x AAA battery holder\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"parts-action\"\u003e\n  \u003cdiv\u003e\n\n  \u003c/div\u003e\n\u003c/div\u003e\n\n  \u003cdiv class=\"clearfix\"\u003e\u003c/div\u003e\n","metadata":{"name":"Battery Holder","url":null,"description":"3x AAA battery holder","quantity":"1"}},{"element_type":"parts","content":"\n  \u003cdiv class=\"parts-details\"\u003e\n    \u003cdiv\u003e\n      \u003cspan class=\"parts-quantity\"\u003e1\u003c/span\u003e\u003cspan\u003e x \u003c/span\u003e\n        \u003cspan class=\"parts-name\"\u003eProto Perf Board\u003c/span\u003e\n      \u003cdiv class=\"parts-description\"\u003e50mm square - cut down from a larger piece of board\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"parts-action\"\u003e\n  \u003cdiv\u003e\n\n  \u003c/div\u003e\n\u003c/div\u003e\n\n  \u003cdiv class=\"clearfix\"\u003e\u003c/div\u003e\n","metadata":{"name":"Proto Perf Board","url":null,"description":"50mm square - cut down from a larger piece of board","quantity":"1"}},{"element_type":"parts","content":"\n  \u003cdiv class=\"parts-details\"\u003e\n    \u003cdiv\u003e\n      \u003cspan class=\"parts-quantity\"\u003e15\u003c/span\u003e\u003cspan\u003e x \u003c/span\u003e\n        \u003cspan class=\"parts-name\"\u003eWire\u003c/span\u003e\n      \u003cdiv class=\"parts-description\"\u003e30 ga silicon hook-up wire - ~6\" pieces\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"parts-action\"\u003e\n  \u003cdiv\u003e\n\n  \u003c/div\u003e\n\u003c/div\u003e\n\n  \u003cdiv class=\"clearfix\"\u003e\u003c/div\u003e\n","metadata":{"name":"Wire","url":null,"description":"30 ga silicon hook-up wire - ~6\" pieces","quantity":"15"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u003cstrong\u003eConnecting the Electronics\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eThe cathodes of the 9 LEDs are tied to a common ground connected to pin 3 of the Pico. The anodes of the LEDs are connected to GPIOs 0-8 (pins 1, 2, 4, 5, 6, 7, 9, 10, 11) through 330 ohm current limiting resistors.\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eThe LED pips are wired and arranged:\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/904/original/pips.png?1717129007","metadata":{"caption":"What's with rolling a 7, 8 or 9?"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThe piezo element is connected to GP13 (pin 17) and a ground pin. The tilt switch is connected to GP26 (pin 31) and the other side to a ground pin. Positive side of the battery is connected through one side of the slide switch to VBUS (pin 40) with the other side to ground (I know, I know there should be a Schottky diode in there).\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eI made two other connections for the special features I planned to add: I used the second slide switch to connect GP9 (pin 12) to a ground pin when the switch is on. I then used the other side of the power slide switch to connect GP15 (pin 20) to a ground pin when power is one. More on these later.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u003cstrong\u003e3D Case Design\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eI used TinkerCad (\u003ca href=\"https://www.tinkercad.com\"\u003ehttps://www.tinkercad.com\u003c/a\u003e) for my 3D design work. The original thought was to make two halves - a top and bottom that overlap/slide together. but I ran into some difficulties with this design. Ultimately, I broke it down into 3 parts - an outer 70x70x85mm cube with a 50mm square \"hole\" through the middle. Then I made two 50mm cubes for the top and bottom that mate open end to open end and slide into center of the cube. The heights of each are one half the depth of the cube so when assembled the closed ends are flush with the top and bottom of the cube. The top has the 9 holes which just fit the 10mm LEDs. The bottom had places to support the Pico and battery back with cut-outs for the slide switches and the USB connector on the Pico.\u003c/p\u003e\n\u003cp\u003eHere are what the three parts look like in TinkerCad:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/901/original/Dice_TC.png?1717118243","metadata":{"caption":"Three cube parts displayed in TinkerCad"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eSome design notes:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eThe top of the cube (yellow, top facing down) has a bevel. This matches the:\u003c/li\u003e\n\u003cli\u003eLED top section (pink) bevel - this keeps the top from sliding through the outer cube.\u003c/li\u003e\n\u003cli\u003eThe bottom layer of the bottom section (tan) is about 4mm thick. The switches are about 4mm tall, so they would be flush with the bottom, except in order to make one switch more prominent (the power switch) I carved out about 1mm so that switch protrudes about 1mm below the bottom.\u003c/li\u003e\n\u003cli\u003eThere is a box just large enough to squeeze in the battery holder keeping it firmly in the place in the assembled cube.\u003c/li\u003e\n\u003cli\u003eOn the outside of the battery holder box is a shallow half-box which supports the Pico vertically, with the USB facing downward. The box is about 5mm wider than the Pico itself so there is room for the wiring to extend bast the edge of the board connected to the GPIO pins. The wired Pico is hot-glued to the support plate to keep it firmly in place when connecting a USB cable.\u003c/li\u003e\n\u003cli\u003eThere is also 4mm groove in the base to allow the Pico's USB port to sit only 1mm above the bottom so a cable can be plugged in the assembled cube for updating the code without having to disassemble the cube.\u0026nbsp;\u003c/li\u003e\n\u003c/ul\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/910/original/IMG_7903.jpg?1717190412","metadata":{"caption":"Close up of slot to allow the Pico to have the USB sit flush with the base"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u003cstrong\u003eAssembly\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eFirst, since the tilt switch is best positioned on the LED side of the perf board (so it is upright/closed when the cube is sitting upright), I put the leads through approximately where it will be between P1, P2, P6 and P8. This is important to know the minimum distance needed between the perf board and the bottom of the LEDs.\u003c/p\u003e\n\u003cp\u003eThe challenge is getting the LEDs arranged with the leads through the perf board in the right places. I found the best way to do this was to invert the top shell section on the workbench and insert the LEDs backwards with the leads facing upward. Then center the perf board and guide the LED leads through the best fitting holes. I actually did this one LED at a time starting in the center and tacking each LED cathode lead to the perf board. This helps with the horizontal spacing but also watch the vertical spacing so the perf board is level across all of the LEDs. I actually 3D printed a jig (3x3 square grid the depth I wanted the LEDs at) which helped a lot.\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/905/original/AlignLED.jpg?1717189072","metadata":{"caption":"Using the top cube to align the LEDs to the appropriate perf board holes"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eOnce the perf board is in place, connect all of the cathodes and one side of the tilt switch to a common ground pin and solder a 330 ohm resistor to each anode. I used 30ga silicone hook-up wire (the silicone is much easier to work with due to its flexibility) to connect the resistors to the appropriate GPIO pins as well as the tilt switch and the perf board common ground. Once the perf board is all wired, a couple of dabs of hot glue around the edge holds the board in place in the top section, Keep in mind that kids will be poking at the LEDs so this board needs to be anchored pretty firmly.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/906/original/IMG_7894.jpg?1717189350","metadata":{"caption":"Fully assembled LEDs with resistors and tilt switch on the perf board"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThe rest of the connections are in the base cube. The battery holder positive goes to one side of the slide switch and the negative goes to a ground pin. The other connection on the power side of the switch got to VBUS (pin 40). On the other side of the power switch run one connection to GP15 (pin 20) and the other side to ground so that when the power switch is in the on position GP15 is connected to ground.\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/907/original/IMG_7893.jpg?1717189979","metadata":{"caption":"Everything wired up and ready to be put together"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eFor the other slide switch connect one lead to ground and the other lead to GP9 (pin12) so that when this side is on GP9 is grounded. The slide switches are held on to the base with 2mm screws. I used a 2mm tap to make threads however it also works just to force the screws in and they will easily cut their own threads in the PLA.\u003c/p\u003e\n\u003cp\u003eFinally connect the piezo element to ground and GP13 (pin 17).\u003c/p\u003e\n\u003cp\u003eThat's all the connections!\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/908/original/IMG_7897.jpg?1717190038","metadata":{"caption":"Stacked inner cubes slide into the outer cube"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eStack the two inner cubes and then slide them into the outer cube. Apply a few dabs of hot glue to the corners on the bottom to keep the inner cubes from sliding out of the outer cube.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/909/original/IMG_7902_%281%29.jpg?1717190302","metadata":{"caption":"Assembled cube"}},{"element_type":"text","content":"\n  \n  \n        \u003cp\u003e\u003cstrong\u003eSpecial Features\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eSometimes when playing the game the kids get a little bored or they feel cheated when rolling a low number. Since we can make our own rules, I thought I'd add a bit of fun by randomly adding some special rolls. This is the purpose of the second switch. Set the switch to normal and you get a roll of 1 to 6. \u003cspan\u003eWhen the special switch is set, the random number generator chooses a number between 1 and 7. With a little magic in the code, if a 7 comes up, a second random number is generated, and if that is greater than a threshold (in the code it is 1 in 4 chance), the roll can be a 7, 8, or 9! Extra pips light and a little ditty plays to announce they got something special. At the other end of the spectrum, if the player rolls a 1 or a 2, there is a 1 in 20 chance the cube will play Happy Birthday and the player can roll again.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan\u003eThe other special feature I added was not so much in game play but a data logger to track the rolls over time, so that we can check how random the rolls are (interestingly so far that data seems to support a pretty even distribution). Collection of the roll results is accomplished using the data logger approach saving each roll in a text file logger.txt. The technique used comes from this Learn Guide:\u003c/span\u003e\u003c/p\u003e\n      \n\n","metadata":{}},{"element_type":"guide","content":"https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython/data-logger","metadata":{"guide_id":"3230","page_id":"21426"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eIn the boot.py file you specify GP15 (pin 20) as the write-enable pin. Using the power switch to make this connection only when it is powered on from the battery means that when the power is off (and you connect to your PC through the bottom with a USB cable) the write protect will be disabled and you will be able to read the text file and alter the code on your board.\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"alert","content":"\u003cp\u003eSince the battery is connected directly to VBUS, only connect your cube with a USB cable when the power switch is in the off position. If connected when the power switch is on you will be connecting the internal AAA batteries to 5v power and bad things will probably happen! Plus, when the power switch is in the on position you cannot read or write to the Pico anyway.\u003c/p\u003e","metadata":{"class":"element row-fluid alert-element build-alert alert-danger","markdown":"Since the battery is connected directly to VBUS, only connect your cube with a USB cable when the power switch is in the off position. If connected when the power switch is on you will be connecting the internal AAA batteries to 5v power and bad things will probably happen! Plus, when the power switch is in the on position you cannot read or write to the Pico anyway.","alert_type":"danger"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u003cstrong\u003eCoding\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eAt this point you are ready to add the code. We will create three files:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eboot.py\u003c/strong\u003e - to enable/disable data logging\u003c/li\u003e\n\u003cli\u003e\n\u003cstrong\u003ecode.py\u003c/strong\u003e - the main program code\u003c/li\u003e\n\u003cli\u003e\n\u003cstrong\u003enote_freq.py\u003c/strong\u003e - placed in the lib folder, this file defines the frequency of the notes and durations. Although this can be added to code.py, I thought this would be a good use to break out in a separate file and import at the top of the program to neaten things up a bit.\u0026nbsp;\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFirst let's start with \u003cstrong\u003eboot.py\u003c/strong\u003e:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"code","content":"# This file uses GP15 to write protect the board to allow data logging\n\nimport board\nimport digitalio\nimport storage\n\nwrite_pin = digitalio.DigitalInOut(board.GP15)\nwrite_pin.direction = digitalio.Direction.INPUT\nwrite_pin.pull = digitalio.Pull.UP\n\nif not write_pin.value:\n    storage.remount(\"/\", readonly=False)","metadata":{"language":"auto","linenums":false}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eNext let's add the library file \u003cstrong\u003enote_freq.py\u003c/strong\u003e for note values. This is saved in the lib folder:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"code","content":"# Notes class assigns frequencies for musical notes used to produce tones by the piezo element.\n# Dur class sets the duration of the notes\n\nclass Notes:\n    B0 = 31\n    C1 = 33\n    CS1 = 35\n    D1 = 37\n    DS1 = 39\n    E1 = 41\n    F1 = 44\n    FS1 = 46\n    G1 = 49\n    GS1 = 52\n    A1 = 55\n    AS1 = 58\n    B1 = 62\n    C2 = 65\n    CS2 = 69\n    D2 = 73\n    DS2 = 78\n    E2 = 82\n    F2 = 87\n    FS2 = 93\n    G2 = 98\n    GS2 = 104\n    A2 = 110\n    AS2 = 117\n    B2 = 123\n    C3 = 131\n    CS3 = 139\n    D3 = 147\n    DS3 = 156\n    E3 = 165\n    F3 = 175\n    FS3 = 185\n    G3 = 196\n    GS3 = 208\n    A3 = 220\n    AS3 = 233\n    B3 = 247\n    C4 = 262\n    CS4 = 277\n    D4 = 294\n    DS4 = 311\n    E4 = 330\n    F4 = 349\n    FS4 = 370\n    G4 = 392\n    GS4 = 415\n    A4 = 440\n    AS4 = 466\n    B4 = 494\n    C5 = 523\n    CS5 = 554\n    D5 = 587\n    DS5 = 622\n    E5 = 659\n    F5 = 698\n    FS5 = 740\n    G5 = 784\n    GS5 = 831\n    A5 = 880\n    AS5 = 932\n    B5 = 988\n    C6 = 1047\n    CS6 = 1109\n    D6 = 1175\n    DS6 = 1245\n    E6 = 1319\n    F6 = 1397\n    FS6 = 1480\n    G6 = 1568\n    GS6 = 1661\n    A6 = 1760\n    AS6 = 1865\n    B6 = 1976\n    C7 = 2093\n    CS7 = 2217\n    D7 = 2349\n    DS7 = 2489\n    E7 = 2637\n    F7 = 2794\n    FS7 = 2960\n    G7 = 3136\n    GS7 = 3322\n    A7 = 3520\n    AS7 = 3729\n    B7 = 3951\n    C8 = 4186\n    CS8 = 4435\n    D8 = 4699\n    DS8 = 4978\n\nclass Dur:\n    e = .1  # eighth note\n    q = .2  # quarter note\n    h = .4  # half note\n    w = .8  # whole note","metadata":{"language":"auto","linenums":false}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eFinally, the main code in \u003cstrong\u003ecode.py:\u003c/strong\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"code","content":"import time\nimport random\nimport digitalio\nimport board\nimport pwmio\nfrom note_freq import Notes\nfrom note_freq import Dur\n\nbuzzer1 = pwmio.PWMOut(board.GP13, variable_frequency=True) # set the piezo up on GP13\nOFF = 0  # pwm duty cycle when piezo is silent\nON = 2 ** 15  # pwm duty cycle when piezo is sounding - 50% \nph = 0.003  # short sleep time used in phaser sound effect\nraf = 20  # roll again factor - if 1 or 2 comes up, how ofter will the player be chosen to roll again. Factor of 20 is a 1 in 20 chance\n\n# Set up the LEDs for the pips\n\np1 = digitalio.DigitalInOut(board.GP0)\np1.direction = digitalio.Direction.OUTPUT\n\np2 = digitalio.DigitalInOut(board.GP1)\np2.direction = digitalio.Direction.OUTPUT\n\np3 = digitalio.DigitalInOut(board.GP3)\np3.direction = digitalio.Direction.OUTPUT\n\np4 = digitalio.DigitalInOut(board.GP2)\np4.direction = digitalio.Direction.OUTPUT\n\np5 = digitalio.DigitalInOut(board.GP4)\np5.direction = digitalio.Direction.OUTPUT\n\np6 = digitalio.DigitalInOut(board.GP5)\np6.direction = digitalio.Direction.OUTPUT\n\np7 = digitalio.DigitalInOut(board.GP6)\np7.direction = digitalio.Direction.OUTPUT\n\np8 = digitalio.DigitalInOut(board.GP7)\np8.direction = digitalio.Direction.OUTPUT\n\np9 = digitalio.DigitalInOut(board.GP8)\np9.direction = digitalio.Direction.OUTPUT\n\n# set up the tilt switch\n\nroll = digitalio.DigitalInOut(board.GP26)\nroll.direction = digitalio.Direction.INPUT\nroll.pull = digitalio.Pull.UP\n\n# set up the special switch - when low special fetures are enabled\n\nspecial = digitalio.DigitalInOut(board.GP9)\nspecial.direction = digitalio.Direction.INPUT\nspecial.pull = digitalio.Pull.UP\n\n# define functions \n\ndef bn(): # stops the piezo sounding\n    buzzer1.duty_cycle = OFF\n    time.sleep(0.05)\n\ndef hbd(d):  # Happy Birthday melody when a player rolls a 1 or 2 and is selected to roll again\n    x = 0\n    while x \u003c d:\n        buzzer1.frequency = Notes.G5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.q)\n        bn()\n        buzzer1.frequency = Notes.G5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.q)\n        bn()\n        buzzer1.frequency = Notes.A5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.G5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.C6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.B5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.w)\n        bn()\n        bn()\n        buzzer1.frequency = Notes.G5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.q)\n        bn()\n        buzzer1.frequency = Notes.G5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.q)\n        bn()\n        buzzer1.frequency = Notes.A5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.G5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.D6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.C6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.w)\n        bn()\n        bn()\n        buzzer1.frequency = Notes.G5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.q)\n        bn()\n        buzzer1.frequency = Notes.G5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.q)\n        bn()\n        buzzer1.frequency = Notes.G6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.E6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.C6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.B5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.A5\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.w)\n        bn()\n        bn()\n        buzzer1.frequency = Notes.F6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.q)\n        bn()\n        buzzer1.frequency = Notes.F6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.q)\n        bn()\n        buzzer1.frequency = Notes.E6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.C6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.D6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.h)\n        bn()\n        buzzer1.frequency = Notes.C6\n        buzzer1.duty_cycle = ON\n        time.sleep(Dur.w)\n        bn()\n        x = x + 1\n        buzzer1.duty_cycle = OFF\n        time.sleep(0.25)\n\n\ndef gliss(g, d):  # glissando sound effect\n    x = 0\n    while x \u003c d:\n        buzzer1.frequency = Notes.C4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.D4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.E4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.F4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.G4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.A4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.B4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.C5\n        buzzer1.duty_cycle = ON\n        time.sleep(g * 4)\n        x = x + 1\n        buzzer1.duty_cycle = OFF\n        time.sleep(g * 2)\n\ndef mjr(g, d):  # major chord sound effect\n    x = 0\n    while x \u003c d:\n        buzzer1.frequency = Notes.C5\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.E5\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.G5\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.C6\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.C5\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.C6\n        buzzer1.duty_cycle = ON\n        time.sleep(g * 4)\n        x = x + 1\n        buzzer1.duty_cycle = OFF\n        time.sleep(g * 2)\n\ndef mnr(g, d):  # minor chord sound effect\n    x = 0\n    while x \u003c d:\n        buzzer1.frequency = Notes.AS5\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.CS5\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.A4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.FS4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.GS4\n        buzzer1.duty_cycle = ON\n        time.sleep(g)\n        buzzer1.frequency = Notes.C6\n        buzzer1.duty_cycle = ON\n        time.sleep(g * 1)\n        x = x + 1\n        buzzer1.duty_cycle = OFF\n        time.sleep(g * 2)\n\ndef phaser(r):  # phaser sound effect\n    x = 0\n    while x \u003c r:\n        buzzer1.frequency = Notes.C5\n        buzzer1.duty_cycle = ON\n        time.sleep(ph)\n        buzzer1.frequency = Notes.C6\n        buzzer1.duty_cycle = ON\n        time.sleep(ph)\n        buzzer1.frequency - Notes.C7\n        buzzer1.duty_cycle = ON\n        time.sleep(ph)\n        x = x + 1\n\ndef rollthedice():  # main function when the dice is rolled (tilt switch opens)\n    if special.value == True:\n        maxy = 6  # only allow roll of 1 - 6 when special switch is off\n    else:\n        maxy = 7\n    x = random.randint(1, maxy)\n    if x == 1:\n        flashy(1, 0.05)  # flashy function flashes all of the LEDs before showing roll result\n        r1()\n        if maxy == 7:  # check to see if the player has won a roll again\n            ra = random.randint(1, raf)\n            if ra == raf:\n                hbd(1)\n        try:  # data logging of resulting roll\n            with open(\"/logger.txt\", \"a\") as datalog:\n                datalog.write(\"1 \\n\")\n                datalog.flush()\n\n        except OSError as e:\n            print(\"is error\") \n            \n    elif x == 2:\n        flashy(1, 0.05)\n        r2()\n        if maxy == 7:\n            ra = random.randint(1, raf)\n            if ra == raf:\n                hbd(1)\n        try:\n            with open(\"/logger.txt\", \"a\") as datalog:\n                datalog.write(\"2 \\n\")\n                datalog.flush()\n\n        except OSError as e:\n            print(\"is error\")\n            \n    elif x == 3:\n        flashy(1, 0.05)\n        r3()\n        try:\n            with open(\"/logger.txt\", \"a\") as datalog:\n                datalog.write(\"3 \\n\")\n                datalog.flush()\n\n        except OSError as e:\n            print(\"is error\")\n            \n    elif x == 4:\n        flashy(1, 0.05)\n        r4()\n        try:\n            with open(\"/logger.txt\", \"a\") as datalog:\n                datalog.write(\"4 \\n\")\n                datalog.flush()\n\n        except OSError as e:\n            print(\"is error\")\n            \n    elif x == 5:\n        flashy(1, 0.05)\n        r5()\n        try:\n            with open(\"/logger.txt\", \"a\") as datalog:\n                datalog.write(\"5 \\n\")\n                datalog.flush()\n\n        except OSError as e:\n            print(\"is error\")\n            \n    elif x == 6:\n        flashy(1, 0.05)\n        r6()\n        try:\n            with open(\"/logger.txt\", \"a\") as datalog:\n                datalog.write(\"6 \\n\")\n                datalog.flush()\n\n        except OSError as e:\n            print(\"is error\")\n            \n    else:  # roll is 7 therefore check to see if the player gets something greater than 6\n        ctseven = random.randint(1, 20) \n        if ctseven \u003e 15:  # if random number is between 16 to 20 - 1 in 4 chance - player rolls something greater than 6\n            flashy(1, 0.03)\n            adr = random.randint(0, 2)  # determine if player gets a 7 8 or 9\n            if adr == 0:\n                r7()\n                gliss(.03, 3)\n                bn()\n                try:\n                    with open(\"/logger.txt\", \"a\") as datalog:\n                        datalog.write(\"7 \\n\")\n                        datalog.flush()\n\n                except OSError as e:\n                    print(\"is error\")\n                    \n            elif adr == 1:\n                r8()\n                mjr(0.10, 3)\n                bn()\n                try:\n                    with open(\"/logger.txt\", \"a\") as datalog:\n                        datalog.write(\"8 \\n\")\n                        datalog.flush()\n\n                except OSError as e:\n                    print(\"is error\")\n                    \n            else:\n                r9()\n                mnr(0.10, 3)\n                bn()\n                try:\n                    with open(\"/logger.txt\", \"a\") as datalog:\n                        datalog.write(\"9 \\n\")\n                        datalog.flush()\n\n                except OSError as e:\n                    print(\"is error\")\n                    \n        else:  # if player not entitled to a 7 8 or 9 - 3 out of 4 chance - just roll again\n            rollthedice()\n\n\ndef clearall():  # turns off all of the pips\n    p1.value = False\n    p2.value = False\n    p3.value = False\n    p4.value = False\n    p5.value = False\n    p6.value = False\n    p7.value = False\n    p8.value = False\n    p9.value = False\n\n# Functions defining each roll outcome - which pips to light up\n\ndef r1():\n    p1.value = True\n\ndef r2():\n    p2.value = True\n    p3.value = True\n\ndef r3():\n    p1.value = True\n    p2.value = True\n    p3.value = True\n\ndef r4():\n    p2.value = True\n    p4.value = True\n    p5.value = True\n    p3.value = True\n\ndef r5():\n    p1.value = True\n    p2.value = True\n    p4.value = True\n    p5.value = True\n    p3.value = True\n\ndef r6():\n    p2.value = True\n    p4.value = True\n    p5.value = True\n    p3.value = True\n    p7.value = True\n    p6.value = True\n\ndef r7():\n    p2.value = True\n    p4.value = True\n    p5.value = True\n    p3.value = True\n    p7.value = True\n    p6.value = True\n    p1.value = True\n\ndef r8():\n    p2.value = True\n    p3.value = True\n    p4.value = True\n    p5.value = True\n    p6.value = True\n    p7.value = True\n    p8.value = True\n    p9.value = True\n\ndef r9():\n    p1.value = True\n    p2.value = True\n    p3.value = True\n    p4.value = True\n    p5.value = True\n    p6.value = True\n    p7.value = True\n    p8.value = True\n    p9.value = True\n\ndef flashy(c, t):  # pip flash sequence before roll is revealed\n    z = 0\n    while z \u003c c:\n        r1()\n        time.sleep(t)\n        clearall()\n        r2()\n        time.sleep(t)\n        clearall()\n        r3()\n        time.sleep(t)\n        clearall()\n        r4()\n        time.sleep(t)\n        clearall()\n        r5()\n        time.sleep(t)\n        clearall()\n        r6()\n        time.sleep(t)\n        clearall()\n        z = z + 1\n\nwhile True:  # main loop waiting for a roll to begin\n    if roll.value == True:\n        clearall()\n        flashy(2, 0.05)\n        rollthedice()\n        time.sleep(1)\n    else:\n        time.sleep(0.3)","metadata":{"language":"auto","linenums":false}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eI learned a huge amount developing the project. Use this a s jumping off point for you to make it your own!\u003c/p\u003e\n\u003cp\u003eFor example, the first time we played with it my granddaughter pretty quickly figured out how to game the system - she tilted the die (it keeps rolling as long as the tilt switch is open) and righted it when it came up to what she wanted. Therefore, I went back and modified the code to blank out between rolls and it will only reveal and stay lit once the cube is sitting upright, I also added a short beep to signal the roll is complete.\u003c/p\u003e\n\u003cp\u003eI also have ideas for the next version - we can add a second and a third piezo so the melodies can be polyphonic. I'm also thinking of adding an accelerometer to check the tilt level rather than just using a tilt switch or adding a way to select how many pips to show (so it can be used in another game that has a 1-3 spinner). Add functionality to work with other games like Hot Potato:\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"guide","content":"https://learn.adafruit.com/circuit-playground-hot-potato/game-play","metadata":{"guide_id":"1620","page_id":"9149"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThe possibilities are endless!\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}}]