On off time by widget input

hello, im wondering if anyone can help, im trying to control 2 relays where one comes on and the other gos off for a set time then the first relay turns off and the second relay turns on. i wan this to loop on unless deactivated by on/off button. im also trying to have it so i can change the on off times between the relays from 5-30 seconds set with a widget within the app.

so fair have the following im a bit lost from there .
this receives value from my widget and defults to 5:

float skimDelay = 5; 
BLYNK_WRITE(V4)// Time interval for wave makers
{ 
 int waveDelay = param.asFloat();// reads value 
}

i also have declaired my relay pin and as a output and i have the code to read the value of the on/off switch:

BLYNK_WRITE(V6){  // Return pump button off 
 int waveswitch = param.asInt(); // Get State of Virtual Button, Return pump
  if (waveswitch == 1) {  // button ON
  } else {  // button OFF
    // Turn as many pins/relays OFF as you need
  }
}

how could i convert a value from wavedelay into seconds so it can be used as a timer function?

i believe this is the way to go

BLYNK_WRITE(V4)// Time interval for wave makers
{ 
  int  waveDelay = param.asInt();// reads value 
   
    Serial.println(waveDelay);
    timer.deleteTimer(wavetime);
    wavetime = timer.setInterval(waveDelay * 1000L);
    timer.enable(wavetime);
}

but i get a error when compiling :
^

C:\Users\Adam\Documents\Arduino\libraries\Blynk\src/Blynk/BlynkTimer.h:67:9: note: candidate expects 3 arguments, 1 provided

exit status 1
no matching function for call to ‘BlynkTimer::setInterval(long int)’

Where am i going wrong? its my understanding this should compile.

thanks in advance

full code



/*
  DS18B20multiple.ino https://community.blynk.cc/t/arduino-mega-2650-with-w5100-multiple-ds18b20/16706/10
  YourDuino Multiple DS18B20 Temperature Sensors on 1 wire
  Connections:
  DS18B20 Pinout (Left to Right, pins down, flat side toward you)
  - Left   = Ground
  - Center = Signal (Pin 2):  (with 3.3K to 4.7K resistor to +5 or 3.3 )
  - Right  = +5 or +3.3 V

   Questions: terry@yourduino.com 
   V1.01  01/17/2013 ...based on examples from Rik Kretzinger
   
/*-----( Import needed libraries )-----*/

#define BLYNK_PRINT Serial // Enables Serial Monitor
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h> // This part is for Ethernet stuff
#define W5100_CS  10
#define SDCARD_CS 4
BlynkTimer timer;
char auth[] = "d**********"; // Put your Auth Token here.


#include <OneWire.h> // Get 1-wire Library here: http://www.pjrc.com/teensy/td_libs_OneWire.html

//Get DallasTemperature Library here:  http://milesburton.com/Main_Page?title=Dallas_Temperature_Control_Library
#include <DallasTemperature.h>

/*-----( Declare Constants and Pin Numbers )-----*/
#define ONE_WIRE_BUS 48// DS18B20 on arduino pin2 corresponds to D4 on physical board
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
// This function will run every time Blynk connection is established
DeviceAddress Probe01 = { 0x28, 0xFF, 0x2D, 0x5A, 0xC4, 0x17, 0x05, 0xEF  }; 
BLYNK_CONNECTED() {
  // Request Blynk server to re-send latest values for all pins
Blynk.syncAll();
}

/*-----( Declare Variables )-----*/
// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html



float temp;
int relayPin = 49;// Heater on ssr1
int relay2Pin = 28;// Cooling to 16ch relay board relay 7 on the board
int relay3Pin = 22;// return pump on relay 1 on the board
int relay4Pin = 23;// skimmer on relay 2 on the board
int relay5Pin = 24;// reactor on relay 3 on the board
int wave1Pin = 47; //wave maker on ssr2 
int wave2Pin = 46;// wavemaker 2 on ssr3
float desiredTemp = 26;// set this to your desired temp
float tempDiff = 1;// this variable provides a small +/- temp differential that will prevent constant relay switching.
bool      tempAlarmFlag    = false;      //flag to alarm, and avoid multiple Notification
bool      faultyProbeFlag  = false;      //flag to alarm, and avoid multiple Notification
float lowAlarm     = NAN;
float highAlarm    = NAN;
int wavetime = 1;
int waveDelay = 1;
BLYNK_WRITE(V4)// Time interval for wave makers
{ 
  int  waveDelay = param.asInt();// reads value 
   
    Serial.println(waveDelay);
    timer.deleteTimer(wavetime);
    wavetime = timer.setInterval(waveDelay* 1000L);
    timer.enable(wavetime);
}
BLYNK_WRITE(V6){  // Return pump button off 
 int waveswitch = param.asInt(); // Get State of Virtual Button, Return pump
  if (waveswitch == 1) {  // button ON
    wavetime = timer.setInterval(waveOn);
  } else {  // button OFF
    digitalWrite(wave1Pin, LOW);
    digitalWrite(wave2Pin, LOW);
    
    // Turn as many pins/relays OFF as you need
  }
}
void waveOn()
{
  digitalWrite(wave1Pin, HIGH);
  digitalWrite(wave2Pin, LOW);
}
BLYNK_WRITE(V11) // Triggered when the value of V11 in the app changes
{
  //reads the setppoint
  desiredTemp = param.asFloat();
}

