Coding the Rube Goldberg box

Use a force sensor to trigger a servo that drops a rolling weight. The weight hits a button which starts a fan, blowing out confetti everywhere.

Duration: ~25 minutes

What’s in the code?

Concepts

  • Force sensors (input)
  • Buttons (input)
  • Pin functions (servo)
  • Pixels (light)

Blocks

pins.A1.analogRead()
light.showRing("red red red red red red red red red red")
pins.A2.servoWrite(180)
pause(0)

Let’s code it!

|Step 1| - Get the logic setup

First, we’ll set up some code to get us started.

  1. Open MakeCode in your web browser.
  2. From LOOPS drag a ||loops:forever|| loop out.
  3. In LOGIC grab a ||logic:if then else|| block and put it in the ||loops:forever|| block.
  4. Again, from LOGIC, pull out the ||logic:0 < 0|| conditional and replace true in the condition for the ||logic:if then else|| block.
  5. Change the condition from < to >.
forever(function () {
    if (0 > 0) {

    } else {

    }
})

|Step 2| - Respond to the force sensor

Ok, let’s do something when the force sensor is pressed. How about lighting the pixels?

  1. Get a ||pins:analog read pin|| from PINS and put it on the left side of the > in the ||logic:if then else||.
  2. Change the 0 on the right to 100.
  3. Change the A0 to A1 in the ||pins:analog read pin|| block.
forever(function () {
    if (pins.A1.analogRead() > 100) {

    } else {

    }
})

Now, we’ll add two different pixel patterns to show when the force sensor is pressed and not pressed.

  1. Go into LIGHT and get a ||light:show ring||. Put it in the first part of the ||logic:if then else|| block.
  2. Get another ||light: show ring|| and put it in the second part of the ||logic:if then else|| block.
  3. Make each ||light: show ring|| display a different pattern of colors.
forever(function () {
    if (pins.A1.analogRead() > 100) {
        light.showRing("yellow white blue green blue pink red green yellow pink")
    } else {
        light.showRing("red red red red red red red red red red")    
    }
})

Download the code to your Adafruit Circuit Playground Express and press the force sensor. Did you see the lights change?

|Step 3| - Controlling the servo

Right, time to make the servo turn so the rolling weight will drop.

  1. Get a ||pins:servo write pin|| from PINS and put it below your first ||light:show ring|| inside the ||logic:if||.
  2. Get another ||pins:servo write pin|| and put it under the second ||light:show ring|| inside the ||logic:else||.
  3. Change the A0 in both ||pins:servo write pin|| blocks to A2.
  4. Change the 0 in the first ||pins:servo write pin|| to say 180.
forever(function () {
    if (pins.A1.analogRead() > 100) {
        light.showRing("yellow white blue green blue pink red green yellow pink")
        pins.A2.servoWrite(180)
    } else {
        light.showRing("red red red red red red red red red red")
        pins.A2.servoWrite(0)    
    }
})

|Step 4| - Reset the box for the next drop (optional)

So that you can keep running the prank over again, let’s have the box reset itself to have the weight held up again. Ok, this step is a little more involved…

  1. Pull out a ||loops.pause|| block from LOOPS and place it under the last ||pins:servo write pin||.
  2. Change the time to 3000 milliseconds. This gives the weight some time to roll down before the holder comes back.

  3. In LOOPS, find ||loops:on start|| and pull it out onto the workspace somewhere. Go to VARIABLES and drag a ||variables:set to|| into ||loops:on start||. Rename the variable from item to reset. Go into LOGIC and pick up a true. Drag it over to the ||variables:set to|| and replace the 0 with it.

  4. Get an ||logic:if then|| block and put it in the ||logic:if|| part of the outer ||logic:if then else||.
  5. Get another ||variables:set to|| and put it in the new ||logic:if then||. Go to the dropdown and change the variable name to reset. This time get a false from LOGIC and stick it in this ||variables:set to||.
  6. Finally, drag the ||light:show ring|| and ||pins:servo write pin|| into the inner ||logic:if then||.
  7. Duplicate the ||variables:set to|| from the ||loops:on start|| loop and place it inside the ||logic:else|| part of the outer ||logic:if then else||.
let reset = true;
forever(function () {
    if (pins.A1.analogRead() > 100) {
        if (reset) {
            light.showRing("yellow white blue green blue pink red green yellow pink")
            pins.A2.servoWrite(180)
            reset = false;
        }
    } else {
        light.showRing("red red red red red red red red red red")
        pins.A2.servoWrite(0)    
        pause(3000)
        reset = true;
    }
})

Good work!

You’ve finished! Download the code to your Adafruit Circuit Playground Express. Now, set the weight on top of the chute an fill up the box with the confetti. Ready to PRANK!