[Solved] Have everything working except one Void

I am new to arduino/blynk programming but have manged to put this together so far and everything works except for void phchecker(). Can someone please point me in the right direction?

It worked before but after doing my best to clean up my code I ended up with this and now the only relay activated or table message I have gotten to print from the if/else portion was PhUp activating and indicating pin V5 was being read as less <5.21 rather than the 7.01 that was displaying via a labeled display on pin v5 on my app

Live ph readout via pin V5 to the app works great though.

#include <SPI.h>
#include <SoftwareSerial.h>
#include <BlynkSimpleStream.h>
#include <SimpleTimer.h>
#include <TimeLib.h>



#define SensorPin 7          //pH meter Analog output to Arduino Analog Input 7 
unsigned long int avgValue;  //Store the average value of the sensor feedback
float b;
int buf[10], temp;

//pins to pumps
int PhDown = 40;
int PhUp = 42;


//temp Ph Min/Max range and value readout
float PhLow = 5.21;
float PhHigh = 6.23;


char auth[] = "removed";
SimpleTimer timer;


void setup() {
  digitalWrite(PhDown, HIGH);
  digitalWrite(PhUp, HIGH);
  Serial.begin(9600);
  Blynk.begin(Serial, auth);
  pinMode(PhDown, OUTPUT);
  pinMode(PhUp, OUTPUT);
  timer.setInterval(900000L, phchecker);
  timer.setInterval(1000L, PhProbe);
}

void PhProbe()
{
  avgValue = 0;
  for (int i = 2; i < 8; i++)               //take the average value of 6 center sample
    avgValue += buf[i];
  float phValue = (float)avgValue * 5.0 / 1024 / 6; //convert the analog into millivolt
  phValue = 3.5 * phValue;                  //convert the millivolt into pH value
  Blynk.virtualWrite(V5, phValue);
}

void phchecker() {
  if (V5 >= PhLow && V5 <= PhHigh)
  {
    //placeholder for table message
  }

  else if (V5 > PhHigh)
  {
    digitalWrite(PhDown, LOW);
    delay(3000);
    digitalWrite(PhDown, HIGH);
    //placeholder for table message
  }

  else if (V5 < PhLow)
  {
    digitalWrite(PhUp, LOW);
    delay(3000);
    digitalWrite(PhUp, HIGH);
    //placeholder for table message
  }
}

void loop() {
  Blynk.run();
  timer.run();

  {
    for (int i = 0; i < 10; i++) //Get 10 sample value from the sensor for smooth the value
    {
      buf[i] = analogRead(SensorPin);
      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 (buf[i] > buf[j])
        {
          temp = buf[i];
          buf[i] = buf[j];
          buf[j] = temp;
        }
      }
    }
  }
}

Withdrawn

Count your brackets and here is one without function

I see that you comprehend the use of SimpleTimer so in order for you to properly use it you must remove your delays. They halt your entire device.

Instead define a function that sets your pin high and use
Use a global variable to track what pin to set high

int handlePin;

Then in your pH checker

handlePin = PhLow; // or PhHigh depending on if
timer.setTimeout(3000L, someFunction);
void someFunction() 
{
   digitalWrite(handlePin, HIGH);
} 

Instead of Delay, this will call the function once after 3s without blocking your code.

1 Like

Thank you for the advice. I removed the rouge brackets and will work on restructuring the rest today.

I have changed things up to this but it still doesn’t seem to read V5 properly as it activates pin 42 which would mean it is seeing the value as < 5.21 when V5 is currently reading 7.25+ in my app so it should activate pin 40.

For reference my relay is LOW = on HIGH = off . Even though the wrong relay is activating right now due to the above it will not revert after the timeout. Do I need to have it set HIGH when it timesout somehow?

#include <SPI.h>
#include <SoftwareSerial.h>
#include <BlynkSimpleStream.h>
#include <SimpleTimer.h>
#include <TimeLib.h>



#define SensorPin 7          //pH meter Analog output to Arduino Analog Input 0   
unsigned long int avgValue;  //Store the average value of the sensor feedback
float b;
int buf[10], temp;

//pins to pumps
int PhDown = 40;
int PhUp = 42;
int CurrentPump;

