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

Thanks for the tip, i was stucked searching for... sure I'll do. Thanks.. pass the booff :d5: :pass:
 
Hey, there I got a working code... might not be the best but at least it works as it should.

C++:
#define BLYNK_TEMPLATE_ID "xxx"
#define BLYNK_DEVICE_NAME "xxx"
#define BLYNK_AUTH_TOKEN "xxx"
#define BLYNK_PRINT Serial

#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
const int Pump_Pin = 5;             //initialize a GPIO 5 --> D1 pin

void pump(int pin){       //function to check and set relay on/off depending on humidity %
  if(humidity>=60){
    digitalWrite(pin, LOW);       //set pin D1 on/off 
    Blynk.virtualWrite(V2, LOW);  //display a led indicator pump is on/off on blynk app
  }else{
    digitalWrite(pin, HIGH);
    Blynk.virtualWrite(V2, HIGH);
  }
   
   
   
}

void moisture(int pin, const int AirValue, const int WaterValue, int virPin ) {         //function for a 0-100 % humidity level

  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);                                                  //check from serial monitor moisture%
  //Serial.println("%");
  humidity = soilmoisturepercent;                                                       //set a value for a globally variable called in pump()
  }

void runMe(){
  moisture(A0, 1044, 600, V1);   //Arduino Pin, Raw Air Value, Raw Water Value, Blynk Virtual Pin
  pump(Pump_Pin);       //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);
  digitalWrite(Pump_Pin, HIGH); // Built-in D1 off

  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...


}

thanks ... sharing one
 
Hey, there I got a working code... might not be the best but at least it works as it should.

C++:
#define BLYNK_TEMPLATE_ID "xxx"
#define BLYNK_DEVICE_NAME "xxx"
#define BLYNK_AUTH_TOKEN "xxx"
#define BLYNK_PRINT Serial

#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
const int Pump_Pin = 5;             //initialize a GPIO 5 --> D1 pin

void pump(int pin){       //function to check and set relay on/off depending on humidity %
  if(humidity>=60){
    digitalWrite(pin, LOW);       //set pin D1 on/off
    Blynk.virtualWrite(V2, LOW);  //display a led indicator pump is on/off on blynk app
  }else{
    digitalWrite(pin, HIGH);
    Blynk.virtualWrite(V2, HIGH);
  }
 
 
 
}

void moisture(int pin, const int AirValue, const int WaterValue, int virPin ) {         //function for a 0-100 % humidity level

  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);                                                  //check from serial monitor moisture%
  //Serial.println("%");
  humidity = soilmoisturepercent;                                                       //set a value for a globally variable called in pump()
  }

void runMe(){
  moisture(A0, 1044, 600, V1);   //Arduino Pin, Raw Air Value, Raw Water Value, Blynk Virtual Pin
  pump(Pump_Pin);       //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);
  digitalWrite(Pump_Pin, HIGH); // Built-in D1 off

  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...


}

thanks ... sharing one
Good for you buddy :thumbsup:
Glad you've got it to work. You'll probably notice that the solenoid will go crazy when you are around that 60% humidity. At 16.000 calculations a second it will start switching like crazy. Try it out ;)
To solve that issue you'll have to implement smoothing and add two more variables (setpoint and hysteresis). Then you can even set those from within the Blynk app and have a beginning of a interactive controller. :cheers:
 
Hey guys,

Today I received my 100K digital potentiometers and my NPKPHC-S which I ordered a couple weeks ago.
I played around with the NPKPHC-S sensor, connected to the pc and got real values...Yeah!!!!...Very exciting stuff guys :woohoo1:

I also replaced the 10K with one of the new 100K potmeters and went to the tent. I got to set the light intensity with the aid of my Blynk app, but had to keep a hand on the light for it to work, meaning I had a ground issue. But this test I call successful!!
I had hoped to create something one could just add to the system without opening it, but the ground wire got in my way. Let me explain...For the digital pot meter to work as it should the device needs to be at the same reference voltage. The way to do that is to connect the ground wires with each other. So I'll probably need to open the box again and mount the little NodeMCU inside and connect ground with it. I'll probably will also have to create an opening for the usb cable to fit inside or install a small voltage regulator inside to get the voltage from 10V to the 5V the NodeMCU expects. I do have these standard in my tinkerbox and would prefer the latter...


Regards,

Bob :toke:
 
Hello Bob :pass: ,
I took your suggestion and tried to implement -setpoint- and -hysteresis-, what do you think?

C++:
#define BLYNK_TEMPLATE_ID "TMPL-ccc"
#define BLYNK_DEVICE_NAME "cc"
#define BLYNK_AUTH_TOKEN "ccc"
#define BLYNK_PRINT Serial

#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
const int Pump_Pin = 5;                          //initialize a GPIO 5 --> D1 pin                           
const float SETPOINT = 55.0;                     // Set the desired moisture setpoint (between 45% and 65%)
const float HYSTERESIS = (65.0 - 45.0) / 5;   // Set the hysteresis value (15% of the setpoint range)

