Microcontroller-Regulated Eggshell Grinder and Reactor for Efficient Calcium Acetate Fertilizer Synthesis π±βοΈ
An automated Arduino-based system that grinds eggshells to precise weights and reacts them with vinegar to produce calcium acetate fertilizer, with intelligent monitoring and control throughout the entire synthesis process.
- About
- Features
- How It Works
- Hardware Requirements
- Software Requirements
- Installation
- Usage
- Project Structure
- Configuration
- API Reference
- LCD Integration
- Contributing
- License
- Author
This project implements a complete automated synthesis system for calcium acetate fertilizer production. The microcontroller regulates an eggshell grinding process to achieve precise weight measurements, followed by automated vinegar addition in optimal ratios, and continuous monitoring of the exothermic reaction until completion.
Chemical Reaction: CaCOβ (egg shells) + 2CHβCOOH (vinegar) β Ca(CHβCOO)β (calcium acetate) + HβO + COβ
Key Features:
- Precision grinding with real-time weight feedback
- Automated 1:12 ratio vinegar addition
- Reaction monitoring until bubbling cessation
- Temperature stabilization at ~39Β°C
- Complete process automation with LCD user interface
- Precision Grinding: Automated eggshell grinding to exact weight specifications
- Intelligent Ratio Control: Automated 1:12 eggshell-to-vinegar ratio addition
- Reaction Monitoring: Continuous tracking until bubbling stops and temperature stabilizes
- Complete Process Automation: From grinding to final product with minimal user intervention
- Temperature Sensing: DS18B20 sensor tracking reaction temperature (target: ~39Β°C)
- Weight Measurement: HX711 load cell for precise grinding and ratio control
- pH Level Detection: Analog pH sensor monitoring reaction progress
- Serial Output: Real-time data logging and display
- Grinding Motor Control: SSR-controlled motor for eggshell grinding
- Automated Pumping: Relay-controlled pump for precise vinegar addition
- LCD User Interface: I2C LCD for process status and user input
- Button Input System: User controls for process initiation and parameter input
- Dual Relay Control: SSR and regular relays for mixing operations
- LCD Display: I2C LCD for local status visualization (configurable)
- Power Management: Sleep/wake functionality for energy efficiency
- Modular Design: Separate configuration files for each component
- Centralized Pin Management: All hardware pins defined in one location
- Extensible Codebase: Easy to add new sensors or actuators
START
β
Put Eggshell β Press Start Button β LCD Shows Message
β
Input Desired Grams (g) to Grind β Loadcell Ready
β
Motor ON (Grinding Starts)
β
ββ Decision: Loadcell = Desired Weight?
β NO β Continue Grinding (Motor ON)
ββ YES β Motor OFF β Pump ON
β
Pump Runs Until 1:12 Ratio Achieved
β
Monitor Solution (Temperature & pH)
β
Store Data & Continue Monitoring
β
Until Bubbling Stops & Temp β 39Β°C
β
END (Fertilizer Ready)
- System Initialization: Arduino boots up, initializes sensors and LCD
- Eggshell Loading: User places eggshells in grinding chamber
- Process Start: User presses button to begin synthesis
- Parameter Input: LCD prompts for desired eggshell weight in grams
- Grinding Phase: Motor activates, load cell monitors weight in real-time
- Weight Verification: System checks if target weight is achieved
- Grinding Completion: Motor stops when desired weight is reached
- Vinegar Addition: Pump activates to add vinegar in 1:2 ratio
- Reaction Monitoring: Continuous temperature and pH monitoring begins
- Data Logging: All sensor readings stored and displayed
- Completion Detection: Process continues until bubbling stops and temperature stabilizes at ~39Β°C
- System Shutdown: Automatic completion when reaction is finished
- Grinding Control: SSR Relay (Pin 23) controls grinding motor with weight feedback
- Pumping Control: Regular Relay (Pin 22) controls vinegar pump with ratio feedback
- Reaction Endpoints: Process completes when COβ evolution ceases and temperature peaks
- Safety Monitoring: Continuous parameter checking prevents unsafe conditions
- Arduino Board (Uno, Mega, or compatible)
- DS18B20 Temperature Sensor
- HX711 Load Cell Amplifier + Load Cell (for weight measurement)
- Analog pH Sensor Module
- I2C LCD Display (16x2 or 20x4)
- Momentary Push Button (for process initiation)
- DC Motor (for eggshell grinding)
- Peristaltic Pump (for vinegar addition)
- 2-Channel Relay Module (Regular + SSR for motor/pump control)
- Grinding Chamber: Container for eggshell grinding
- Reaction Vessel: Container for fertilizer synthesis
- Load Cell Mounting: Proper setup for weight measurement
- Tubing System: For vinegar transfer from pump to reaction vessel
DS18B20 Sensor -> Pin 2 (DATA; VCC -> 3.3V; GND -> GND; 4.7kΞ© pull-up resistor between DATA and VCC)
HX711 DT -> Pin 4
HX711 SCK -> Pin 3
pH Sensor -> A0
LCD I2C -> I2C pins (SDA, SCL)
Buttons -> Pins 24 (Start), 5 (Stop), 6 (Calibrate)
Grinding Motor -> Pin 23 (via SSR Relay)
Vinegar Pump -> Pin 22 (via Regular Relay)
SD Card CS -> Pin 53 (Arduino Mega)
The Fritzing file is available at wiring/SmartMixer.fzz
- Version: 1.8.19 or higher
- Board: Arduino Uno/Mega (or compatible)
Install via Arduino Library Manager:
OneWireby Paul StoffregenDallasTemperatureby Miles BurtonLiquidCrystal_I2Cby Marco SchwartzHX711by Bogdan Necula
-
Clone the Repository
git clone https://github.com/qppd/Smart-Mixer.git cd Smart-Mixer -
Open Arduino IDE
- Navigate to
src/arduino/SmartMixer/SmartMixer.ino - Open the file in Arduino IDE
- Navigate to
-
Install Required Libraries
- Go to
Sketch > Include Library > Manage Libraries - Search and install:
- OneWire
- DallasTemperature
- LiquidCrystal_I2C
- HX711
- Go to
-
Configure Hardware
- Connect sensors according to pin configuration
- Verify power supplies for all components
-
Upload Code
- Select correct board and port
- Click Upload button
- System Setup: Power on Arduino, ensure all sensors are connected
- Load Eggshells: Place eggshells in the grinding chamber on the load cell
- Start Process: Press the start button to initiate synthesis
- Parameter Input: LCD displays "Enter weight (g):", use buttons to input desired grams
- Grinding Phase: Motor activates, grinding continues until target weight is reached
- Weight Verification: System automatically stops grinding when load cell measures desired weight
- Vinegar Addition: Pump activates to add vinegar in 1:12 ratio to eggshell weight
- Reaction Monitoring: System continuously monitors temperature and pH
- Data Logging: All readings displayed on Serial Monitor and optionally LCD
- Completion Detection: Process ends when bubbling stops and temperature stabilizes at ~39Β°C
Temperature: 39.20Β°C --- Weight: 150.00g --- pH: 4.80 --- Status: REACTING
Temperature: 39.50Β°C --- Weight: 450.00g --- pH: 5.20 --- Status: COMPLETE
- Grinding Weight: User-defined (typically 100-200g eggshells)
- Vinegar Ratio: Automatic 1:12 eggshell-to-vinegar ratio
- Reaction Temperature: Target ~39Β°C (normal temperature change)
- Completion Criteria: Bubbling cessation + temperature stabilization
- Monitoring Duration: Continuous until reaction completion
// Start grinding motor
operateSSR(RELAY_GRINDER, true);
// Check if target weight reached
if (getLOADCELLWeight() >= targetWeight) {
operateSSR(RELAY_GRINDER, false); // Stop grinding
operateRELAY(RELAY_PUMP, true); // Start vinegar pump
}
// Monitor reaction completion
if (getPHValue() >= 4.5 && getDS18B20Temperature(false) >= 38.0) {
// Reaction complete - stop all operations
operateRELAY(RELAY_PUMP, false);
}The LCD is always active from startup. It automatically shows the appropriate screen for each process state. See the LCD Integration section for full layout details.
Smart-Mixer/
βββ LICENSE
βββ README.md
βββ src/
βββ arduino/
βββ SmartMixer/
βββ SmartMixer.ino # Main Arduino sketch
βββ PINS_CONFIG.h # Hardware pin definitions
βββ DS18B20_CONFIG.h/.cpp # Temperature sensor (DS18B20)
βββ HX711_CONFIG.h/.cpp # Load cell amplifier
βββ PH_CONFIG.h/.cpp # pH sensor
βββ LCD_CONFIG.h/.cpp # LCD display
βββ RELAY_CONFIG.h/.cpp # Relay control
βββ SD_CONFIG.h/.cpp # SD card logging
βββ BUTTON_CONFIG.h/.cpp # 3-button input handling
SD_CONFIG.*: SD card logging and storageBUTTON_CONFIG.*: Three-button input handling with debounce
- Target Grinding Weight: User-defined (100-200g recommended)
- Vinegar Ratio: 1:12 eggshell-to-vinegar (automatic calculation)
- Reaction Temperature: ~39Β°C (normal temperature increase)
- Completion Criteria: Bubbling cessation + temperature stabilization
- Safety Limits: Max 45Β°C, Min pH 4.0, Max weight 500g
- HX711 Scale Factor:
22500.3f(adjust for your load cell) - pH Calibration:
21.34(calibrate with pH 4.0 and 7.0 buffers)
Edit PINS_CONFIG.h to modify hardware connections:
#define TEMP_SENSOR_PIN 2 // Temperature sensor
#define HX711_DT 4 // Load cell data
#define HX711_SCK 3 // Load cell clock
#define PH_PIN A0 // pH sensor analog input
#define BUTTON_START 24 // Start button
#define BUTTON_STOP 5 // Stop button
#define BUTTON_CALIBRATE 6 // Calibrate button
#define SD_CS 53 // SD card chip select (Arduino Mega)
#define RELAY_GRINDER 23 // Grinding motor relay (SSR)
#define RELAY_PUMP 22 // Vinegar pump relay (regular)- DS18B20: Single-wire digital temperature sensor on Pin 2
- pH Sampling: 10 readings with median filtering for noise reduction
- Weight Averaging: 10-sample moving average for stability
- Button Debouncing: 50ms debounce delay
- LCD Refresh Rate: 500ms non-blocking update interval (
LCD_UPDATE_INTERVAL)
The Smart Mixer uses an I2C LCD (16 columns Γ 4 rows) at address 0x27 as the primary user interface, showing real-time sensor data, process status, and menu prompts throughout every stage of operation. The LCD is always initialised in setup() and never requires a manual enable command.
ββββββββββββββββββ
ββ Smart Mixer β Row 0 β mixer icon + project title
βCa-Acetate Synthβ Row 1 β process description
ββSTART βCALIB β Row 2 β button hints with arrow icons
β System Ready β Row 3 β system status
ββββββββββββββββββ
ββββββββββββββββββ
β== CALIBRATE == β Row 0 β mode header
βRemove weight! β Row 1 β current step prompt (updates per step)
βFactor:22500.3 β Row 2 β calibration factor (live)
βPress to confirmβ Row 3 β action hint
ββββββββββββββββββ
Steps cycle: Remove weight! β Taring scale... β Place 100g... β Calibrating... β Done!
ββββββββββββββββββ
β== SET TARGET ==β Row 0 β mode header
βEgg: 50.0g β Row 1 β confirmed eggshell target
βVin:600.0g β Row 2 β auto-calculated vinegar (1:12 ratio)
β Waiting input..β Row 3 β status
ββββββββββββββββββ
ββββββββββββββββββ
β== GRINDING == β Row 0 β stage header
βCur:45.2g/50.0g β Row 1 β current weight / target weight
βProgress: 90% β Row 2 β completion percentage
βGND:ON [STOP] β Row 3 β grinder state + stop hint
ββββββββββββββββββ
ββββββββββββββββββ
β= DISPENSING =β Row 0 β stage header
βD:45.2g/600.0g β Row 1 β dispensed / target vinegar
βPID Out: 85% β Row 2 β PID controller output percentage
βPMP:ON [STOP] β Row 3 β pump state + stop hint
ββββββββββββββββββ
ββββββββββββββββββ
βT:25.4Β°C pH:7.20β Row 0 β temperature (Β°) + pH
βW: 720g D: 600gβ Row 1 β total weight + dispensed vinegar
βGND:OFF PMP:OFF β Row 2 β actuator states
β00:05:30 Active β Row 3 β elapsed time HH:MM:SS + phase
ββββββββββββββββββ
The degree symbol Β° is rendered as a custom CGRAM character for crisp display.
ββββββββββββββββββ
ββ COMPLETE! β Row 0 β check icon + completion
βT:24.5Β°C pH:6.80β Row 1 β final temperature + pH
βW: 720g SD:OK β Row 2 β final weight + SD card status
β Press START β Row 3 β restart hint
ββββββββββββββββββ
SD:OK or SD:ERR reflects the result of the last CSV write.
ββββββββββββββββββ
ββ² !! ERROR !! β Row 0 β blinking alert (600 ms period)
βCheck sensors! β Row 1 β error description
βActuators: OFF β Row 2 β safety confirmation
βCheck & Restart β Row 3 β corrective hint
ββββββββββββββββββ
Row 0 blinks on/off every 600 ms using a non-blocking millis() timer.
ββββββββββββββββββ
ββ²EMERGENCY STOP!β Row 0 β alert icon + label
βGrinder:OFF β Row 1 β grinder state
βPump: OFF β Row 2 β pump state
β Press START β Row 3 β restart hint
ββββββββββββββββββ
When any button is pressed, row 3 instantly updates for ~500 ms:
- START β
βSTART pressed! - STOP β
βSTOP pressed! - CALIB β
βCALIB pressed!
The next scheduled display refresh overwrites this automatically, creating a brief visual acknowledgement without any blocking delay.
| Index | Symbol | Usage |
|---|---|---|
CHAR_DEGREE (0) |
Β° |
Temperature unit in monitoring/complete screens |
CHAR_ALERT (1) |
β² |
Error screen row 0 and emergency stop |
CHAR_CHECK (2) |
β |
Complete screen row 0 |
CHAR_ARROW_R (3) |
β |
Idle button hints and button feedback |
CHAR_MIXER (4) |
β |
Idle splash screen title |
All periodic LCD updates are gated by lcdShouldUpdate(), which returns true at most once per LCD_UPDATE_INTERVAL (500 ms). This ensures:
- No flicker from redundant writes
- Sensor reads and actuator control are never delayed by display logic
- Button feedback bypasses the gate for immediate visual response
To add readings from a future sensor:
- Add a new display function in
LCD_CONFIG.cppfollowing the existing patterns. - Declare the prototype in
LCD_CONFIG.h. - Call the function from the relevant state handler in
SmartMixer.inoinside anif (lcdShouldUpdate())block.
void initDS18B20(); // Initialize DS18B20 sensor
float getDS18B20Temperature(boolean fahrenheit); // Get temperature (-1 on error)void initLOADCELL(); // Initialize HX711
float getLOADCELLWeight(); // Get weight reading
void operateHX711sleep(); // Put HX711 to sleep
void operateHX711wake(); // Wake HX711float getPHValue(); // Get filtered pH readingvoid initLCD(); // Init LCD, load custom chars
void clearLCD(); // Clear all rows
void setLCDText(String text, int col, int row); // Write text at position
void setLCDText(float value, int col, int row); // Write float at position
bool lcdShouldUpdate(); // Non-blocking 500 ms gate
// State-specific full-screen display functions
void lcdDisplayIdle(); // Splash / idle screen
void lcdDisplayCalibration(const char* step, float cf); // Calibration prompts
void lcdDisplayInputTarget(float eggG, float vinG); // Target weight input
void lcdDisplayGrinding(float cur, float tgt, bool on); // Grinding progress
void lcdDisplayDispensing(float disp, float tgt,
bool on, int pidPct); // Dispensing progress
void lcdDisplayMonitoring(float temp, float ph,
float weight, float dispensed,
bool gOn, bool pOn, unsigned long elapsedMs); // Reaction dashboard
void lcdDisplayComplete(float wt, float t,
float ph, bool sdOk); // Completion summary
void lcdDisplayError(const char* msg); // Blinking error screen
void lcdDisplayEmergencyStop(); // E-stop overlay
void lcdDisplayButtonFeedback(int buttonIndex); // Brief button flashvoid initRELAY(); // Initialize relays
void operateRELAY(uint16_t relay, boolean state); // Control regular relay
void operateSSR(uint16_t relay, boolean state); // Control SSRWe welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Follow Arduino coding standards
- Add comments to complex logic
- Test hardware compatibility
- Update documentation
This project is licensed under the MIT License - see the LICENSE file for details.
Sajed Lopez Mendoza
- GitHub: @qppd
- Project: Smart-Mixer
β Star this repository if you find it useful!
For questions or support, please open an issue on GitHub.



