Skip to content

Mouse maze

A modular maze built from swappable acrylic panels, with closed-loop tracking: an IR camera and a Python state machine follow the animal and tell BeeHive when to dispense a reward.

Ingredients

BeeHive boards:

Board Qty Role
ESP32 BeeHive mainboard Receives serial commands from the tracking PC and drives the reward hardware.
IR sensor array Local IR sensing at reward ports / beam-breaks.

Other components:

Component Qty Notes
Acrylic maze panels, 50 × 50 mm many Opaque in visible light, transparent in IR; reconfigurable walls.
Makerbeam XL posts many The frame the panels slot between.
Adafruit PCA9685 (16-ch 12-bit PWM/servo driver, I2C) Drives the reward servos; daisy-chainable to 992 motors over two data lines.
Servo-driven 3D-printed pellet dispenser 1×+ Food reward; one per reward port.
IR camera Tracks the animal through the IR-transparent walls.
PC running OpenCV Runs the tracking state machine; sends serial commands to the mainboard.

How it works

The maze is assembled from 50 × 50 mm acrylic panels that slot vertically between Makerbeam XL posts, so the layout is reconfigured by hand in minutes. Panels are opaque in the visible range but transparent in IR, so an overhead IR camera sees straight through the walls to track the animal while the mouse sees an opaque maze. Panels are swapped for textures, gratings or reward ports as the experiment demands.

Control is closed-loop:

  1. The IR camera feeds video to a PC.
  2. OpenCV tracks the animal, and a Python state machine decides when reward is due.
  3. The PC sends a serial command to the BeeHive mainboard.
  4. The mainboard triggers the pellet dispenser (and any port hardware on the IR sensor array).

The pellet dispenser was redesigned to use a servo instead of a stepper, which makes it far easier to 3D-print and share. Servos are driven through the PCA9685 PWM driver over I2C; a single PCA9685 chain can address a large number of servos — up to 992 servos over just two data lines when daisy-chained — so many reward ports scale without extra mainboard pins.

Wiring

  • PCA9685 to mainboard I2C (SDA/SCL data lines) + power and ground; the dispenser servo(s) connect to the PCA9685 outputs.
  • IR sensor array to a mainboard data line for port sensing.
  • The tracking PC connects to the mainboard over USB serial.

Schematic

Panel drawings, the dispenser model and board schematics live in the BeeHive repository.

Code

Illustrative — not published upstream

The maze firmware isn't in the BeeHive repositories, so the sketch below is an illustrative starting point, not the lab's code. The real building blocks it would use are published: serial commands from PC to mainboard (see serial_beehive.py) and servo pellet-dispenser control (see Servo_test.py).

Written in C++

Unlike most BeeHive recipes, the maze firmware is written in C++ (Arduino) rather than MicroPython. This let it reuse the Adafruit PWM Servo Driver library for the PCA9685 and an existing serial-command parsing library. It is a good example of BeeHive's language flexibility — the same mainboard runs either toolchain.

// TODO: pins/addresses are placeholders — set to your wiring.
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

void setup() {
  Serial.begin(115200);
  pwm.begin();
  pwm.setPWMFreq(50);        // servo update rate
}

void dispensePellet(uint8_t ch) {
  pwm.setPWM(ch, 0, 400);    // rotate to dispense
  delay(300);
  pwm.setPWM(ch, 0, 200);    // return
}

void loop() {
  // Serial command from the OpenCV state machine, e.g. "R3\n" = reward port 3
  if (Serial.available()) {
    char cmd = Serial.read();
    if (cmd == 'R') {
      int port = Serial.parseInt();
      dispensePellet(port);
    }
  }
}

Results / notes

The maze is quick to reconfigure, tracks through the walls in IR, and rewards in closed loop from a standard PC vision pipeline. Moving the dispenser to a servo makes the whole build printable and shareable. The same servo-driven pellet dispenser is reused in the 5-choice serial reaction time task.