//temp Ph Min/Max range and value readout
float PhLow = 5.21;
float PhHigh = 6.23;


char auth[] = "removed";
SimpleTimer timer;


void setup() {
  Serial.begin(9600);
  Blynk.begin(Serial, auth);
  digitalWrite(PhDown, HIGH);
  digitalWrite(PhUp, HIGH);
  pinMode(PhDown, OUTPUT);
  pinMode(PhUp, OUTPUT);
  timer.setInterval(1000L, PhProbe);
  timer.setInterval(5000L, PhChecker);

}

void PhProbe() {
  avgValue = 0;
  for (int i = 2; i < 8; i++)               //take the average value of 6 center sample
    avgValue += buf[i];
  float phValue = (float)avgValue * 5.0 / 1024 / 6; //convert the analog into millivolt
  phValue = 3.5 * phValue;                  //convert the millivolt into pH value
  Blynk.virtualWrite(V5, phValue);
}

void PumpActivate() {
  digitalWrite(CurrentPump, LOW);
}


void PhChecker() {
  if (V5 >= PhLow && V5 <= PhHigh)
  {
    //placeholder table msg
  }
  else if (V5 > PhHigh)
  {
    CurrentPump = PhDown;
    timer.setTimeout(3000L, PumpActivate);
  }
  else
  {
    CurrentPump = PhUp;
    timer.setTimeout(3000L, PumpActivate);
  }
}


void loop() {
  Blynk.run();
  timer.run();


  for (int i = 0; i < 10; i++) //Get 10 sample value from the sensor for smooth the value
  {
    buf[i] = analogRead(SensorPin);
    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 (buf[i] > buf[j])
      {
        temp = buf[i];
        buf[i] = buf[j];
        buf[j] = temp;
      }
    }
  }
}

Ok I’ve finished tonight with this but it still doesn’t seem to properly read pin v5 in the if/else if’s. Always reverts to “else if (V5 < PhLow)” and prints “PhUp Activated” although the labelled display in the app reads it fine.

#include <SPI.h>
#include <SoftwareSerial.h>
#include <BlynkSimpleStream.h>
#include <SimpleTimer.h>
#include <TimeLib.h>
WidgetLCD lcd(V10);

#define SensorPin 7          //pH meter Analog output to Arduino Analog Input 7   
unsigned long int avgValue;  //Store the average value of the sensor feedback
float b;
int buf[10], temp;

//pins to pumps
int PhDown = 40;
int PhUp = 42;

//Holds PhDown or PhUp Depending on if/else if
int CurrentPump;

//temp Ph Min/Max range and value readout
float PhLow = 5.20;
float PhHigh = 6.00;

//Auth Code for Blynk App Local Server
char auth[] = "removed";

//timer
SimpleTimer timer;


void setup() {
  Serial.begin(9600);
  Blynk.begin(Serial, auth);
  digitalWrite(PhDown, HIGH);             //sets pins to high at default. High is off.
  digitalWrite(PhUp, HIGH);
  pinMode(PhDown, OUTPUT);
  pinMode(PhUp, OUTPUT);
  timer.setInterval(1000L, PhProbe);
  timer.setInterval(5000L, PhChecker);    //Needs to be changed after testing
  timer.setInterval(100L, Probe);
  lcd.clear();
}

void Probe() {
  for (int i = 0; i < 10; i++) //Get 10 sample value from the sensor for smooth the value
  {
    buf[i] = analogRead(SensorPin);
  }
  for (int i = 0; i < 9; i++) //sort the analog from small to large
  {
    for (int j = i + 1; j < 10; j++)
    {
      if (buf[i] > buf[j])
      {
        temp = buf[i];
        buf[i] = buf[j];
        buf[j] = temp;
      }
    }
  }
}

void PhProbe() {
  avgValue = 0;
  for (int i = 2; i < 8; i++)             //take the average value of 6 center sample
    avgValue += buf[i];
  float phValue = (float)avgValue * 5.0 / 1024 / 6; //convert the analog into millivolt
  phValue = 3.5 * phValue;                //convert the millivolt into pH value
  Blynk.virtualWrite(V5, phValue);        //writes float to Virtual pin 5 for Blynk App
}

