DIY DIY - Affordable? Soil NPK, pH & EC sensor (NPKPHC-S)

As min and max values I have calibrated 610 > inside water, 1024 > dry
 
To get the raw value for air and for water run this code on the device and read it out via a the 'Serial Monitor'
C++:
void setup() {
  Serial.begin(9600);
}

void loop() {
Serial.print("Raw Value: ");
Serial.println(analogRead(A0));
delay(500);
}
 
Ah, that sensor...
I've written a function for it.
Try this in your code
C++:
void moisture(int pin, const int AirValue, const int WaterValue, int virPin ) {

  int i;
  int value = 0;
  int numReadings = 5;
  int soilMoistureValue = 0;
  int soilmoisturepercent = 0;

  for (i = 0; i < numReadings; i++){
    value = value + analogRead(pin);
    delay(1);
  }
  soilMoistureValue = value / numReadings;
  soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);
  Blynk.virtualWrite(virPin, soilmoisturepercent);
}

Call it by adding this line in void setup()
C++:
moisture(A0, 787, 446, 1);   //Arduino Pin, Raw Air Value, Raw Water Value, Blynk Virtual Pin

interesting function, didn’t thought , didn’t knew there were a function for percentage calculations between values … usually I make all by myself :smoking:
 
In case som1 will need it I post the woriking code. Thanks for the help, very cool from you! :toke: ... pass the boof ... Deserved...:d5:

C++:
#define BLYNK_TEMPLATE_ID "TMPLxxxx"
#define BLYNK_DEVICE_NAME "Sensor 1"
#define BLYNK_AUTH_TOKEN "xxxxx-PmFc"
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "ssid ";
char pass[] = "pw";
BlynkTimer timer;



void moisture(int pin, const int AirValue, const int WaterValue, int virPin ) {

  int i;
  int value = 0;
  int numReadings = 5;
  int soilMoistureValue = 0;
  int soilmoisturepercent = 0;

  for (i = 0; i < numReadings; i++){
    value = value + analogRead(pin);
    delay(1);
  }
  soilMoistureValue = value / numReadings;
  soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);
  Blynk.virtualWrite(virPin, soilmoisturepercent);
  Serial.print(soilmoisturepercent);
  delay(5000);
  //Serial.print("%");
  }

void runMe(){
  moisture(A0, 1024, 560, V1);   //Arduino Pin, Raw Air Value, Raw Water Value, Blynk Virtual Pin
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
}

void loop()
{
  Blynk.run();
  //timer.setInterval(5000L, runMe);
  runMe();
}
 
Last edited:
In case som1 will need it I post the woriking code. Thanks for the help, very cool from you! :toke: ... pass the boof ... Deserved...:d5:

C++:
#define BLYNK_TEMPLATE_ID "TMPLxxxx"
#define BLYNK_DEVICE_NAME "Sensor 1"
#define BLYNK_AUTH_TOKEN "xxxxx-PmFc"
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "ssid ";
char pass[] = "pw";
BlynkTimer timer;



void moisture(int pin, const int AirValue, const int WaterValue, int virPin ) {

  int i;
  int value = 0;
  int numReadings = 5;
  int soilMoistureValue = 0;
  int soilmoisturepercent = 0;

  for (i = 0; i < numReadings; i++){
    value = value + analogRead(pin);
    delay(1);
  }
  soilMoistureValue = value / numReadings;
  soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);
  Blynk.virtualWrite(virPin, soilmoisturepercent);
  Serial.print(soilmoisturepercent);
  delay(5000);
  //Serial.print("%");
  }

void runMe(){
  moisture(A0, 1024, 560, V1);   //Arduino Pin, Raw Air Value, Raw Water Value, Blynk Virtual Pin
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
}

void loop()
{
  Blynk.run();
  //timer.setInterval(5000L, runMe);
  runMe();
}
Sorry brother, but your code is faulty... Never ever use the loop function for anything other then Blynk.run(); and timer.run();
Also, never use delay's in Blynk...It stops the cpu. Use the timer function for that. It should be looking like this...
C++:
#define BLYNK_TEMPLATE_ID "TMPLxxxx"
#define BLYNK_DEVICE_NAME "Sensor 1"
#define BLYNK_AUTH_TOKEN "xxxxx-PmFc"
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "ssid ";
char pass[] = "pw";
BlynkTimer timer;



void moisture(int pin, const int AirValue, const int WaterValue, int virPin ) {

  int i;
  int value = 0;
  int numReadings = 5;
  int soilMoistureValue = 0;
  int soilmoisturepercent = 0;

  for (i = 0; i < numReadings; i++){
    value = value + analogRead(pin);
    delay(1);
  }
  soilMoistureValue = value / numReadings;
  soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);
  Blynk.virtualWrite(virPin, soilmoisturepercent);
  Serial.print(soilmoisturepercent);
  Serial.println("%");
  }

void runMe(){
  moisture(A0, 1024, 560, V1);   //Arduino Pin, Raw Air Value, Raw Water Value, Blynk Virtual Pin
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(5000L, runMe);   //This line runs 'runMe' every 5 seconds, but it has to be put in the setup funtion.
}

