Authors: Candice Lee and Ziyue Liu
An Arduino-based closed-loop system for rodent behavioral neuroscience experiments, implementing real-time sensorimotor feedback for texture/shape/object discrimination tasks. The system continuously monitors licking behavior via capacitive touch sensing and dynamically adjusts stimulus presentation and reward delivery with millisecond precision.
Key Features:
- Closed-loop control with real-time behavioral feedback
- Event synchronization via TTL outputs for multi-modal data integration
- Python-based experiment management with automated data logging
- Multiple behavioral paradigms (operant and Pavlovian conditioning)
- Cross-platform support (Windows, Linux, macOS)
Originally developed for whisker-guided texture discrimination experiments in mice.
System Requirements:
- Python 3.7 or higher
- Arduino Uno (ATmega328P)
- Arduino CLI
- 4GB RAM minimum
- USB port for Arduino connection
System built on 2AFC setup architecture used here:
-
Jung M Park, Y Kate Hong, Chris C Rodgers, Jacob B Dahan, Nina Harano, Ewoud RE Schmidt, Randy M Bruno bioRxiv 2020.08.12.245381; doi: https://doi.org/10.1101/2020.08.12.245381
-
Arduino Uno - Main microcontroller (ATmega328P)
-
OM2 PCB Shield - Custom interface board (https://claylacefield.wixsite.com/openmazehome/openmaze-shields)
-
12V Power Supply - Motor and solenoid control
-
Stepper Motor - Precision texture wheel positioning (0°, 90°, 180°, 270°)
-
Linear Actuator (Servo) - Stimulus presentation control
-
MPR121 Capacitive Touch Sensor - Sub-millisecond lick detection via I2C communication
-
Speaker - Auditory feedback and white noise generation
-
Solenoid Valve - Precise water reward delivery (10-26ms resolution)
-
TTL Output Pins - Event synchronization for external data acquisition systems
- Arduino Sketches - Behavioral paradigms and hardware control
- Python Control Scripts - Experiment management and data logging
- Arduino CLI - Sketch compilation and upload automation
whisker_tasks/
├── Arduino/ # Arduino sketches for different behavioral paradigms
│ ├── GoNoGo_Texture/ # Go/No-Go texture discrimination
│ │ └── GoNoGo_Texture.ino
│ ├── PavlovianTexture/ # Pavlovian conditioning
│ │ └── PavlovianTexture.ino
│ ├── GradedPavlovian/ # Graded reward Pavlovian conditioning
│ │ └── GradedPavlovian.ino
│ ├── initialize_and_end/ # System initialization and shutdown
│ │ └── initialize_and_end.ino
│ ├── reward_habituation/ # Reward habituation protocol
│ │ └── reward_habituation.ino
│ ├── test_MPR121/ # Touch sensor testing for troubleshooting
│ │ └── test_MPR121.ino
│ ├── libraries/ # Arduino libraries
│ └── archive/ # Archived/obsolete sketches (git-ignored)
├── behaviour_run.py # Main experiment runner
├── behaviour_stop.py # System stop and initialization
├── habituation_run.py # Operant water habituation
├── upload_and_write.py # Arduino upload and data logging utility
├── config_loader.py # Configuration file loader
├── config.example.json # Example configuration file (copy to config.json)
├── requirements.txt # Python dependencies
├── LICENSE # MIT License
└── README.md # This file
File: Arduino/GoNoGo_Texture/GoNoGo_Texture.ino
Implements real-time closed-loop feedback based on continuous lick monitoring:
- Go trials (CS+): Lick detection triggers reward tone, immediate stimulus retraction and reward delivery
- No-Go trials (CS-): Lick detection triggers white noise, immediate stimulus retraction, timeout and period
- Real-time event logging with TTL synchronization for external recording systems
- Auditory feedback (pure tone for correct responses, white noise for false alarms)
- Configurable trial parameters including CS-/CS+ bias and threshold settings
File: Arduino/PavlovianTexture/PavlovianTexture.ino
Classical conditioning paradigm with continuous behavioral monitoring:
- 4-position stimulus system (CS+ at 0° & 180°, CS- at 90° & 270°)
- Randomized stimulus positioning within trial types
- Optional timeout functionality for false alarm trials
- Continuous lick tracking throughout all task phases
File: Arduino/GradedPavlovian/GradedPavlovian.ino
Closed-loop system with trial-by-trial adaptive reward magnitude:
- Real-time lick counting during anticipatory period
- Dynamic reward scaling based on behavioral output (small: 10ms, medium: 18ms, large: 26ms)
- Demonstrates adaptive feedback control based on continuous behavioral metrics
- 4-position stimulus system with optional timeout functionality
File: Arduino/reward_habituation/reward_habituation.ino
Basic operant conditioning protocol:
- Lick-triggered reward delivery for initial training
- Real-time touch detection and immediate feedback
Python-based experiment management framework providing automated hardware control and data acquisition:
Main experiment runner for Pavlovian texture conditioning experiments.
System initialization and shutdown control for safe hardware state management.
Automated habituation protocol execution with reward delivery.
Core utility class providing:
- Automated Arduino sketch compilation and deployment via Arduino CLI
- Real-time serial communication for bidirectional hardware control
- Timestamped data logging with automatic file management
- Structured data organization (Mouse ID and date-based hierarchical storage)
- Python 3.7+
- Arduino CLI - Download from: https://arduino.github.io/arduino-cli/latest/installation/
- Arduino Libraries (install via Arduino IDE or CLI):
- Adafruit_MPR121:
arduino-cli lib install "Adafruit MPR121" - Servo (built-in Arduino library)
- Wire (built-in Arduino library)
- Adafruit_MPR121:
- Clone or download this repository
git clone https://github.com/clee162/whisker_tasks.git
cd whisker_tasks- Install Python dependencies
pip install -r requirements.txt- Configure your system
# Copy the example config file
cp config.example.json config.json
# Edit config.json with your settings (use any text editor)
# - Set your Arduino port (e.g., "COM17" on Windows, "/dev/ttyUSB0" on Linux)
# - Set data save directory path
# - Adjust sketch paths if needed
#- Choose your current sketch to run - Verify Arduino CLI installation
arduino-cli version- Connect Arduino and verify port
# Windows
arduino-cli board list
# Linux/Mac
ls /dev/tty*Edit config.json to match your system:
{
"arduino": {
"port": "COM17", // Your Arduino port
"fqbn": "arduino:avr:uno"
},
"paths": {
"data_save_folder": "C:/my_files/behaviour_data",
"temp_compilation_folder": "C:/my_files/temp/arduino_comp"
}
}Platform-specific port names:
- Windows:
COM#(e.g.,COM17) - Linux:
/dev/ttyUSB#or/dev/ttyACM# - Mac:
/dev/tty.usbserial-#or/dev/cu.usbmodem#
python behaviour_run.pypython habituation_run.pypython behaviour_stop.pyNote: You can also upload sketches directly using Arduino IDE if preferred.
The behavioural task events are logged in two ways: (1) TTL outputs at the time of CS+/CS- onset and offset, lick times and reward times. These can be used to synchronize the behaviour with external imaging or ephys recordings. (2) .txt file outputs with event time stamps. These can be analyzed offline.
Analysis code for both of these can be found at https://github.com/clee162/whisker_tasks_analysis
Behaviour_data/
└── Mouse_ID/
├── Mouse_ID_Date.txt
├── Mouse_ID_Date(1).txt
└── ...
Real-time timestamped event logging via serial communication (115200 baud):
- Trial number and stimulus type (CS+/CS-)
- Lick detection events with millisecond timestamps
- Reward delivery timing and duration
- Timeout periods and false alarm detection
- TTL pulse timing for multi-modal data synchronization
Data streams are captured to structured text files for offline analysis and can be synchronized with external recording systems (e.g., electrophysiology, imaging) via TTL outputs.
For analysis scripts to process the behavioral data outputs:
- MATLAB analysis: See
BehaviourAnalysis/matlab_analysis/lick_analysis - Python analysis: See
BehaviourAnalysis/python_analysis/behavioral_analysis
These scripts analyze .txt outputs and visualize behavioral metrics including lick rates, response times, and learning curves.
- Continuous sensor polling at millisecond resolution for low-latency behavioral feedback
- Event-driven state machine architecture for precise trial timing
- Deterministic response times for closed-loop stimulus control
- Capacitive touch sensing with configurable threshold detection
- Digital filtering for reliable lick detection from noisy sensor data
- I2C communication protocol for sensor interfacing
- TTL pulse generation synchronized with behavioral events
- Serial data streaming at 115200 baud for real-time monitoring
- Timestamped event logging for post-hoc analysis and cross-system synchronization
-
Serial Communication Errors:
- Verify correct COM port in
config.json - Check baud rate is set to 115200
- Ensure no other programs are using the serial port
- Verify correct COM port in
-
MPR121 Not Found:
- Verify I2C connections (SDA/SCL pins)
- Check I2C address (default: 0x5A)
- Test with
Arduino/test_MPR121/test_MPR121.ino
-
Arduino CLI Not Found:
- Ensure Arduino CLI is in your system PATH
- Try running
arduino-cli versionto verify installation
-
Config File Error:
- Make sure
config.jsonexists (copy fromconfig.example.json) - Verify JSON syntax is valid
- Check file paths use correct separators for your OS
- Make sure
If you use this software in your research, please cite it using the following:
@software{lee2025whiskertasks,
author = {Lee, Candice and Liu, Ziyue},
title = {Whisker Tasks: Real-Time Behavioral Control System for Rodent Neuroscience},
year = {2025},
url = {https://github.com/cleeneuro/whisker_tasks},
version = {1.0.0}
}
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to:
- Report bugs or issues
- Suggest new features or improvements
- Submit pull requests
For major changes, please open an issue first to discuss what you would like to change.
- Chen, J. L., Voigt, F. F., Javadzadeh, M., Krueppel, R., & Helmchen, F. (2016). Long-range population dynamics of anatomically defined neocortical networks. eLife, 5, e14679. https://doi.org/10.7554/eLife.14679
- Go/No-Go task design adapted from this publication (doi:10.1038/nn.4046 referenced in code)
- OpenMaze OM2 Shield: Lacefield Lab, https://claylacefield.wixsite.com/openmazehome/openmaze-shields
- Park, J. M., Hong, Y. K., Rodgers, C. C., Dahan, J. B., Harano, N., Schmidt, E. R. E., & Bruno, R. M. (2020). Deep and superficial layers of the primary somatosensory cortex are critical for whisker-based texture discrimination in mice. bioRxiv, 2020.08.12.245381. https://doi.org/10.1101/2020.08.12.245381
- 2AFC behavioral setup architecture adapted from this work
- Adafruit MPR121 Library: https://github.com/adafruit/Adafruit_MPR121
- Adafruit BusIO Library: https://github.com/adafruit/Adafruit_BusIO (dependency for MPR121)
- Arduino Servo Library (standard Arduino library): https://www.arduino.cc/reference/en/libraries/servo/
- Arduino Wire Library (I2C communication, standard Arduino library)
Python Libraries:
- pySerial: https://github.com/pyserial/pyserial (Python serial communication)
Development Tools:
- Arduino CLI: https://github.com/arduino/arduino-cli (command-line tool for Arduino compilation and upload)