BLYNK_WRITE(V12)// Triggered when the value of V11 in the app changes
{
  //reads the differential
  tempDiff = param.asFloat();
}
BLYNK_WRITE(V32){
  //reads low alarm
  lowAlarm = param.asFloat();
}
BLYNK_WRITE(V33){
  //reads high alarm
  highAlarm = param.asFloat();
}
void relaysOn()
{
      digitalWrite(relay4Pin, LOW);
    Blynk.virtualWrite(V2, HIGH);
    digitalWrite(relay5Pin, LOW);
    Blynk.virtualWrite(V3, HIGH);
}
void send_data_to_blynk()
{
  Blynk.virtualWrite(5, temp); //virtual pin v5
  Serial.println("Data sent to Blynk");
  
   //check alarms;
  if (isnan(temp)){
    if (Blynk.connected() && !faultyProbeFlag)
    {
      Blynk.notify("Probe disconnected");
      Blynk.email("A.bundy1995@hotmail.co.uk", "Aquaruim Controler Alert", "Probe disconnected");
      faultyProbeFlag = true;
    }
  }
  else if (temp < lowAlarm && !tempAlarmFlag){
    Blynk.notify(String(temp) + "ºC Low temp alarm");
    Blynk.email("A.bundy1995@hotmail.co.uk", "Aquaruim Controler Alert", (String(temp) + "ºC Low temp alarm"));
    tempAlarmFlag = true;
  }
  else if (temp > highAlarm && !tempAlarmFlag){
    Blynk.notify(String(temp) + "ºC High temp alarm");
    Blynk.email("A.bundy1995@hotmail.co.uk", "Aquaruim Controler Alert", (String(temp) + "ºC High temp alarm"));
    tempAlarmFlag = true;
  }
  else if (temp > lowAlarm && temp < highAlarm)
  {
    tempAlarmFlag = false;
  }
  else faultyProbeFlag = false;
}

void Heater()
{
   //if sensor not sending temperature turn relay OFF for safety
  if (isnan(temp)) {
   digitalWrite(relayPin, LOW);
  }
  if (temp  < desiredTemp - tempDiff )
  {
    digitalWrite(relayPin, HIGH);
    
    Serial.println("Heater function where temp  < desiredTemp - tempDiff");    
    Serial.print("temp = ");    
    Serial.println(temp);   
    Serial.print("desiredTemp = ");    
    Serial.println(desiredTemp);
    Serial.print("tempDiff = ");    
    Serial.println(tempDiff);
    Serial.println();    
  }
 
  if (temp > desiredTemp )
  {
    digitalWrite(relayPin, LOW);
    
    Serial.println("Heater function where temp > desiredTemp");  
    Serial.print("temp = ");    
    Serial.println(temp);  
    Serial.print("desiredTemp = ");    
    Serial.println(desiredTemp);
    Serial.print("tempDiff = ");    
    Serial.println(tempDiff);
    Serial.println();
  }
}//--(end Heater )---

void Cooler()
{
  if (temp > desiredTemp - tempDiff )
  {
    digitalWrite(relay2Pin, LOW);
    
    Serial.println("Cooler function where temp > desiredTemp - tempDiff");  
    Serial.print("temp = ");    
    Serial.println(temp);  
    Serial.print("desiredTemp = ");    
    Serial.println(desiredTemp);
    Serial.print("tempDiff = ");    
    Serial.println(tempDiff);
    Serial.println(); 
  }
  if (temp < desiredTemp )
  {
    digitalWrite(relay2Pin, HIGH);
    
    Serial.println("temp < desiredTemp");  
    Serial.print("temp = ");    
    Serial.println(temp);  
    Serial.print("desiredTemp = ");    
    Serial.println(desiredTemp);
    Serial.print("tempDiff = ");    
    Serial.println(tempDiff);
    Serial.println(); 
  }
  if (temp == -127.00)
  digitalWrite(relay2Pin, HIGH);
}//--(end Cooler )---

BLYNK_WRITE(V3){  // Return pump button off 
 int reactor = param.asInt(); // Get State of Virtual Button, Return pump
  if (reactor == 1) {  // button ON
    // Turn as many pins/relays ON as you need
    digitalWrite(relay5Pin, LOW);
  } else {  // button OFF
    // Turn as many pins/relays OFF as you need
    digitalWrite(relay5Pin, HIGH);
  }
}