void loop()
{
  Blynk.run();
  timer.run();   //The above timer will only run if you activate the timer function in the void loop...confusing isn't it...

}
 
Last edited:
Thanks for the review, much appreciated, learn writing good code is even better:pass:
You're welcome brother. :thumbsup:

Let's continue with this thread. Last week the CO2 sensor arrived, so I began building the second sensor node...It is actually an upgrade from the sensor that's already inside the tent.
This node consists of three sensor packets:
  • DHT44 (or AM2305), measuring humidity and temperature
  • BH1750 board, measuring light (lux)
  • CJMCU-8128 board, measuring CO2 and barometric pressure
I glued the two boards together and used a couple of straps to mount it to a piece of carbon rod. This setup is placed in the middle of the tent at the same height as the canopy.
1669556458839 _small.jpg

1669556458834 _small.jpg


So for now I have two node's installed in the tent. The first node, measuring the humidity and temperature in the four pots. (One sensor has already failed. Think it's faulty wiring). As soon as the NPKPHC-S sensor arrives, this board will get a total workover.
Some of you may notice the high humidity inside the pots, which is actually my fault. I need to get my watering skills under control...

And since today, the upgraded second node...updating it's values inside the new Blynk app v2.0...
1669556458831 _small.jpg




Regards,

Bob :toke:
 
Hey, @Bob's Auto's, I was trying to set up an automatic relay actuating a pump for soil rh control, I have managed to get a trigger on the app automatically when the moisture of the soil is up on a certain %. The problem I am encountering is about using the pin D4 to actually Enable or Disable the relay when this happens. Got any ideas? Thanks!!!

C++:
#define BLYNK_TEMPLATE_ID "xxx-xxx"
#define BLYNK_DEVICE_NAME "ESP2rele"
#define BLYNK_AUTH_TOKEN "xxx"
#define BLYNK_PRINT Serial
#define PUMP_PIN D4   // FAN RELAY

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Tony";
char pass[] = "marm1te1sterr1ble";
BlynkTimer timer;
int humidity = 0;                   //humidity value for actuating the relay pump

void pump(int pin, int virPin, int humidity){       //function to check and set relay on/off depending on humidity %
  if(humidity>=60)
    Blynk.virtualWrite(virPin, LOW);
    else
    Blynk.virtualWrite(virPin, HIGH);
}


void moisture(int pin, const int AirValue, const int WaterValue, int virPin ) {

  int i;
  int value = 0;
  int numReadings = 5;
  int soilMoistureValue = 0;
  int soilmoisturepercent = 0;

  for (i = 0; i < numReadings; i++){
    value = value + analogRead(pin);
    delay(1);
  }
  soilMoistureValue = value / numReadings;
  soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);
  Blynk.virtualWrite(virPin, soilmoisturepercent);
  Serial.print(soilmoisturepercent);
  Serial.println("%");
  humidity = soilmoisturepercent;
  }

void runMe(){
  moisture(A0, 1024, 600, V1);   //Arduino Pin, Raw Air Value, Raw Water Value, Blynk Virtual Pin
  pump(D4, V2, humidity);       //passing digital pin of esp8266, virtual pin linked + humidity % top check needed for trigger
  //Serial.print(analogRead(A0));   //use for calibration
  //Serial.println("<--");

}

void setup()
{
  Serial.begin(9600);
  //pinMode(PUMP_PIN, OUTPUT);
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(5000L, runMe);   //This line runs 'runMe' every 5 seconds, but it has to be put in the setup funtion.
}

void loop()
{
  Blynk.run();
  timer.run();   //The above timer will only run if you activate the timer function in the void loop...confusing isn't it...
}



[ATTACH type="full" align="left"]1543651[/ATTACH]
 

Attachments

  • RPReplay_Final1670152362.mp4
    1.8 MB
Last edited:
Your problem probably lies with the pin numbering. Check out this page about ESP pinnumbers vs Arduino

That being said, try to make the pump function work without anything else. ie, just the ESP, sensor and relay. Forget Blynk and the app for a moment.
Go back to trying to get that function work as it suppose to, because you'll need loads more code before you will get there, I say you that. You'll need a 'setpoint and a hysteresis' variable to get some stability in your system. Maybe also some 'smoothing' can be done so the values from the analog read aren't as erratic.
Also, as you've written the code the value 'humidity' is 0 when you pass this into the function pump(). That's because you declare it two times, once as a global variable and once as a variable of the pump() function. You actually don't need to parse those variables through the function unless you are planning on measuring multiple analog inputs, but then you have the wrong device as this only has one analog input.

So what I would do is to do a analogRead of the A0 pin. Do my calculation upon it so I know what my variable 'humidity' is and then run the if statement against it so you know when to activate the solenoid switch.
Use the Serial Monitor in the Arduino IDE to work out the kinks...and see how the relay responds to the values displayed.


Happy hunting and if you update your code, share it here and I'll have another look at it :thumbsup:
 
Back
Top