All-in-one Arduino library for servo-based pellet feeders
Inspired by the FED3 architecture, TumbleFeeder v2 is a complete, self-contained system that handles everything from hardware initialization to data logging. No more juggling multiple files - just two lines of code!
#include <TumbleFeeder.h>
TumbleFeeder feeder;
void setup() {
feeder.begin(); // Does EVERYTHING
}
void loop() {
feeder.run(); // Handles EVERYTHING
}That's it! The library handles:
- âś… Pin initialization
- âś… RTC setup
- âś… Sharp memory display
- âś… SD card logging
- âś… Interactive startup menu
- âś… Input detection
- âś… FR schedules
- âś… Servo control
- âś… Sleep management
- âś… Battery monitoring
- âś… Automatic data saving
- Display built-in - No external display code needed
- RTC built-in - Automatic time tracking
- SD logging built-in - Automatic CSV creation and logging
- Startup menu - Interactive configuration on boot
- Sleep management - Automatic power saving
- v1.0: Required ~13 separate .ino files, manual callbacks, interrupt setup
- v2.0: Just main sketch + library - everything else is automatic
Based on the proven FED3 design by Lex Kravitz, adapted for servo feeders.
- Servo: Pin 10
- LED: Pin 13
- Left touch: A2
- Right touch: A0
- Feeder touch: A1
- Display: SCK=5, MOSI=A4, SS=6
- SD Card: CS=4
- Battery: A7
- Menu buttons: Red=A3, Green=1, Blue=A5
- Arduino M0/SAMD21 (Adafruit Feather M0 recommended)
- Servo motor
- Sharp Memory Display (144x168)
- SD card breakout
- RTC (DS3231)
- 3x Capacitive touch sensors
- 3x Buttons (menu navigation)
- LiPo battery + charger
- Download latest release ZIP
- Sketch → Include Library → Add .ZIP Library
- Select TumbleFeeder.zip
- Restart Arduino IDE
- Tools → Manage Libraries
- Search "TumbleFeeder"
- Click Install
On first boot (or anytime you restart), you'll see an interactive menu:
Red Button = Start session
Blue Button = Edit settings
Green Button = Navigate menus
You can configure:
- Mode - FR or Free feeding
- FR Value - 1 through 10
- Device Number - 0 through 19 (for multi-cage setups)
- Open Duration - 10-120 seconds
- Servo Positions - Fine-tune open/closed angles
All settings are automatically saved to CONFIG.csv on the SD card.
Files are named: TUMBLER_DDD_MMDDYY_NN.CSV
DDD= Device number (3 digits)MMDDYY= DateNN= Session number (auto-increments)
Every event is automatically logged with:
- Timestamp (date + time)
- Temperature (from RTC)
- Elapsed time (seconds)
- Battery voltage
- Device number
- Left poke count & duration
- Right poke count & duration
- Feeder access count & duration
- Current paradigm (FR# or Free)
Just call feeder.run() - logging happens automatically!
#include <TumbleFeeder.h>
TumbleFeeder feeder;
void setup() {
feeder.begin();
}
void loop() {
feeder.run();
}#include <TumbleFeeder.h>
TumbleFeeder feeder;
void setup() {
// Optional: Configure before begin()
feeder.setFR(5);
feeder.setOpenDuration(30);
feeder.setDeviceNumber(2);
feeder.begin(); // Still shows menu for final adjustments
}
void loop() {
feeder.run();
}#include <TumbleFeeder.h>
TumbleFeeder feeder;
void setup() {
feeder.begin();
}
void loop() {
feeder.run();
// Custom logic based on events
if (feeder.leftPokeCount == 50) {
Serial.println("Halfway milestone!");
}
// Check battery
if (feeder.measuredvbat < 3.5) {
Serial.println("Battery low!");
}
}Initialize all hardware, show startup menu, create data file.
Check inputs, update display, log data, manage sleep. Call this every loop.
Set fixed-ratio schedule (1-10).
Set how long gate stays open (10-120 seconds).
Set servo angles (open: 0-90, closed: 0-180).
Set device ID (0-19).
Set mode (0 = FR, 1 = Free feeding).
Manually open gate.
Manually close gate.
Close then open gate (settles food).
Blink LED 10 times.
Reset all event counters to zero.
Control automatic sleep (useful for debugging).
feeder.leftPokeCount- Total left pokesfeeder.rightPokeCount- Total right pokesfeeder.FeederCount- Total feeder accessesfeeder.leftPokeDur- Last left poke duration (ms)feeder.rightPokeDur- Last right poke duration (ms)feeder.leftFeederDur- Last feeder duration (ms)feeder.FR- Current FR valuefeeder.mode- Current mode (0=FR, 1=Free)feeder.deviceNumber- Device IDfeeder.closedpos- Closed servo positionfeeder.openpos- Open servo positionfeeder.open_duration- Gate open duration (seconds)feeder.measuredvbat- Battery voltage
feeder.display- Sharp display object (Adafruit_SharpMem)feeder.rtc- Real-time clock object (RTC_DS3231)feeder.SD- SD card object (SdFat)feeder.logfile- Current log file (File)
Good news: Your hardware doesn't change!
v1.0 Code:
#include <TumbleFeeder.h>
TumbleFeeder feeder;
void setup() {
feeder.begin(150, 0);
feeder.setFR(1);
feeder.setLogCallback(logData);
feeder.setDisplayCallback(updateDisplay);
attachInterrupt(...);
// ... lots of setup code
}
void loop() {
feeder.checkInputs(60);
}
// + 12 other .ino filesv2.0 Code:
#include <TumbleFeeder.h>
TumbleFeeder feeder;
void setup() {
feeder.begin();
}
void loop() {
feeder.run();
}
// That's it!- Check SD card is inserted
- Verify connections (CS on pin 4)
- Try reformatting card (FAT32)
- Check servo connected to pin 10
- Verify positions in startup menu
- Test with manual
feeder.feederOpen()
- Verify wiring (A2=left, A0=right, A1=feeder)
- Check pull-up resistors on touch sensors
- Test with Serial.println in sketch
- Check display connections (SCK=5, MOSI=A4, SS=6)
- Verify Sharp Memory Display compatibility
- Check contrast/viewing angle
- Ensure SD card has space
- Check
CONFIG.csvexists (created on first boot) - Verify RTC is set (shows in startup menu)
void loop() {
feeder.run();
// Add custom text to display
feeder.display.setCursor(0, 140);
feeder.display.print("Trial: ");
feeder.display.print(feeder.leftPokeCount / feeder.FR);
feeder.display.refresh();
}void loop() {
feeder.run();
DateTime now = feeder.rtc.now();
if (now.hour() == 18 && now.minute() == 0) {
Serial.println("Feeding session ending!");
}
}// Device 1
feeder.setDeviceNumber(1);
// Device 2
feeder.setDeviceNumber(2);
// Each creates separate log files:
// TUMBLER_001_MMDDYY_NN.CSV
// TUMBLER_002_MMDDYY_NN.CSVIssues and pull requests welcome on GitHub!
MIT License - Free to use and modify for research purposes.
If you use TumbleFeeder in your research, please cite:
Barrett, M. (2025). TumbleFeeder: An Arduino library for servo-based
pellet feeders in behavioral neuroscience. GitHub repository.
https://github.com/MasBarr/TumbleFeeder
Based on FED3 architecture:
Kravitz, A.V., et al. (2020). The Feeding Experimentation Device
version 3 (FED3): An open-source home-cage compatible device for
measuring food intake in rodents.
Mason Barrett, Kravitz Lab
Washington University in St. Louis
Psychiatry Department
- Based on FED3 by Lex Kravitz
- Inspired by open science and reproducible research
- Built with Arduino, Adafruit libraries, and community contributions