BLYNK_WRITE(V2){  // Return pump button off 
 int skimmer = param.asInt(); // Get State of Virtual Button, Return pump
  if (skimmer == 1) {  // button ON
    // Turn as many pins/relays ON as you need
    digitalWrite(relay4Pin, LOW);
  } else {  // button OFF
    // Turn as many pins/relays OFF as you need
    digitalWrite(relay4Pin, HIGH);
  }
}

BLYNK_WRITE(V1){  // Return pump button off 
 int value = param.asInt(); // Get State of Virtual Button, Return pump
  if (value == 1) {  // button ON
    // Turn as many pins/relays ON as you need
    digitalWrite(relay3Pin, LOW);
    timer.setTimeout(30000, relaysOn);
  } else {  // button OFF
    // Turn as many pins/relays OFF as you need
    digitalWrite(relay3Pin, HIGH);
    digitalWrite(relay4Pin, HIGH);
    Blynk.virtualWrite(V2, LOW);
    digitalWrite(relay5Pin, HIGH);
    Blynk.virtualWrite(V3, LOW);
  }
}
void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);  // start serial port to show results
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  
  DS18B20.begin(); // Initialize the Temperature measurement library
  
  // set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
  DS18B20.setResolution(Probe01, 12);
pinMode(relayPin, OUTPUT);
pinMode(relay2Pin, OUTPUT);
pinMode(relay3Pin, OUTPUT);
pinMode(relay4Pin, OUTPUT);
pinMode(relay5Pin, OUTPUT);
pinMode(wave1Pin, OUTPUT);
 
  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
  Blynk.begin(auth);  // Here your Arduino connects to the Blynk Cloud.  
  timer.setInterval(1000L, take_temp_readings);  // Setup a function to be called every second
  timer.setInterval(5000L, send_data_to_blynk);
timer.setInterval(1500L, Heater);
timer.setInterval(1300L, Cooler);
timer.setInterval(wavetime);
}//--(end setup )---

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  Blynk.run(); // All the Blynk Magic happens here...
  timer.run(); // Initiates BlynkTimer   


}//--(end main loop )---

void take_temp_readings() {
  //Serial.print("Number of Devices found on bus = ");  
  //Serial.println(DS18B20.getDeviceCount());   
  //Serial.print("Getting temperatures... ");  
  //Serial.println();   
   
  DS18B20.requestTemperatures();  // Command all devices on bus to read temperature  
  
temp = DS18B20.getTempCByIndex(0);

 
   if (temp == -127.00) 
   {
    Serial.println("Error getting temperature  ");
   } 
 
     }
//*********( THE END )***********

Not sure about your compile error… but you can’t run a disable/delete command prior to actually defining the timer you want to disable.

ok i have take that out but i thought it was needed for when the value changes to it deletes the old one and uses the new one.

i have added some Serial.prints to help see whats going on and i noticed that for some reason my timerID is -1 no matter what the input value

BLYNK_WRITE(V4){   // add a slider on V0 range 0 to 30 (minutes)
  int seconds = param.asInt();
  timerID = timer.setInterval(seconds * 1000L, notifyUptime);
    Serial.print("seconds = ");    
    Serial.println(seconds);  
    Serial.println("timerID = ");
    Serial.println(timerID); 
}

Your timer ID is not a fluctuating variable, it is an ID that gets assigned to that particular timer in order to use special commands like enable, disable, etc.

Fred = timer.setInterval(1000L, DoStuff);

Fred becomes your Timer ID, for that particular timer, and thus can be used as such…

timer.enable(Fred);

timer.disable(Fred);

timer.restartTimer(Fred);

timer.deleteTimer(Fred);

ok so i dont really need to put the timeID = in the setup?

just this

int wavetime = 1;
int timerID =5;
BLYNK_WRITE(V4){   // add a slider on V0 range 0 to 30 (minutes)
  int seconds = param.asInt();
  timerID = timer.setInterval(seconds * 1000L, wavecontrol);
    Serial.print("seconds = ");    
    Serial.println(seconds);  
    Serial.println("timerID = ");
    Serial.println(timerID); 
}
BLYNK_WRITE(V6){  // Return pump button off 
 int wavesw = param.asInt(); // Get State of Virtual Button, Return pump
  if (wavesw == 1) {  // button ON
    // Turn as many pins/relays ON as you need
    digitalWrite(wave1Pin, HIGH);
    digitalWrite(wave2Pin, LOW);
    timer.enable(timerID);
  } else {  // button OFF
    // Turn as many pins/relays OFF as you need
    digitalWrite(wave1Pin, LOW);
    digitalWrite(wave2Pin, LOW);
  }
}
void wavecontrol()
{
  digitalWrite(wave1Pin, LOW);
  digitalWrite(wave2Pin, HIGH);
}

