Sienna Giuseppi
Slow Invertebrate Release Feeder — Reptile Enrichment

Project overview

PAGE CURRENTLY UNDER CONSTRUCTION- please check back later for finalized details!

Three teammates adn I built a timed, randomized release feeder that returns natural hunting behavior to reptiles by releasing live crickets in randomized intervals over a user-selected duration (1–12 hours). The device holds ~150+ crickets live, and dispenses 6 independent groups at random times so reptiles must hunt rather than their current method of feeding from a single bowl at a predicted time.

The design emphasizes keeper usability (removable rechargeable battery and an accessible lid), animal safety (ventilated lid and gentle trap-door mechanism), low cost (target < $100 BOM), and durability for long-term exhibit use. Key components include an Arduino controller, potentiometer timing control, relays and solenoids driving trap doors, and a modular partitioned hopper for easy cleaning.

Project demo

How it works

The user selects a total run duration with a potentiometer (1–12 hours) and toggles the device on. Arduino firmware chooses 6 random timestamps within that period and triggers solenoids, each of which retracts to drop a trap door and release a small group of live crickets.

Design highlights

  • Partitioned hopper holds >150 crickets and is removable for cleaning.
  • Ventilated lid preserves cricket viability while keeping electronics protected.
  • Timing randomness mimics natural prey availability and encourages natural hunting.

Keeper workflow

Fill hopper and close lid, slide potentiometer to desired duration, flip power on — device runs autonomously and is designed for weekly recharging and simple maintenance.

Features

Partitioned hopper and lid
Partitioned Hopper & Lid
Removable lid with mesh for airflow; partitions for containment and easy cleaning.
Random timing concept
Randomized Release Timing
Arduino selects 6 random times across the chosen duration to trigger drops.
Solenoid and trap door
Solenoids & Trap Doors
6 solenoids retract to release individual trap doors that drop groups of insects.
Electronics box
Electronics & Power
Arduino controller with relays, removable rechargeable battery, accessible electronics box.
Testing and safety
Testing & Animal Safety
Temperature, drop height, durability, and keeper usability testing completed.
Capacity and maintenance
Capacity & Maintenance
Holds 150+ crickets; modular parts for easy cleaning and serviceability.

Full images & CAD

Top view
(function(){ // LIGHTBOX: images and videos const lightbox = document.getElementById('lightbox'); const lightboxMedia = document.getElementById('lightboxMedia'); const lightboxClose = document.querySelector('.lightbox-close'); const imgButtons = Array.from(document.querySelectorAll('.img-btn')); function openLight(src){ lightboxMedia.innerHTML = ''; const isVideo = /\.(mp4|webm|ogg)$/i.test(src); if(isVideo){ const v = document.createElement('video'); v.controls = true; v.autoplay = true; v.playsInline = true; v.preload = 'metadata'; v.style.maxWidth = '100%'; v.style.maxHeight = 'calc(92vh - 80px)'; const s = document.createElement('source'); s.src = src; s.type = 'video/mp4'; v.appendChild(s); lightboxMedia.appendChild(v); } else { const img = document.createElement('img'); img.src = src; img.alt = ''; img.style.maxWidth='100%'; img.style.maxHeight='calc(92vh - 80px)'; lightboxMedia.appendChild(img); } lightbox.classList.add('open'); lightbox.setAttribute('aria-hidden','false'); document.body.style.overflow = 'hidden'; lightboxClose.focus(); } function closeLight(){ lightbox.classList.remove('open'); lightbox.setAttribute('aria-hidden','true'); lightboxMedia.innerHTML=''; document.body.style.overflow=''; } imgButtons.forEach(btn => { btn.addEventListener('click', () => openLight(btn.dataset.src)); btn.addEventListener('keydown', e => { if(e.key==='Enter' || e.key===' ') { e.preventDefault(); openLight(btn.dataset.src); } }); }); lightboxClose.addEventListener('click', closeLight); lightbox.addEventListener('click', (e) => { if(e.target === lightbox) closeLight(); }); document.addEventListener('keydown', (e) => { if(e.key === 'Escape' && lightbox.classList.contains('open')) closeLight(); }); // FEATURE MODAL: collect features const featureCards = Array.from(document.querySelectorAll('.feature-card')); const features = featureCards.map(card => { const title = card.querySelector('.feature-title')?.textContent || ''; const excerpt = card.querySelector('.feature-excerpt')?.textContent || ''; const body = card.querySelector('.feature-body'); const full = body?.getAttribute('data-full') || ''; return { title, excerpt, full }; }); const modalOverlay = document.getElementById('featureModal'); const modalTitle = document.getElementById('modal-title'); const modalImg = document.getElementById('modalImg'); const modalDesc = document.getElementById('modalDesc'); const btnClose = document.getElementById('modal-close'); const btnPrev = document.getElementById('modal-prev'); const btnNext = document.getElementById('modal-next'); let currentIndex = 0; function renderFeature(i){ const f = features[i] || {}; modalTitle.textContent = f.title || ''; modalDesc.textContent = f.excerpt || ''; modalImg.src = f.full || ''; modalImg.style.display = f.full ? 'block' : 'none'; } function openModal(i){ if(!features.length) return; currentIndex = (i + features.length) % features.length; renderFeature(currentIndex); modalOverlay.classList.add('open'); modalOverlay.setAttribute('aria-hidden','false'); document.body.style.overflow = 'hidden'; btnClose.focus(); } function closeModal(){ modalOverlay.classList.remove('open'); modalOverlay.setAttribute('aria-hidden','true'); document.body.style.overflow=''; modalImg.src = ''; } featureCards.forEach((card, idx) => { card.addEventListener('click', () => openModal(idx)); card.addEventListener('keydown', e => { if(e.key==='Enter' || e.key===' ') { e.preventDefault(); openModal(idx); } }); }); btnClose.addEventListener('click', closeModal); btnPrev.addEventListener('click', () => openModal((currentIndex - 1 + features.length) % features.length)); btnNext.addEventListener('click', () => openModal((currentIndex + 1) % features.length)); modalOverlay.addEventListener('click', (e) => { if(e.target === modalOverlay) closeModal(); }); document.addEventListener('keydown', (e) => { if(e.key === 'Escape' && modalOverlay.classList.contains('open')) closeModal(); }); })();