We picked up a magnetic foam shape kit, to make a fridge-mounted marble run. But picking up the marble after each run is such a drag - wouldn't it be fun if you could use your Crickit to help lift the ball back up and re-start the marble run?

With an electromagnet, we can pick up the stainless steel balls. A DC motor acts as a pulley, and a servo helps align the electromagnet so it can navigate around the foam.

You can DIY, as we did, using the two Circuit Playground Express buttons and switch to control the motors - or you could even automate the whole thing!

Parts List

Circuit Playground Express is the next step towards a perfect introduction to electronics and programming. We've taken the original Circuit Playground Classic and...
In Stock
Sometimes we wonder if robotics engineers ever watch movies. If they did, they'd know that making robots into slaves always ends up in a robot rebellion. Why even go down that...
In Stock
Perhaps you've been assembling a new robot friend, adding a computer for a brain and other fun personality touches. Now the time has come to let it leave the nest and fly on...
In Stock
This high-torque standard servo can rotate approximately 180 degrees (90 in each direction). You can use any servo code, hardware or library to control these servos. Good for beginners...
In Stock
1 x 5V Electromagnet
Use a "50N" one for good pick up ability!

Wiring Diagram

Even though an electromagnet doesn't have 'direction' and thus could be controlled by a Drive pin, we opted for a Motor port because these electromagnets can draw up to 700mA and that's more than the Drive pin. But, you could almost certainly get away with using a Drive pin if you like!


Save to your CPX as code.py and press the CPX buttons to move the pulley up and down. Capacitive touch pads #1 and #4 twist the servo and then the switch enables and disables the electromagnet.

The most interesting part is smooth_move which is our gentle servo movement helper, it will carefully move the servo rather than jostling it and the magnet which would possibly cause the balls to fall.

import time
from busio import I2C
from adafruit_seesaw.seesaw import Seesaw
from adafruit_seesaw.pwmout import PWMOut
from adafruit_motor import motor, servo
from digitalio import DigitalInOut, Direction, Pull
import board

print("Mag Neat-o!")

# Create seesaw object
i2c = I2C(board.SCL, board.SDA)
seesaw = Seesaw(i2c)

# Create one motor on seesaw PWM pins 22 & 23
motor_a = motor.DCMotor(PWMOut(seesaw, 22), PWMOut(seesaw, 23))
# Create another motor on seesaw PWM pins 19 & 18
motor_b = motor.DCMotor(PWMOut(seesaw, 19), PWMOut(seesaw, 18))

# Create servo object
pwm = PWMOut(seesaw, 17)     # Servo 1 is on s.s. pin 17
pwm.frequency = 50           # Servos like 50 Hz signals
my_servo = servo.Servo(pwm)  # Create my_servo with pwm signa
my_servo.angle = 90

def smooth_move(start, stop, num_steps):
    return [(start + (stop-start)*i/num_steps) for i in range(num_steps)]

buttona = DigitalInOut(board.BUTTON_A)
buttona.direction = Direction.INPUT
buttona.pull = Pull.DOWN

buttonb = DigitalInOut(board.BUTTON_B)
buttonb.direction = Direction.INPUT
buttonb.pull = Pull.DOWN

switch = DigitalInOut(board.SLIDE_SWITCH)
switch.direction = Direction.INPUT
switch.pull = Pull.UP

last_buttona = buttona.value
last_buttonb = buttonb.value
last_switch = switch.value

last_touch1 = False
last_touch4 = False

while True:
    touch_vals = (seesaw.touch_read(0), seesaw.touch_read(3))
    # print(touch_vals)

    touch1 = False
    if seesaw.touch_read(0) > 500:
        touch1 = True

    if touch1 != last_touch1:
        if touch1:
            start_angle = my_servo.angle
            end_angle = start_angle - 20
            end_angle = max(0, min(end_angle, 180))
            print("left from", start_angle, "to", end_angle)
            for a in smooth_move(start_angle, end_angle, 25):
                my_servo.angle = a
        last_touch1 = touch1

    touch4 = False
    if seesaw.touch_read(3) > 500:
        touch4 = True

    if touch4 != last_touch4:
        if touch4:
            start_angle = my_servo.angle
            end_angle = start_angle + 20
            end_angle = max(0, min(end_angle, 180))
            print("right from", start_angle, "to", end_angle)
            for a in smooth_move(start_angle, end_angle, 25):
                my_servo.angle = a
        last_touch4 = touch4

    if buttona.value != last_buttona:
        if buttona.value:
            if motor_a.throttle:
                motor_b.throttle = -0.1
                motor_b.throttle = -0.1
            motor_b.throttle = 0
        last_buttona = buttona.value

    if buttonb.value != last_buttonb:
        if buttonb.value:
            if motor_a.throttle:
                motor_b.throttle = 0.4
                motor_b.throttle = 0.3
            motor_b.throttle = 0
        last_buttonb = buttonb.value

    if switch.value != last_switch:
        motor_a.throttle = switch.value
    if motor_a.throttle:
        last_switch = switch.value


This guide was first published on May 16, 2018. It was last updated on May 16, 2018.

This page (Mag Neat-o) was last updated on Nov 04, 2020.