Introduction to Farm Data Visualization
π Farm Data Visualization - From Raw Numbers to Smart Decisions
π What You'll Learn in This Lesson:
- π Turn raw sensor data into actionable visual insights
- π Choose the right chart type for each farm decision
- β οΈ Spot problems instantly with visual pattern recognition
- π° Save water and increase yields using data visualization
- πΎ Build your own farm dashboard from scratch
π Why Visualize Farm Data?
| Without Visualization | With Visualization |
|---|---|
| β Stare at confusing numbers: "45, 47, 46, 44, 73, 42..." | β See instantly: "Spike at 12 PM - sensor error?" |
| β Hard to spot gradual drying trends | β Line chart shows "moisture dropping 5% daily" |
| β Can't compare zones easily | β Bar chart: "Zone A is drier than Zone B" |
| β Workers struggle to understand data | β Green = good, Red = problem - everyone understands! |
Your brain processes visual information 60,000x faster than text. A well-designed chart can communicate in seconds what would take minutes to explain with numbers!
π Key Visualization Types for Farms
Line Chart
Best for: Trends over time
Shows how moisture, temperature, or humidity changes across hours, days, or seasons.
Bar Chart
Best for: Comparing values
Compare water usage across zones, yields by crop type, or moisture between fields.
Gauge Chart
Best for: Single value vs target
Shows current reading against optimal range - red/yellow/green zones.
Heat Map
Best for: Field variability
Color-coded map shows which parts of your field are dry, wet, or optimal.
Scatter Plot
Best for: Correlations
Shows relationship between two variables - moisture vs yield, temperature vs growth.
Calendar Heatmap
Best for: Daily patterns
Color-coded calendar shows daily irrigation amounts or moisture levels.
π The Farm Dashboard: What to Monitor Daily
| Metric | Chart Type | What to Look For | Action if Abnormal |
|---|---|---|---|
| π§ Soil Moisture | Line + Gauge | Dropping below 35% or spiking above 80% | Irrigate if dry, check drainage if wet |
| π‘οΈ Temperature | Line Chart | Daily peaks >35Β°C or night temps >25Β°C | Increase ventilation, shade cloth |
| π§ Humidity | Line Chart | >85% (mold risk) or <30% (stress) | Ventilate if humid, mist if dry |
| π§ Water Usage | Bar Chart | Sudden spike or zone imbalance | Check for leaks, adjust schedule |
| π VPD | Line + Gauge | Outside 0.8-1.2 kPa range | Adjust temp/humidity |
| πΎ GDD Accumulation | Progress Bar | Behind schedule vs expected | Adjust harvest expectations |
π¨ Dashboard Design Best Practices
π Rules for Effective Farm Dashboards:
- π΄ RED = Problem: Moisture <30%, Temperature >38Β°C, Humidity >85%
- π‘ YELLOW = Warning: Moisture 30-40%, Temperature 32-38Β°C
- π’ GREEN = Good: Moisture 40-70%, Temperature 20-30Β°C
- π One screen view: Most important metrics visible without scrolling
- π Auto-refresh: Update every 5-15 minutes for real-time monitoring
- π± Mobile friendly: Check from your phone anywhere on the farm
π» Arduino Code: Send Formatted Data for Visualization
/* * Farm Data Logger for Visualization * Formats data for dashboard display * * Sends: soil moisture, temperature, humidity, VPD, timestamp * Compatible with OceanRemote dashboard */ #include#include #include #include #define DHTPIN 4 #define DHTTYPE DHT22 #define SOIL_PIN 32 DHT dht(DHTPIN, DHTTYPE); // WiFi credentials const char* ssid = "YOUR_WIFI"; const char* password = "YOUR_PASSWORD"; // OceanRemote API const char* token = "YOUR_DEVICE_TOKEN"; const char* apiEndpoint = "https://api.oceanremote.net/device/state"; // Sensor calibration const int DRY_VALUE = 3800; const int WET_VALUE = 1500; // Data storage for charts const int MAX_READINGS = 168; // Store 7 days of hourly data float moistureHistory[MAX_READINGS]; float tempHistory[MAX_READINGS]; float humidityHistory[MAX_READINGS]; int historyIndex = 0; int historyCount = 0; // Calculate VPD (Vapor Pressure Deficit) float calculateVPD(float temp, float humidity) { float es = 0.6108 * exp((17.27 * temp) / (temp + 237.3)); float ea = es * (humidity / 100.0); return es - ea; } // Read soil moisture percentage int readSoilMoisture() { int raw = analogRead(SOIL_PIN); int percentage = map(raw, DRY_VALUE, WET_VALUE, 0, 100); return constrain(percentage, 0, 100); } // Determine status color for dashboard String getStatusColor(int moisture) { if (moisture < 30) return "red"; if (moisture < 40) return "yellow"; return "green"; } // Get recommendation text String getRecommendation(int moisture, float temp, float vpd, float humidity) { if (moisture < 30) { return "π¨ CRITICAL: Soil too dry - Irrigate immediately!"; } else if (moisture < 40) { return "β οΈ WARNING: Soil drying - Plan irrigation today"; } else if (moisture > 80) { return "β οΈ WARNING: Soil too wet - Stop irrigation, check drainage"; } if (temp > 38) { return "π₯ HEAT STRESS: Increase ventilation, provide shade"; } else if (temp > 32) { return "βοΈ High temperature - Monitor closely"; } if (humidity > 85) { return "π§ HIGH HUMIDITY: Risk of mold - Ventilate immediately"; } else if (humidity < 30) { return "π΅ LOW HUMIDITY: Plants stressed - Consider misting"; } if (vpd < 0.4) { return "π LOW VPD: Mold risk - Increase ventilation"; } else if (vpd > 1.5) { return "π₯ HIGH VPD: Plants closing stomata - Increase humidity"; } return "β OPTIMAL: All conditions normal"; } // Send data to OceanRemote dashboard void sendToCloud(int moisture, float temp, float humidity, float vpd) { if (WiFi.status() != WL_CONNECTED) return; HTTPClient http; http.begin(apiEndpoint); http.addHeader("Content-Type", "application/x-www-form-urlencoded"); String data = "token=" + String(token); data += "&soil_moisture=" + String(moisture); data += "&temperature=" + String(temp); data += "&humidity=" + String(humidity); data += "&vpd=" + String(vpd); data += "&status=" + getStatusColor(moisture); data += "&recommendation=" + getRecommendation(moisture, temp, vpd, humidity); int httpCode = http.POST(data); if (httpCode == 200) { Serial.println("β Data sent to dashboard"); } http.end(); } // Generate dashboard HTML for local display (no cloud needed) void generateLocalDashboard(int moisture, float temp, float humidity, float vpd) { Serial.println("\nββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"); Serial.println("β πΎ FARM DASHBOARD β"); Serial.println("β " + String(__TIME__) + " β"); Serial.println("β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£"); // Soil moisture gauge Serial.print("β π§ SOIL MOISTURE: "); Serial.print(moisture); Serial.print("% "); int bars = moisture / 10; for (int i = 0; i < 10; i++) { if (i < bars) Serial.print("β"); else Serial.print("β"); } Serial.println(" β"); // Temperature Serial.print("β π‘οΈ TEMPERATURE: "); Serial.print(temp, 1); Serial.println("Β°C β"); // Humidity Serial.print("β π§ HUMIDITY: "); Serial.print(humidity, 1); Serial.println("% β"); // VPD Serial.print("β π VPD: "); Serial.print(vpd, 2); Serial.println(" kPa β"); Serial.println("β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£"); Serial.println("β π RECOMMENDATION: β"); Serial.println("β " + getRecommendation(moisture, temp, vpd, humidity)); Serial.println("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n"); } // Store data for history charts void storeHistory(int moisture, float temp, float humidity) { moistureHistory[historyIndex] = moisture; tempHistory[historyIndex] = temp; humidityHistory[historyIndex] = humidity; historyIndex = (historyIndex + 1) % MAX_READINGS; if (historyCount < MAX_READINGS) historyCount++; } void setup() { Serial.begin(115200); dht.begin(); // Connect to WiFi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nβ WiFi connected!"); Serial.println("βββββββββββββββββββββββββββββββββββββββββββ"); Serial.println("π FARM DATA VISUALIZATION DASHBOARD"); Serial.println(" Real-time monitoring system"); Serial.println("βββββββββββββββββββββββββββββββββββββββββββ\n"); } void loop() { // Read sensors int moisture = readSoilMoisture(); float temp = dht.readTemperature(); float humidity = dht.readHumidity(); float vpd = calculateVPD(temp, humidity); // Validate readings if (isnan(temp) || isnan(humidity)) { Serial.println("β οΈ Sensor error - retrying..."); delay(2000); return; } // Store history storeHistory(moisture, temp, humidity); // Display dashboard generateLocalDashboard(moisture, temp, humidity, vpd); // Send to cloud sendToCloud(moisture, temp, humidity, vpd); // Display last 24 hours trend if (historyCount >= 24) { float morningAvg = 0, eveningAvg = 0; for (int i = 0; i < 24; i++) { int idx = (historyIndex - 1 - i + MAX_READINGS) % MAX_READINGS; if (i < 6) eveningAvg += moistureHistory[idx]; // Last 6 hours if (i >= 18) morningAvg += moistureHistory[idx]; // 18-24 hours ago } morningAvg /= 6; eveningAvg /= 6; Serial.print("π TREND: "); if (eveningAvg < morningAvg - 5) { Serial.println("Moisture decreasing β Time to irrigate"); } else if (eveningAvg > morningAvg + 5) { Serial.println("Moisture increasing β Reduce irrigation"); } else { Serial.println("Moisture stable β Maintain schedule"); } } delay(3600000); // Send every hour }
π± OceanRemote Dashboard Features
π Your OceanRemote Dashboard Includes:
- π Real-time gauges for soil moisture, temperature, humidity
- π Interactive line charts showing 7-day or 30-day trends
- π― Threshold alerts - Get notified when moisture drops below 35%
- π± Mobile responsive - Check on your phone from anywhere
- π Historical data export - Download CSV for advanced analysis
- π€ Automation rules - Trigger irrigation based on dashboard thresholds
A South African fruit farmer installed soil moisture sensors across 20 hectares:
- π Dashboard showed: Northwest zone consistently 20% drier than rest
- π Investigation found: Clogged drip emitters in that zone
- π° Savings: Fixed emitters β yield increased 40% in that zone
- π ROI: Dashboard paid for itself in 2 weeks
"Without the visual dashboard, we would have never noticed the uneven watering. Now we check our charts every morning!" - Farm Manager, South Africa
- π Check daily at the same time: Morning (7-8 AM) is best before irrigation decisions
- π Share with your team: Put a tablet in the farm office showing the dashboard
- π Set up mobile alerts: Get SMS when moisture drops below threshold
- π Track over seasons: Compare this year's data to last year's
- π Take screenshots: Document problems when they happen for later analysis
You can now visualize and interpret farm data like a pro!
- β Choose the right chart type for each farm metric
- β Build a complete Arduino-powered dashboard
- β Spot problems instantly using visual patterns
- β Send formatted data to OceanRemote for visualization
- β Make faster, better decisions with visual insights
Next step: Set up automated alerts and integrate weather forecasts!
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β DASHBOARD COLOR CODE GUIDE β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β β β π’ GREEN (Optimal) π‘ YELLOW (Warning) π΄ RED (Critical) β β ββββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ β β Moisture: 40-70% Moisture: 30-40% Moisture: < 30% β β Temp: 20-28Β°C Temp: 28-32Β°C Temp: > 35Β°C β β Humidity: 40-70% Humidity: 70-85% Humidity: > 85% β β VPD: 0.8-1.2 kPa VPD: 1.2-1.5 kPa VPD: > 1.5 kPa β β β β ACTION: Monitor only ACTION: Prepare to act ACTION: ACT NOW! β β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Apply these concepts directly to your farm or project.
- Take notes on important details for the quiz.
- Use the button below to track your progress.