- Overview
- Key Features
- Architecture
- Hardware Requirements
- Assembly Instructions
- Software Setup
- Usage
- Advanced Configuration
- Troubleshooting
- Examples and Demos
- Contributions
- License
- Acknowledgments
FungiVue is an open-source, cost-efficient DIY hardware and software kit designed for non-invasive ultrasound imaging of mushroom (mycelium) growth. This project combines affordable off-the-shelf components with modular software to enable real-time monitoring, data visualization, and basic machine learning predictions for growth patterns. It's ideal for educational purposes in biohacking, mycology, and STEM, allowing users to build a functional ultrasound scanner for under $200.
The system uses a duo-cluster of Raspberry Pi Zero 2W boards for distributed processing, an Arduino for sensor data acquisition, and ultrasound transducers for imaging. Data is processed via Python scripts, with optional ML integration using TensorFlow Lite. Results are visualized through a lightweight Vue.js webapp served via NGINX, providing a user-friendly dashboard for scan results.
This repository provides all necessary code, configurations, and documentation. The project is modular, expandable (e.g., add cameras or more sensors), and licensed under MIT for unrestricted use, modification, and distribution.
Project Goals:
- Promote accessible biohacking tools.
- Demonstrate low-cost ultrasound principles.
- Integrate hardware, software, and AI for educational insights.
- Support hobbyists, educators, and researchers in mycology.
For a quick start, see the Installation and Setup Guide (separate document in the repo).
| Feature | Description |
|---|---|
| Ultrasound Imaging | Non-invasive A-scan style imaging using HC-SR04 or similar transducers for depth and growth monitoring. |
| Multi-Sensor Integration | Includes temperature/humidity (DHT22) and optional bio-electric signals for comprehensive data. |
| Duo-Cluster Processing | Two Raspberry Pi Zero 2W units for load balancing: one for data acquisition, one for web hosting/ML. |
| Machine Learning | Lightweight TensorFlow Lite model for growth predictions (e.g., mycelium expansion rate). |
| Vue.js Dashboard | Responsive webapp for viewing time-lapse scans, predictions, and real-time data. |
| Portability Options | NixOS for declarative setups, Docker for containerized environments. |
| No Soldering Required | Plug-and-play assembly with jumper wires and USB connections. |
| Extensibility | Modular code; easy to add features like email alerts or cloud syncing. |
The system follows a layered architecture:
- Hardware Layer: Arduino Uno/Nano collects raw data from sensors (ultrasound, DHT22, bio-electrodes) and sends it via serial to the Raspberry Pi.
- Data Acquisition Layer: Python script on one Pi processes serial data, generates images/plots, and runs ML inferences.
- Processing/Storage Layer: Duo-cluster setup allows distributed tasks; data saved as images/JSON in a shared directory.
- Presentation Layer: Vue.js SPA served by NGINX on the second Pi, fetching and displaying scan results via static files or simple API.
- Optional Layers: NixOS for reproducible environments, Docker for cross-platform testing.
Data Flow:
- Sensors → Arduino Sketch → Serial → Python Script → Images/JSON → Vue.js Webapp (via NGINX).
This design ensures efficiency on low-power hardware like Pi Zero 2W (512MB RAM, 1GHz CPU).
Refer to docs/parts_list.md for sourcing and costs. Key components:
- Raspberry Pi Zero 2W (x2): For duo-cluster; handles processing and web hosting.
- Arduino Uno or Nano (x1): Sensor controller.
- Ultrasonic Transducers (x2): HC-SR04 or equivalents (40kHz-1MHz range).
- DHT22 Sensor (x1): Temperature and humidity monitoring.
- Bio-Electric Electrodes (x2, optional): For mycelium electrical signals.
- USB Hub: For stacking Pis.
- MicroSD Cards (x2, 16GB+): For OS installation.
- Miscellaneous: Jumper wires, power supplies, enclosure (e.g., 3D-printable box), coupling gel for transducers.
Total estimated cost: $150-200.
-
Duo-Cluster Setup:
- Insert flashed MicroSD cards into each Pi.
- Connect Pis via USB hub (one as host, one as peripheral via OTG).
- Power on and verify networking (e.g., ping between static IPs like 192.168.0.1 and 192.168.0.2).
-
Sensor Connections:
- On Arduino:
- Transducer 1: Trig → Pin 9, Echo → Pin 10, VCC → 5V, GND → GND.
- DHT22: Data → Pin 2, VCC → 5V, GND → GND.
- Electrodes (optional): To Analog Pin A1.
- Connect Arduino to host Pi via USB.
- On Arduino:
-
Chamber Assembly:
- Place transducers facing the substrate in an airtight box.
- Apply coupling gel to transducers for improved signal quality.
- Route wires out securely to maintain humidity.
Photos/Diagrams: See docs/assembly_diagrams.md (add if creating visuals).
Test: Power on; use lsusb on Pi to confirm Arduino detection.
- Operating System: Raspberry Pi OS (Lite recommended for efficiency) or NixOS for declarative setups.
- Software:
- Arduino IDE (free from arduino.cc).
- Python 3.8+ (with numpy, matplotlib, tensorflow-lite, serial).
- Node.js/npm (for Vue.js development).
- NGINX (for webapp hosting).
- Tools: Computer with SD card reader, internet access.
Clone the repo to your Pi or development machine:
git clone https://github.com/ALH477/FungiVue.git
cd FungiVue
Install base dependencies for non-NixOS systems (e.g., Raspberry Pi OS):
sudo bash scripts/install-linux-deps.sh
This installs git, Python, pip, Arduino tools, and required Python libraries.
- Install Arduino IDE or CLI on your computer or Pi.
- Upload the Sketch:
- Open
src/arduino/ultrasound_sketch.inoin Arduino IDE. - Select board (Uno/Nano) and port (e.g.,
/dev/ttyUSB0). - Upload the sketch.
- Alternatively, use Arduino CLI on Pi:
arduino-cli upload -p /dev/ttyUSB0 --fqbn arduino:avr:uno src/arduino/ultrasound_sketch.ino
- Open
The sketch uses NewPing and DHT libraries to collect ultrasound distance, temperature, humidity, and optional bio-electric data, sending it via serial (9600 baud) every second.
-
Configure:
- Ensure
src/python/imaging_script.pypoints to the correct serial port (default:/dev/ttyUSB0) and TensorFlow Lite model (growth_model.tflite, assumed in repo). - Dependencies (numpy, matplotlib, serial, tensorflow-lite) are installed via
install-linux-deps.sh.
- Ensure
-
Test:
python3 src/python/imaging_script.py- Reads serial data from Arduino.
- Generates A-scan plots (saved as
scan.pngin/var/www/scans/). - Runs ML predictions for growth rates.
- Outputs data to console and optional CSV.
-
Background Execution:
- Use
screenfor detached sessions:screen -S fungivue python3 src/python/imaging_script.py - Or create a systemd service (see Installation Guide).
- Use
-
Output Configuration:
- Modify script to save images/JSON to
/var/www/scans/for webapp access:sudo mkdir -p /var/www/scans sudo chown -R pi:www-data /var/www/scans - Add JSON output (e.g.,
scans.json) listing images:[{ "url": "/scans/scan_001.png", "name": "Scan 001", "timestamp": "2025-08-07T12:00:00" }].
- Modify script to save images/JSON to
For reproducible, declarative setups:
- Flash NixOS image for Raspberry Pi (from nixos.org).
- Customize
nix/configuration.nixusing:bash scripts/prepare-config.sh- Prompts for features like Docker, graphics, or PipeWire.
- Copy to
/etc/nixos/on the Pi. - Apply:
Or:
sudo bash scripts/apply-nixos-config.shnixos-rebuild switch.
NixOS handles dependencies declaratively, ensuring consistency across builds.
For portable, containerized environments:
- Build:
docker build -t fungivue -f docker/Dockerfile . - Run, mounting Arduino device:
docker run -it --device /dev/ttyUSB0 fungivue - Mount volumes for persistent data (e.g.,
/var/www/scans).
The Dockerfile uses a lightweight Debian base with pre-installed dependencies.
The Vue.js webapp is a single-page application (SPA) built with Vue 3, displaying scan results (images and predictions) in a responsive dashboard. It uses Axios for fetching data and is served statically via NGINX for efficiency on Pi Zero 2W.
-
Create Project:
- Install Vue CLI:
sudo npm install -g @vue/cli - Create app:
vue create fungi-vue-app cd fungi-vue-app npm install axios
- Install Vue CLI:
-
App Code (
src/App.vue):<template> <div id="app"> <h1>FungiVue Ultrasound Scan Dashboard</h1> <p>Displaying latest mushroom growth scans</p> <div v-if="scans.length > 0" class="scan-grid"> <div v-for="(scan, index) in scans" :key="index" class="scan-item"> <img :src="scan.url" :alt="scan.name" width="300" /> <p>{{ scan.name }} - Timestamp: {{ scan.timestamp }}</p> </div> </div> <p v-else>No scans available yet.</p> <button @click="refreshScans">Refresh Scans</button> </div> </template> <script> import axios from 'axios'; export default { data() { return { scans: [], // Array of { url: '/scans/scan_001.png', name: 'Scan 001', timestamp: '2025-08-07' } }; }, mounted() { this.loadScans(); }, methods: { async loadScans() { // For static files, hardcode or fetch from a JSON endpoint // Example: Assume a backend API at /api/scans returns JSON try { const response = await axios.get('/api/sc evidences'); this.scans = response.data; } catch (error) { console.error('Error loading scans:', error); // Fallback to static list if no API this.scans = [ { url: '/scans/scan_001.png', name: 'Scan 001', timestamp: new Date().toISOString() }, // Add more as needed ]; } }, refreshScans() { this.loadScans(); } } }; </script> <style> .scan-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; } .scan-item { border: 1px solid #ccc; padding: 10px; text-align: center; } </style>
-
Main Entry (
src/main.js):import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app');
-
Build for Production:
npm run buildOutputs static files to
dist/. -
Deploy:
sudo mkdir -p /var/www/fungi-vue sudo cp -r dist/* /var/www/fungi-vue/ sudo chown -R www-data:www-data /var/www/fungi-vue -
Integration with Python:
- Modify
imaging_script.pyto generatescans.jsonin/var/www/scans/:import json # After saving scan.png scan_data = [{"url": "/scans/scan_001.png", "name": "Scan 001", "timestamp": "2025-08-07T12:00:00"}] with open('/var/www/scans/scans.json', 'w') as f: json.dump(scan_data, f)
- Alternatively, run a Flask server for dynamic
/api/scans(requirespip install flask).
- Modify
-
Install NGINX:
sudo apt install nginx -y -
Create config (
/etc/nginx/sites-available/fungi-vue):server { listen 80; server_name localhost; root /var/www/fungi-vue; index index.html; location / { try_files $uri $uri/ /index.html; } location /scans/ { alias /var/www/scans/; autoindex on; } location /api/ { proxy_pass http://localhost:5000/; # If using Flask for dynamic API proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } -
Enable and restart:
sudo ln -s /etc/nginx/sites-available/fungi-vue /etc/nginx/sites-enabled/ sudo rm /etc/nginx/sites-enabled/default sudo nginx -t sudo systemctl restart nginx -
Access: Open
http://<pi-ip-address>in a browser to view the dashboard.
- Prepare Substrate: Inoculate mushroom substrate in the chamber.
- Start System:
- Power on Pis and Arduino.
- Run Python script:
python3 src/python/imaging_script.py(or via systemd/screen).
- View Results: Access the Vue.js dashboard at
http://<pi-ip>to see scan images and predictions. - Refresh: Click "Refresh Scans" to update the view.
Duo-Cluster:
- Pi 1: Runs Arduino and Python script for data acquisition.
- Pi 2: Hosts NGINX and Vue.js app, fetching data from shared
/scans/(via NFS or rsync).
- ML Customization: Replace
growth_model.tflitewith a custom-trained model (train on growth datasets using TensorFlow). - Dynamic API: Add Flask to
imaging_script.pyfor real-time/api/scansendpoint. - Networking: Use NFS for shared
/scans/across Pis:sudo apt install nfs-kernel-server # Configure /etc/exports and mount on second Pi - Security: Enable HTTPS with Let's Encrypt:
sudo apt install certbot python3-certbot-nginx sudo certbot --登 - Extensions: Add camera module for visual overlays, email alerts via SMTP, or cloud syncing to Google Drive.
- No Arduino Data: Check port (
dmesg | grep tty), baud rate (9600), group (dialoutviausermod -aG dialout pi). - Webapp Fails: Inspect browser console; verify
/var/www/fungi-vuepaths and permissions (chown www-data). - Low Performance: On Pi Zero, reduce ML batch size; check
free -horhtop. - No Scans Displayed: Ensure
imaging_script.pywrites to/var/www/scans/; check JSON format. - NixOS Errors: Run
nixos-rebuild switch --show-trace; verify config syntax.
Logs: Check /var/log/nginx/error.log or Python stdout.
- Demo Video: [Placeholder for YouTube link].
Contributions are welcome! Fork the repo, create issues/PRs for:
- Cost optimizations (e.g., cheaper transducers).
- New sensors (e.g., CO2 monitors).
- UI enhancements (e.g., real-time charts). Follow code style: ESLint for JS, Black for Python. Use issue templates in repo.
MIT License. See LICENSE for details.
Copyright (c) 2025 [DeMoD LLC].
- Inspired by biohacking and mycology communities.
- Thanks to NewPing, DHT, Vue.js, and TensorFlow Lite developers.
- Gratitude to contributors and testers.