should i also make “seconds” a float variable?

i tried this and its seems to stay on (wave1Pin, HIGH); (wave2Pin, LOW) for a few seconds then over to (wave1Pin, LOW); (wave2Pin, HIGH); but stays like that and dosnt go back to the first setting with the set time delay.

Depends… if you are just using a simple timer, no… if however you want more dynamic control of a timer, then yes.

But, it appears you are still doing it wrong… :stuck_out_tongue_winking_eye: It is not a simple Arduino type variable that holds user assigned data, it is a SimpleTimer/BlynkTimer specific ID method.

Hi @Bundy, I think there’s a couple of things that you’re doing here that aren’t working well for you.
In your first post in this topic you asked

What you’re doing in the BLYNK_WRITE(V4) function is correct, except that by having int in front of waveDelay = param.asFloat() you’re declaring waveDelay as a local variable. This means that it cant be used outside of the function where it’s declared. in your full code example, you waveDelay as a global variable by having it at the top of your code, but this is being overridden by the fact that you are re-declaring the variable in the BLYNK_WRITE(V4) function.
Your function should look like this:

BLYNK_WRITE(V4)// Time interval for wave makers
{ 
 waveDelay = param.asFloat();// reads value 
}

This way, you’ll then be able to use the value that comes from the V4 widget in other areas of your code. Personally, I’d change the declaration of waveDelay to assign it a value of zero at the beginning, so that it only has a value when you’ve specifically assigned one via the V4 widget.

Obviously, if you’re doing the processing within the BLYNK_WRITE(V4) function, as you later started to do, the re-declaration of the waveDelay variable doesnt really matter (but it should be avoided anyway).

You then seem to be getting yourself mixed-up between the timer ID, and the delay that you want to use when you call that timer. I think you may also be mixing-up the waveDelay and waveTime variables.
If I were you’ I’d simplify your code. Take-out the stuff that controls your lights and temperature as you know that this already works. Just focus on the code for the duration that you want your wave machine to run for and use one widget to set this value and use the result for your timer duration.
Once it’s working then insert the code into your working sketch and then develop the next element in isolation and so on.

Pete.

thank you very much for your help, iv now chosen different route to controling the relays by using this code:

void wave_control()
{
  Serial.print("\n");
  Serial.println(":: Executing check loop this minute");

  if ((CounterOn > 0) && (ledStatus == 0))
  {
      digitalWrite(wave1Pin,HIGH);   //write to pin to turn the LED on.
      digitalWrite(wave2Pin,LOW);
      Serial.print(": LED on\n");
      ledStatus = 1;
      CounterOff = 0;
   }
  if ((CounterOn > 0) && (ledStatus == 1))
      {
      CounterOn = (CounterOn - 1);
      }
      
  if ((CounterOff == 0) && (CounterOn == 0) && (ledStatus == 1))
    {
      CounterOff = onsec;
    }

  if ((CounterOff > 0) && (ledStatus == 1))
  {
      digitalWrite(wave1Pin,LOW);   //write to pin to turn wave1 off
      digitalWrite(wave2Pin,HIGH);//write to pin to turn wave2 on
      Serial.print(": LED off\n");
      ledStatus = 0;
      CounterOn = 0;
   }
   
  if ((CounterOff > 0) && (ledStatus == 0))
      {
      CounterOff = (CounterOff - 1);
      }
      
  if ((CounterOff == 0) && (CounterOn == 0) && (ledStatus == 0))
    {
      CounterOn = onsec+1;
    }

and thisin the loop:

 if (onsec== 0)
  {
    onsec=1;
  }
  if (offsec== 0)
  {
    offsec=1;
  }

am i correct in saying the last bit in the loop function isnt needed if i dont want to make onsec or offsec = 1 if the set value is 0? also could i turn this function on and off with a virtual button using delcareing onsec and offsec as 0 when the pinvalue of the virtual button = 0 and then digital write the relays low?

i should add that there is also a timer set on the function: timer.setInterval(1000L, wave_control); this convets the values inputed by the sliders to set onsec and offsec.

i think ill come back to using the timer function some other day when i have a little more time.

with the above code, the relays function like they should and i can change the times with the slider but i dont necessarily want them to run all the time hene in inplement of a virtual button. :slight_smile:

thanks in advance.
Adam

I cant tell if these are needed in your void loop without seeing all of your code and taking the time to pick through the logic - which I’m not going to do!

However, the golden rule of Blynk is that the only thing that should be in your void loop is:

Blynk.run();
timer.run();

Try taking your code out of the loop and testing again. if it works then fine, if not then go back to the drawing board.

Pete.