void controlPump(int pin) {
  // Water pump state (high = on, low = off)
    digitalWrite(pin, LOW);       //set pin D1 on/off

  if (humidity < SETPOINT - HYSTERESIS) {
    // If the moisture level is below the setpoint minus the hysteresis value, turn the pump on
    digitalWrite(pin, HIGH);
    Blynk.virtualWrite(V2, HIGH);
  } else if (humidity > SETPOINT + HYSTERESIS) {
    // If the moisture level is above the setpoint plus the hysteresis value, turn the pump off
    digitalWrite(pin, LOW);       //set pin D1 on/off
    Blynk.virtualWrite(V2, LOW);  //display a led indicator pump is on/off
  }
}

  /*void pump(int pin){       //function to check and set relay on/off depending on humidity %
  if(humidity>=60){
    digitalWrite(pin, LOW);       //set pin D1 on/off
    Blynk.virtualWrite(V2, LOW);  //display a led indicator pump is on/off
  }else{
    digitalWrite(pin, HIGH);
    Blynk.virtualWrite(V2, HIGH);
  }
}*/


void moisture(int pin, const int AirValue, const int WaterValue, int virPin ) {         //function for a 0-100 % humidity level

  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);                                                  //check from serial monitor moisture%
  //Serial.println("%");
  humidity = soilmoisturepercent;                                                       //set a value for a globally variable called in pump()
  }

void runMe(){
  moisture(A0, 1024, 600, V1);   //Arduino Pin, Raw Air Value, Raw Water Value, Blynk Virtual Pin
  controlPump(Pump_Pin);       //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);
  digitalWrite(Pump_Pin, LOW); // Built-in D1 off

  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...


}


thanks very much for your time ! Hope everything is good. sharing a boof
 
Last edited:
This is some cool ass shit. Wayyyyy to complicated for me, but Im fascinated. Question though, does this npkphc-s sensor need some kind of calibration to get accurate readings?
Even if I am not sure about the answer of this specific device, usually sensors are pre-calibrated by manufacturers, but their accuracy is not-so good(mostly fine for avg needs). You should calibrate them for better accuracy in a controlled environment (means that you specifically create a environment with the knowledge of what’s inside).
P.S.
YzwFfsE.jpg
 
Last edited:
Hello Bob :pass: ,
I took your suggestion and tried to implement -setpoint- and -hysteresis-, what do you think?

C++:
#define BLYNK_TEMPLATE_ID "TMPL-ccc"
#define BLYNK_DEVICE_NAME "cc"
#define BLYNK_AUTH_TOKEN "ccc"
#define BLYNK_PRINT Serial

#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
const int Pump_Pin = 5;                          //initialize a GPIO 5 --> D1 pin                          
const float SETPOINT = 55.0;                     // Set the desired moisture setpoint (between 45% and 65%)
const float HYSTERESIS = (65.0 - 45.0) / 5;   // Set the hysteresis value (15% of the setpoint range)

void controlPump(int pin) {
  // Water pump state (high = on, low = off)
    digitalWrite(pin, LOW);       //set pin D1 on/off

  if (humidity < SETPOINT - HYSTERESIS) {
    // If the moisture level is below the setpoint minus the hysteresis value, turn the pump on
    digitalWrite(pin, HIGH);
    Blynk.virtualWrite(V2, HIGH);
  } else if (humidity > SETPOINT + HYSTERESIS) {
    // If the moisture level is above the setpoint plus the hysteresis value, turn the pump off
    digitalWrite(pin, LOW);       //set pin D1 on/off
    Blynk.virtualWrite(V2, LOW);  //display a led indicator pump is on/off
  }
}

  /*void pump(int pin){       //function to check and set relay on/off depending on humidity %
  if(humidity>=60){
    digitalWrite(pin, LOW);       //set pin D1 on/off
    Blynk.virtualWrite(V2, LOW);  //display a led indicator pump is on/off
  }else{
    digitalWrite(pin, HIGH);
    Blynk.virtualWrite(V2, HIGH);
  }
}*/


void moisture(int pin, const int AirValue, const int WaterValue, int virPin ) {         //function for a 0-100 % humidity level

  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);                                                  //check from serial monitor moisture%
  //Serial.println("%");
  humidity = soilmoisturepercent;                                                       //set a value for a globally variable called in pump()
  }

void runMe(){
  moisture(A0, 1024, 600, V1);   //Arduino Pin, Raw Air Value, Raw Water Value, Blynk Virtual Pin
  controlPump(Pump_Pin);       //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);
  digitalWrite(Pump_Pin, LOW); // Built-in D1 off

  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...


}


thanks very much for your time ! Hope everything is good. sharing a boof
You did really good with your code brother. :thumbsup:
But the more important question...Does the code do what you'd expect?


This is some cool ass shit. Wayyyyy to complicated for me, but Im fascinated.
It's not that hard. If an old stoner can do it... :baked:


Question though, does this npkphc-s sensor need some kind of calibration to get accurate readings?
The Windows application does have calibration commands for pH, EC & TDS and so on, but not for the NPK values...
Now, I don't suspect it to be super accurate, but rather give me a ballpark value. I'm not that interested in the actual values, but rather being able to see which substance is in excess or gets depleted. ie, If we start with fresh soil and during veg I see N dropping, but P & K rising, I know the plant is taking up more N and one shouldn't be adding P & K anymore.
1670525814369.png
 
You did really good with your code brother. :thumbsup:
But the more important question...Does the code do what you'd expect?

yeah, I did some tests and it works perfectly, also checked for a week the range of humidity the sensor was giving me after & before watering and the time it was taking to dry … and it should be well fitted.. also bought 4 smart plugs with a Wi-Fi temp-humidity sensor, and automated by a secondary app the sensor check for temps and rh, activating vents fans and heater.

setting all up tonight, might take a couple of picture once everything is ready, thinking about posting a thread called -cheap automated growbox diy-

honestly, I spent very little in comparison with how much does it costs in the market..
 
Back
Top