AquaMesh: Engineering an IoT-Enabled Biomimetic Fog Harvester
by Vihaan Punjabi in Circuits > Arduino
40 Views, 1 Favorites, 0 Comments
AquaMesh: Engineering an IoT-Enabled Biomimetic Fog Harvester
What does a better future look like? To me, it appears to be a world where clean drinking water is accessible to everyone, regardless of their geographical location. As climate change creates big droughts, particularly in coastal and arid regions, we need solutions to water scarcity. Here is the solution: Fog is basically a ground-level cloud made of billions of microscopic liquid water droplets suspended in the air. The solution to this issue is to supply water to those in need by collecting water from fog.
Welcome to AquaMesh. This project changes traditional fog harvesting nets by utilizing an engineered surface topology, a 3D-printed geometric structure optimized for condensation, paired with a smart IoT backend.
By integrating environmental sensors and a machine learning model to predict peak atmospheric moisture, the system automatically adjusts its orientation to maximize water collection. While being quite conceptual, in some parts of the project, due to constraints, this Instructable will guide you through modeling the surfaces, wiring the sensors, and deploying the automation code. Let's build a future where innovation fixes the world's thirst.
Supplies
Hardware & Fabrication:
- 3D Printer
- PETG or ASA Filament, PLA works for short testing
- Custom-cut aluminum framing and brackets
- Assorted M3/M4 fasteners and T-nuts
- Food-safe silicone tubing and a glass collection beaker (If testi)
Electronics & Software:
- Arduino Uno microcontroller
- Sixfab IoT Cellular module
- DHT22 Temperature & Humidity Sensor
- Water level/flow sensor
- 4x SG90 Micro Servo Motors
- Breadboard and jumper wires
- Autodesk Fusion 360 (for CAD design)
- Python environment with pandas and scikit-learn libraries (plus a laptop)
Designing the Engineered Surface in Autodesk
Open Autodesk Fusion 360 to design a panel with alternating hydrophilic bumps to catch micro-droplets and hydrophobic channels to drain them rapidly.
Start by sketching a 150mm x 150mm base plate. Use the Pattern tool to create an array of 2mm spherical domes across the surface. Once your domes are set, sweep shallow channels between them, angled downwards at a 15-degree pitch to direct gravity flow toward a central collection funnel at the bottom edge. Export the final body as a STL file.
3D Printing and Mechanical Assembly
Once your CAD is finalized, slice the STL files. Print the panel using PETG or ASA filament for UV and water resistance, and if just testing and trying a bit, use PLA. Set your infill to at least 40% for structural rigidity against wind, if it is to be used.
While the panel prints, assemble your aluminum extrusions to create a stable A-frame or pivot mount. Mount the four SG90 micro servos at the pivot joints of the frame. Once the 3D print is finished, attach the geometric panel to the servo brackets, making sure that the collection funnel sits perfectly above where your silicone tubing will go.
Wiring the IoT
The Arduino Uno serves as the central controller. First, connect the DHT22 sensor to measure ambient temperature and humidity. Next, place the water level sensor inside your collection basin and wire it back to the Arduino. If you need help with wiring, reference the picture above or use online examples of how to wire each of the things.
To enable remote monitoring, attach the Sixfab IoT cellular module. Activate it using their website and the sim card that comes with it. This allows the harvester to transmit environmental data to a cloud dashboard, bypassing the need for Wi-Fi in remote, off-grid areas. Finally, wire the four SG90 servo motors to the Arduino's PWM pins so the board can control the tilt and angle of the panel.
Machine Learning & Automation
Using a Python script on your computer, load this historical data using the pandas library. Train a classification model, such as a RandomForestClassifier from scikit-learn, to recognize the specific atmospheric conditions and temperature drops that precede heavy fog rolls. Once the model is trained, it pushes predictive signals back to the Arduino via the cellular connection. When the sensors detect an incoming fog bank, the Arduino triggers the servos, angling the panels directly into the optimal wind path just before the moisture arrives, maximizing aerodynamic capture.
Plug in the arduino in your computer, as well as make sure the hat works and can transfer data to your computer.
Some example code for the arduino would be:
#include <DHT.h>
#include <Servo.h>
#include <SoftwareSerial.h>
// ==========================================
// AQUAMESH: ARDUINO SENSOR & SERVO CONTROL
// ==========================================
// --- Pin Definitions ---
#define DHTPIN 2 // DHT22 data pin connected to Digital Pin 2
#define DHTTYPE DHT22 // Specify the sensor type
#define WATER_SENSOR A0 // Water level sensor connected to Analog Pin A0
// Sixfab Cellular Module connected via SoftwareSerial (RX, TX)
SoftwareSerial SixfabSerial(10, 11);
// Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE);
// Initialize the 4 SG90 Servos
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
// --- Variables ---
float temperature = 0.0;
float humidity = 0.0;
int waterLevel = 0;
unsigned long lastUpdate = 0;
const long updateInterval = 10000; // Read sensors every 10 seconds
void setup() {
// Start serial communication for computer debugging
Serial.begin(9600);
// Start serial communication with Sixfab cellular module
SixfabSerial.begin(9600);
Serial.println("AquaMesh System Initializing...");
// Start DHT sensor
dht.begin();
// Attach servos to Arduino PWM pins
servo1.attach(3);
servo2.attach(5);
servo3.attach(6);
servo4.attach(9);
// Set panels to default/flat position (0 degrees)
resetPanels();
Serial.println("System Ready.");
}
void loop() {
unsigned long currentMillis = millis();
// 1. READ SENSORS & TRANSMIT DATA
if (currentMillis - lastUpdate >= updateInterval) {
lastUpdate = currentMillis;
// Read temperature and humidity
humidity = dht.readHumidity();
temperature = dht.readTemperature();
// Read water collection level
waterLevel = analogRead(WATER_SENSOR);
// Check if any reads failed
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
} else {
// Print to local serial monitor for debugging
Serial.print("Temp: ");
Serial.print(temperature);
Serial.print("C | Humidity: ");
Serial.print(humidity);
Serial.print("% | Water Level: ");
Serial.println(waterLevel);
// Format data and send to Sixfab module to transmit to cloud
// (Using simple CSV format for the Python script to catch)
SixfabSerial.print("DATA,");
SixfabSerial.print(temperature);
SixfabSerial.print(",");
SixfabSerial.print(humidity);
SixfabSerial.print(",");
SixfabSerial.println(waterLevel);
}
}
// 2. LISTEN FOR PREDICTIVE COMMANDS
// Check if the Sixfab module has received a command from the Python ML script
if (SixfabSerial.available()) {
String command = SixfabSerial.readStringUntil('\n');
command.trim(); // Remove any whitespace or newline characters
if (command == "DEPLOY_PANELS") {
Serial.println("COMMAND RECEIVED: Deploying panels to optimal fog catch angle!");
deployPanels();
}
else if (command == "STANDBY") {
Serial.println("COMMAND RECEIVED: Returning panels to standby flat position.");
resetPanels();
}
}
}
// --- Custom Functions ---
void deployPanels() {
// Move all servos to a 45-degree angle to catch the incoming wind/fog
int targetAngle = 45;
servo1.write(targetAngle);
servo2.write(targetAngle);
servo3.write(targetAngle);
servo4.write(targetAngle);
delay(1000); // Give servos time to move
}
void resetPanels() {
// Return all servos to flat (0 degrees)
int flatAngle = 0;
servo1.write(flatAngle);
servo2.write(flatAngle);
servo3.write(flatAngle);
servo4.write(flatAngle);
delay(1000);
}
And for the Python part using machine learning:
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import requests
import time
# ==========================================
# AQUAMESH: FOG PREDICTION & AUTOMATION
# ==========================================
# 1. LOAD THE HISTORICAL DATA
# This CSV would be generated by your Arduino/Sixfab module over a few weeks.
# Columns should include: 'Temperature_C', 'Humidity_Percent', 'Time_of_Day', 'Fog_Event_Occurred'
print("Loading environmental telemetry data...")
try:
data = pd.read_csv('aquamesh_telemetry_log.csv')
except FileNotFoundError:
print("Error: Telemetry CSV not found. Ensure the Sixfab module is logging data.")
exit()
# 2. PREPARE THE DATA FOR MACHINE LEARNING
# Features (Inputs): What the sensors are reading
X = data[['Temperature_C', 'Humidity_Percent', 'Time_of_Day']]
# Target (Output): 1 if fog happened, 0 if it didn't
y = data['Fog_Event_Occurred']
# Split the data to test the model's accuracy
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 3. TRAIN THE RANDOM FOREST CLASSIFIER
print("Training the predictive model...")
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)
# (Optional) Check how accurate the model is
predictions = rf_model.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
print(f"Model trained with {accuracy * 100:.2f}% accuracy.")
# 4. LIVE AUTOMATION LOOP
# In a real deployment, this loop runs continuously, grabbing live data
# from your cloud dashboard and deciding whether to move the servos.
ARDUINO_ENDPOINT = "http://YOUR_SIXFAB_IP_ADDRESS/trigger_servos"
print("Initiating live monitoring...")
while True:
# Example: Fetching live data from your cloud API (Replace with your actual API call)
# live_data = requests.get("http://YOUR_CLOUD_DASHBOARD/api/live_sensors").json()
# Simulated live sensor readings for demonstration
current_temp = 14.5
current_humidity = 92.0
current_time = 6.5 # 6:30 AM
# Ask the model: Will there be fog right now based on these readings?
live_features = pd.DataFrame([[current_temp, current_humidity, current_time]],
columns=['Temperature_C', 'Humidity_Percent', 'Time_of_Day'])
fog_prediction = rf_model.predict(live_features)
if fog_prediction[0] == 1:
print("PREDICTION: Fog imminent! Sending activation signal to AquaMesh.")
# Send a signal to the cellular module to trigger the Arduino's servos
try:
response = requests.post(ARDUINO_ENDPOINT, data={'command': 'DEPLOY_PANELS'})
if response.status_code == 200:
print("Success: Panels deployed to optimal angle.")
else:
print("Failed to reach AquaMesh.")
except requests.exceptions.RequestException as e:
print(f"Connection Error: {e}")
# Wait before checking again to avoid spamming the motors
time.sleep(3600)
else:
print("PREDICTION: Clear conditions. Panels remain in standby.")
time.sleep(600) # Check again in 10 minutes
Field Testing
Attach the food-safe silicone tubing to the bottom spout of the 3D-printed panel and route it into your collection beaker. Take your assembled AquaMesh prototype outside to a high-moisture area. Monitor the dashboard as the humidity rises and watch the servos automatically adjust the panel array to face the ideal direction.
Understanding the Simulation Controls:
- Environment:
- Temperature & Humidity: These sliders mimic the data coming from the DHT22 sensor. High humidity and a specific temperature drop are the key triggers for fog.
- Automation Logic:
- Target Time of Day: Your machine learning model will predict peak fog hours. You can set a 'target' time (e.g., late night/early morning).
- Current Time: This slider lets you simulate the progression of the day.
- Observing the System Response:
- Water Level: This bar reflects the state of your water sensor. In a real scenario, this value would increase after the servos activate and the panel starts collecting water.
- Servo Activation & Panel Status: This section shows if the system has been triggered and the resulting action.
- Panel Tilt Angle: When the predictive logic is met (Target Time = Current Time, and/or specific environmental conditions), the four SG90 micro servo motors will angle the geometric panel for optimal collection. The simulation indicates this angle.
- Data Status: Shows when telemetry (environmental data, collection volume) is being transmitted via the Sixfab cellular module. This happens periodically, but also immediately upon a trigger event.
Connecting the Simulation to the Real-World Circuit
While the simulation is abstract, it demonstrates the behavior of the actual components and code. When you build the circuit based on the diagram from Step 3, this is what is happening:
- Sensing: The Arduino continuously polls the DHT22 sensor for temperature and humidity, and the water level sensor for any collected volume.
- Logic & Prediction (Arduino Code): Your Arduino code, perhaps with the machine learning model's triggers uploaded as parameters, will process this data.
- Action: When the 'trigger' conditions are met (high predicted probability of fog based on time and/or sensor data), the Arduino sends a signal to the Sensor Management Board.
- Physical Actuation: The Sensor Management Board distributes power and sends the exact PWM signals to all four SG90 servos, causing them to move the panel to the pre-determined optimal angle.
- Telemetry: Periodically, and upon any significant change (like servo activation), the Arduino formats the current status and sends it to the Sixfab cellular module. The module then transmits this data to your cloud dashboard.
Conclusion
By combining biomimetic geometry with IoT tracking and machine learning, we can drastically improve the efficiency of atmospheric water generation. This prototype proves that with accessible fabrication tools, smart coding, and a bit of ingenuity, communities can engineer their own decentralized water solutions. Let's build a future where innovation quenches the world's thirst. I want to highlight there were a lot of limitations in this project, including money, which made part of it conceptual, but tested to work. Thanks for reading, and hope you all have fun making this. Let me know of anything I can add on and any issues. Please like and comment if you enjoyed it or if you have anything to say!