void PumpActivate()
{
  digitalWrite(CurrentPump, LOW);             //Turns on Pump
  timer.setTimeout(3000L, PumpDeactivate);    //Turns off pump after 3 seconds
}

void PumpDeactivate()
{
  digitalWrite(CurrentPump, HIGH);            //Turns off Pump
}

void PhChecker() {
  if (V5 >= PhLow && V5 <= PhHigh)
  {
    lcd.clear();
    lcd.print(0, 0, "Ph is good");
  }
  else if (V5 > PhHigh)
  {
    CurrentPump = PhDown;      //Set CurrentPump to PhDown
    PumpActivate();            //Runs PumpActivate
    lcd.clear();
    lcd.print(0, 0, "PhDown Activated");
  }
  else if (V5 < PhLow)
  {
    CurrentPump = PhUp;       //Set CurrentPump to PhUp
    PumpActivate();           //Runs PumpActivate
    lcd.clear();
    lcd.print(0, 1, "PhUp Activated");
  }
}

void loop() {
  Blynk.run();
  timer.run();
}

OH I totally missed this part. Your error is here, you can not use virtual pin reference to get your “app” value
every virtual pin is a variable in itself in this manner
V0 = 0
V1 = 1
V2 = 2

and so forth.

what you need to do is define a function that handles changes on APP side of a widget, on your hardware.
Also if I remember correctly, widgets only work with integers so you need to multiply your widget min max
with an appropriate number 10/100/1000 that allows you to get the resolution you want.
Then divide it when your hardware fetches that number

float someValue = 0; // global variable for assigning your widget value

//When ever you change value in your widget, this function gets called by Blynk library
BLYNK_WRITE(V5)
{
    someValue = param.asFloat() / 1000; // param contains your widgets value sent to hardware.
}

then do like this

void PhChecker() {
  if (someValue>= PhLow && someValue<= PhHigh)
  {
    lcd.clear();
    lcd.print(0, 0, "Ph is good");
  }
  else if (someValue> PhHigh)
  {
    CurrentPump = PhDown;      //Set CurrentPump to PhDown
    PumpActivate();            //Runs PumpActivate
    lcd.clear();
    lcd.print(0, 0, "PhDown Activated");
  }
  else if (someValue< PhLow)
  {
    CurrentPump = PhUp;       //Set CurrentPump to PhUp
    PumpActivate();           //Runs PumpActivate
    lcd.clear();
    lcd.print(0, 1, "PhUp Activated");
  }
}

I managed to get it all working. I simply added CurrentPh = phValue; in addition to writing to V5 and added float CurrentPh; as a global then changed my if/else ifs to pull from CurrentPh. I also changed my timing on the probe from reading every 100ms to 1000ms to help prevent flooding.

Everything is working great now. I am still working on learning more and making this as clean as possible but that will come in time. Just glad to have it functioning. All your help was very much appreciated!

float CurrentPh;

void PhProbe() {
  avgValue = 0;
  for (int i = 2; i < 8; i++)             //take the average value of 6 center sample
    avgValue += buf[i];
  float phValue = (float)avgValue * 5.0 / 1024 / 6; //convert the analog into millivolt
  phValue = 3.5 * phValue;                //convert the millivolt into pH value
  Blynk.virtualWrite(V5, phValue);        //writes float to Virtual pin 5 for Blynk App
  CurrentPh = phValue;
}

void PhChecker() {
  if (CurrentPh >= PhLow && CurrentPh <= PhHigh)
  {
    lcd.clear();
    lcd.print(0, 0, "Ph is good");
  }
  else if (CurrentPh > PhHigh)
  {
    CurrentPump = PhDown;      //Set CurrentPump to PhDown
    PumpActivate();            //Runs PumpActivate
    lcd.clear();
    lcd.print(0, 0, "PhDown Activated");
  }
  else if (CurrentPh < PhLow)
  {
    CurrentPump = PhUp;       //Set CurrentPump to PhUp
    PumpActivate();           //Runs PumpActivate
    lcd.clear();
    lcd.print(0, 1, "PhUp Activated");
  }
}

Super, I’m glad it worked out for you :slight_smile: