Design and fabricate the rotating inspection nest, positive D-shaft hub, homing cam, and optical darkroom shroud to present Skittles to the AS7341 spectral sensor.
This subassembly combines software, electronics, and mechanical design into a single precision mechanism. The inspector wheel has three critical engineering jobs:
inspection.stl) forms a light-trap hood over the active nest.3D Files/wheel.stl, cam.stl, inspection.stlMeasure 5 random Skittles across diameter and thickness. You will typically find ∅ 13.0–13.4mm diameter and 6.0–6.8mm thickness. Define your pocket parameters:
pocket_diam = 14.2 mm # 13.4mm max + 0.8mm clearance
pocket_depth = 7.0 mm # Full candy thickness
draft_angle = 7.0 deg # Draft to prevent gravity sticking
In Fusion 360:
r = 20.0 mm radius. Extrude as Cut with a 7° taper angle.The inspector wheel must trip the limit switch once per revolution to establish an absolute physical datum ($0.0^\circ$) without using a hard stop that would block continuous 360° forward rotation. On the underside of the wheel (or as the dedicated interlocking part cam.stl):
5.15 mm D-shaft bore with a 4.5 mm flat edge offset.plate_stepper.stl without mechanical shock or contact bounce.The AS7341 sensor board mounts directly above the pocket wheel:
Print the parts (black PLA is ideal for the optical shroud to absorb stray light). Install the M3 heat-set insert, slide the hub onto the motor shaft, and tighten the grub screw against the D-flat. Bolt the optical shroud over the assembly.
Write an automated 3-phase homing routine in Python that eliminates mechanical switch hysteresis and indexes 90° between pockets:
import RPi.GPIO as GPIO
import time
from adafruit_motorkit import MotorKit
from adafruit_motor import stepper
SWITCH_PIN = 20
STEPS_PER_REV = 200 # 1.8° NEMA-17 stepper (200 steps/rev)
OFFSET_TO_POCKET_1 = 14 # Calibrated step offset to center Pocket #1 under sensor
GPIO.setmode(GPIO.BCM)
GPIO.setup(SWITCH_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
kit = MotorKit(0x60)
def precision_home_wheel():
print("Homing inspector wheel...")
# Phase 1: Fast Seek forward until cam trips switch (active LOW)
steps = 0
while GPIO.input(SWITCH_PIN) == GPIO.HIGH:
kit.stepper1.onestep(direction=stepper.FORWARD, style=stepper.SINGLE)
steps += 1
time.sleep(0.008)
if steps > 250:
kit.stepper1.release()
raise RuntimeError("Homing timeout: Cam switch not found!")
# Phase 2: Slow reverse release to eliminate mechanical hysteresis
time.sleep(0.05)
while GPIO.input(SWITCH_PIN) == GPIO.LOW:
kit.stepper1.onestep(direction=stepper.BACKWARD, style=stepper.SINGLE)
time.sleep(0.03) # Slow precision speed
# Phase 3: Step forward by fixed offset to center Pocket #1 under optical sensor
for _ in range(OFFSET_TO_POCKET_1):
kit.stepper1.onestep(direction=stepper.FORWARD, style=stepper.SINGLE)
time.sleep(0.01)
kit.stepper1.release()
print("✓ Wheel homed and Pocket #1 centered under optical shroud.")
def index_pocket(steps_forward=50):
"""Index exactly 90 degrees (50 steps on 200-step motor)"""
for _ in range(steps_forward):
kit.stepper1.onestep(direction=stepper.FORWARD, style=stepper.SINGLE)
time.sleep(0.008)
kit.stepper1.release()
1.0 mm.0.008s to 0.012s and inspect the underside for friction against the bracket.