/// Use Node - Red "Filter" Node to sort out the output of serialprint ///
/*Value need to be updated as follows:
1. bluebarrel = height of the water tank
2. soilDry = calibration value of dry soil (growing medium in this case)
3. soilWet = calibration value of wet soil (growing medium in this case)
4. Line 139 & 166 = the value 5 is due to the pH sensor being connected to 5V of Arduino. Update if necessary. Refer source's link below if needed
*/
// Water level
// Refer : https://www.geeksforgeeks.org/distance-measurement-using-ultrasonic-sensor-and-arduino/
#define echoPin1 2 // Pin D2 Arduino to pin Echo of HC-SR04 // Ultrasonic Sensor 1
#define trigPin1 3 // Pin D3 Arduino to pin Trig of HC-SR04
#define echoPin2 4 // Pin D2 Arduino to pin Echo of HC-SR04 // Ultrasonic Sensor 2
#define trigPin2 5 // Pin D3 Arduino to pin Trig of HC-SR04
// Height of blue barrel / tank of water (in cm)
int bluebarrel = 70;
// Variable for Ultrasonic Sensor 1
long duration1; // time taken to the pulse to reach receiver
int distance1; // distance calculated using formula
int waterlevel1; // calculated water level
long previouslevel1 = 0; // previous calculated water level
// Variable for Ultrasonic Sensor 2
long duration2;
int distance2;
int waterlevel2;
long previouslevel2 = 0;
// PH Sensor
// Source : https://how2electronics.com/ph-meter-using-ph-sensor-arduino-oled/#:~:text=For%20testing%20the%20Ph%20meter%20designed%20above
#define pHSensorPin1 A0 // the pH sensor 1 Analog output
#define pHSensorPin2 A1 // the pH sensor 2 Analog output
unsigned long int avgValue1; //Store the average value of the sensor 1 feedback
unsigned long int avgValue2; //Store the average value of the sensor 2 feedback
int buf1[10],temp1;
int buf2[10],temp2;
// Humidity
// Source : https://lastminuteengineers.com/soil-moisture-sensor-arduino-tutorial/
// Refer : https://iotspace.dev/arduino-bodenfeuchtesensoren-anleitung-und-sketch/
// Plan: connect pump to digitalpin? or control pump through Node Red?
// Plan refer: if connect digitalpin: https://arduinogetstarted.com/tutorials/arduino-controls-pump
/* Change these values based on your calibration values */
#define soilWet 500 // Define max value we consider soil 'wet'
#define soilDry 750 // Define min value we consider soil 'dry'
// Sensor pins
#define humsensorPin1a A2 //Tower 1 above
#define humsensorPin1b A3 //Tower 1 below
#define humsensorPin2a A4 //Tower 2 above
#define humsensorPin2b A5 //Tower 2 below
// Define Analog Readings of humidity sensor
int moisture_1a=0;
int moisture_1b=0;
int moisture_2a=0;
int moisture_2b=0;
void setup() {
pinMode(trigPin1, OUTPUT); // Sets the trigPin as an OUTPUT
pinMode(echoPin1, INPUT); // Sets the echoPin as an INPUT
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
Serial.begin(9600); // Serial Communication is starting with 9600 of baudrate speed
delay(500);
}
void loop() {
// Water level code from here
// Ultrasonic Sensor 1
digitalWrite(trigPin1, LOW);
delayMicroseconds(2); // wait for 2 ms to avoid collision in serial monitor
digitalWrite(trigPin1,HIGH); // turn on the Trigger to generate pulse
delayMicroseconds(10); // keep the trigger "ON" for 10 ms to generate pulse for 10 ms.
digitalWrite(trigPin1,LOW); // Turn off the pulse trigger to stop pulse generation
duration1 = pulseIn(echoPin1, HIGH);
distance1 = duration1 * 0.0344 / 2; // Expression to calculate distance using time
waterlevel1 = bluebarrel - distance1;
if (waterlevel1 != previouslevel1) { // Compare current distance with previous distance
Serial.print("Level1:"); // Print new information to serial monitor
Serial.println(waterlevel1); // unit : cm
previouslevel1 = waterlevel1; // Update previous distance with current distance
}
// Ultrasonic Sensor 2
digitalWrite(trigPin2, LOW);
delayMicroseconds(2);
digitalWrite(trigPin2,HIGH);
delayMicroseconds(10);
digitalWrite(trigPin2,LOW);
duration2 = pulseIn(echoPin2, HIGH);
distance2 = duration2 * 0.0344 / 2;
waterlevel2 = bluebarrel - distance2;
if (waterlevel2 != previouslevel2) {
Serial.print("Level2:");
Serial.println(waterlevel2); // unit : cm
previouslevel2 = waterlevel2;
}
delay(1000);
// pH Sensor code from here
// Ph sensor 1
for(int i=0;i<10;i++) //Get 10 sample value from the sensor for smooth the value
{
buf1[i]=analogRead(pHSensorPin1);
delay(10);
}
for(int i=0;i<9;i++) //sort the analog from small to large
{
for(int j=i+1;j<10;j++)
{
if(buf1[i]>buf1[j])
{
temp1=buf1[i];
buf1[i]=buf1[j];
buf1[j]=temp1;
}
}
}
avgValue1=0;
for(int i=2;i<8;i++) //take the average value of 6 center sample
avgValue1+=buf1[i];
float phValue1=(float)avgValue1*5.0/1024/6; //convert the analog into millivolt
phValue1=3.5*phValue1; //convert the millivolt into pH value
Serial.print("pH_1:");
Serial.print(phValue1,2);
Serial.println(" ");
//Ph sensor 2
for(int i=0;i<10;i++) //Get 10 sample value from the sensor for smooth the value
{
buf2[i]=analogRead(pHSensorPin2);
delay(10);
}
for(int i=0;i<9;i++) //sort the analog from small to large
{
for(int j=i+1;j<10;j++)
{
if(buf2[i]>buf2[j])
{
temp2=buf2[i];
buf2[i]=buf2[j];
buf2[j]=temp2;
}
}
}
avgValue2=0;
for(int i=2;i<8;i++) //take the average value of 6 center sample
avgValue2+=buf2[i];
float phValue2=(float)avgValue2*5.0/1024/6; //convert the analog into millivolt // divide by 5 because of 5 V
phValue2=3.5*phValue2; //convert the millivolt into pH value
Serial.print("pH_2:");
Serial.print(phValue2,2);
Serial.println(" ");
// Humidity sensor code from here
//get the reading for monitoring and display
moisture_1a= analogRead(A2); //Tower 1 above & below
Serial.print("Moist1a:");
Serial.println(moisture_1a);
moisture_1b= analogRead(A3);
Serial.print("Moist1b:");
Serial.println(moisture_1b);
moisture_2a= analogRead(A4); //Tower 2 above & below
Serial.print("Moist2a:");
Serial.println(moisture_2a);
moisture_2b= analogRead(A5);
Serial.print("Moist2b:");
Serial.println(moisture_2b);
// Determine status of our soil - Tower 1
if (moisture_1a >= soilDry && moisture_1b >= soilDry) {
//Both soils is dry -> turn on pump
Serial.print("Pump:ON");
} else if (moisture_1a >= soilDry && moisture_1b >= soilWet && moisture_1b < soilDry) {
// above is dry, below is ok -> turn on pump
Serial.print("Pump:ON");
} else if (moisture_1a >= soilWet && moisture_1a < soilDry && moisture_1b >= soilDry) {
// above is ok, below is dry -> turn on pump
Serial.print("Pump:ON");
} else if (moisture_1a <= soilWet && moisture_1b >= soilWet && moisture_1b < soilDry) {
// above is too wet, below is ok -> turn off pump
Serial.print("Pump:OFF");
} else if (moisture_1a >= soilWet && moisture_1a < soilDry && moisture_1b <= soilWet) {
// above is ok, below too wet -> turn off pump
Serial.print("Pump:OFF");
}
/////// Not sure
else if (moisture_1a >= soilDry && moisture_1b <= soilWet) {
// above is dry, below is too wet -> turn off pump
Serial.print("Pump:OFF");
} else if (moisture_1a <= soilWet && moisture_1b >= soilDry) {
// above is too wet, below is dry -> turn off pump
Serial.print("Pump:OFF");
}
else {
Serial.println("Pump:ERROR with water pumping 1");
}
// Determine status of our soil - Tower 2
if (moisture_2a >= soilDry && moisture_2b >= soilDry) {
//Both soils is dry -> turn on pump
Serial.print("Pump:ON");
} else if (moisture_2a >= soilDry && moisture_2b >= soilWet && moisture_2b < soilDry) {
// above is dry, below is ok -> turn on pump
Serial.print("Pump:ON");
} else if (moisture_2a >= soilWet && moisture_2a < soilDry && moisture_2b >= soilDry) {
// above is ok, below is dry -> turn on pump
Serial.print("Pump:ON");
} else if (moisture_2a <= soilWet && moisture_2b >= soilWet && moisture_2b < soilDry) {
// above is too wet, below is ok -> turn off pump
Serial.print("Pump:OFF");
} else if (moisture_2a >= soilWet && moisture_2a < soilDry && moisture_2b <= soilWet) {
// above is ok, below too wet -> turn off pump
Serial.print("Pump:OFF");
}
/////// Not sure
else if (moisture_2a >= soilDry && moisture_2b <= soilWet) {
// above is dry, below is too wet -> turn off pump
Serial.print("Pump:OFF");
} else if (moisture_2a <= soilWet && moisture_2b >= soilDry) {
// above is too wet, below is dry -> turn off pump
Serial.print("Pump:OFF");
}
else {
Serial.println("Pump:ERROR with water pumping 2");
}
delay(1000); // Take a reading every second for testing
}