I havde the following sketch for a reef tank controller.
V2 to V8 are sliders controlling the brightness over PWM of LEDS.
V9 is a save button
V10 is a reset button to reset the sliders to 0 at the end of programming new light settings.
There is a problem that happens at different times. I will adjust the sliders and it works, I will press save and it works, I press reset and it works, but EVERYTIME it eventually freezes up. Currently V9 is stuck on so it clearly isn’t running the function that V9 is supposed to trigger. Can you see why?
// -- EEPROM KEY --
// No - DESCRIPTION
// 0 - TEST CHANNEL
// 1 - lunar.ch1
// 2 - lunar.ch2
// 3 - lunar.ch3
// 4 - lunar.ch4
// 5 - lunar.ch5
// 6 - lunar.ch6
// 7 - lunar.ch7
// 8 - lowsun.ch1
// 9 - lowsun.ch2
// 10 - lowsun.ch3
// 11 - lowsun.ch4
// 12 - lowsun.ch5
// 13 - lowsun.ch6
// 14 - lowsun.ch7
// 15 - midsun.ch1
// 16 - midsun.ch2
// 17 - midsun.ch3
// 18 - midsun.ch4
// 19 - midsun.ch5
// 20 - midsun.ch6
// 21 - midsun.ch7
// 22 - highsun.ch1
// 23 - highsun.ch2
// 24 - highsun.ch3
// 25 - highsun.ch4
// 26 - highsun.ch5
// 27 - highsun.ch6
// 28 - highsun.ch7
// 29 - **** SPARE ****
// 30 - lunartolowsunStartH
// 31 - lowsuntomidsunStartH
// 32 - midsuntohighsunStartH
// 33 - highsuntomidsunStartH
// 34 - midsuntolowsunStartH
// 35 - lowsuntolunarStartH
// 36 - lunartolowsunStartM
// 37 - lowsuntomidsunStartM
// 38 - midsuntohighsunStartM
// 39 - highsuntomidsunStartM
// 40 - midsuntolowsunStartM
// 41 - lowsuntolunarStartM
// 42 - globalfadedurationM
// 43 - globalfadedurationS
// 44 - globalfadedurationMS
// 45 - **** SPARE ****
// 46 - currentlightmode (0=lunar, 1=low sun, 2=mid sun, 3=high sun, 4=transition, 5=unknown)
// 47 - transitionMode (0- none, 1- l-ls, 2- ls-ms, 3- ms-hs, 4- hs-ms, 5- ms-ls, 6- ls-l)
// 48 - lightedit (0-NOT EDITING 1-EDIT LUNAR 2-EDIT LOWSUN 3-EDIT MIDSUN 4-EDIT HIGHSUN)
// 49 - fadeInProgress (0=false / 1=yes)
// 50 - **** SPARE ****
// 51 - currentColor.ch1
// 52 - currentColor.ch2
// 53 - currentColor.ch3
// 54 - currentColor.ch4
// 55 - currentColor.ch5
// 56 - currentColor.ch6
// 57 - currentColor.ch7
// 60 - Power socket 1 - UV
// 61 - Power socket 2 - ATO
// 62 - Power socket 3 - REACTOR
// 63 - Power socket 4 - DOSER
// 64 - Power socket 5 - SUMP LIGHT
// 65 - Power socket 6 - COOLING
// 66 - Power socket 7 - HEATER
// 67 - Power socket 8 - SKIMMER
// 68 - Power socket 9 - POWER HEADS
// 69 - Power socket 10 - RETURN PUMP
// -- VIRTUAL PIN KEY --
// No - DESCRIPTION
// 0 - LCD widget on lighting LEDs page
// 1 - MENU widget on lighting LEDs page
// 2 - SLIDER widget on lighting LEDs page (ch1)
// 3 - SLIDER widget on lighting LEDs page (ch2)
// 4 - SLIDER widget on lighting LEDs page (ch3)
// 5 - SLIDER widget on lighting LEDs page (ch4)
// 6 - SLIDER widget on lighting LEDs page (ch5)
// 7 - SLIDER widget on lighting LEDs page (ch6)
// 8 - SLIDER widget on lighting LEDs page (ch7)
// 9 - BUTTON widget save changes on lighting LEDs page
// 10 - BUTTON widget to reset lights
// 11 - TIME INPUT widget for lighting TIMES (lunar to lowsun)
// 12 - TIME INPUT widget for lighting TIMES (lowsun to midsun)
// 13 - TIME INPUT widget for lighting TIMES (midsun to highsun)
// 14 - TIME INPUT widget for lighting TIMES (highsun to midsun)
// 15 - TIME INPUT widget for lighting TIMES (midsun to lowsun)
// 16 - TIME INPUT widget for lighting TIMES (lowsun to lunar)
// 17 - +/- BUTTONS widget for 'global' fade duration
// 18 - LABEL DISPLAY widget for 'global' fade duration
// 19 - DISPLAY Float switch 1 - not required
// 20 - DISPLAY Float switch 2 - not required
// 21 - DISPLAY Temp 1
// 22 - DISPLAY Temp 2
// 23 - DISPLAY Temp 3
// 24 - BUTTON sump light timer active
// 25 - TIME INPUT widget for sump lighting ON
// 26 - TIME INPUT widget for sump lighting OFF
// 27 - BUTTON for Arduino resetresetFunc(); //call reset
// 28 -
// 29 -
// POWER SOCKET BUTTONS
// 30 - UV
// 31 - ATO
// 32 - REACTOR PUMP
// 33 - DOSER PUMP POWER
// 34 - SUMP LIGHT
// 35 - COOLING FANS
// 36 - HEATER
// 37 - SKIMMER
// 38 - POWER HEADS
// 39 - RETURN PUMP
// POWER SOCKET LEDS
// 40 - UV
// 41 - ATO
// 42 - REACTOR PUMP
// 43 - DOSER PUMP POWER
// 44 - SUMP LIGHT
// 45 - COOLING FANS
// 46 - HEATER
// 47 - SKIMMER
// 48 - POWER HEADS
// 49 - RETURN PUMP
// FORCE LIGHT MODE
// 60 - BUTTON push widget LUNAR
// 61 - BUTTON push widget LOWSUN
// 62 - BUTTON push widget MIDSUN
// 63 - BUTTON push widget HIGHSUN
// 64 - BUTTON widget STORM
// DOSING
// 70 - BUTTON Dose 1 on/off
// 71 - BUTTON Dose 2 on/off
// 72 - BUTTON Dose 3 on/off
// 73 - BUTTON Dose 4 on/off
// 74 - BUTTON Dose 1 Prime
// 75 - BUTTON Dose 2 Prime
// 76 - BUTTON Dose 3 Prime
// 77 - BUTTON Dose 4 Prime
// 78 - BUTTON Dose 1 Reset
// 79 - BUTTON Dose 2 Reset
// 80 - BUTTON Dose 3 Reset
// 81 - BUTTON Dose 4 Reset
// 82 - SLIDER Dose 1 Reset
// 83 - SLIDER Dose 2 Reset
// 84 - SLIDER Dose 3 Reset
// 85 - SLIDER Dose 4 Reset
// 86 - METER Dose 1 Reset
// 87 - METER Dose 2 Reset
// 88 - METER Dose 3 Reset
// 89 - METER Dose 4 Reset
// 90 - VALUE Dose 1 Left
// 91 - VALUE Dose 2 Left
// 92 - VALUE Dose 3 Left
// 93 - VALUE Dose 4 Left
// 94 - TIME INPUT Dose 1 Start time
// 95 - TIME INPUT Dose 2 Start time
// 96 - TIME INPUT Dose 3 Start time
// 97 - TIME INPUT Dose 4 Start time
#define BLYNK_PRINT Serial1
#define ONE_WIRE_BUS_PIN 44 // TEMP SENSORS
#define BETWEEN 2579 // STORM
#define DURATION 100 // STORM
#define TIMES 7 // STORM
#include <BlynkSimpleStream.h>
#include <Wire.h>
#include <Time.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DS1307RTC.h>
#include <EEPROM.h>
OneWire oneWire(ONE_WIRE_BUS_PIN);
DallasTemperature sensors(&oneWire);
DeviceAddress Probe01 = { 0x28, 0x5E, 0x72, 0xC5, 0x06, 0x00, 0x00, 0xA4 };
DeviceAddress Probe02 = { 0x28, 0x9F, 0x49, 0x2F, 0x06, 0x00, 0x00, 0xAA };
DeviceAddress Probe03 = { 0x28, 0x7A, 0xFB, 0xC4, 0x06, 0x00, 0x00, 0x79 };
char auth[] = "65b59**********************************166";
//-----Temp Sensors
float tempC01, tempC02, tempC03;
unsigned int tempMillis = millis();
//----- Power Plugs
int pwr1, pwr2, pwr3, pwr4, pwr5, pwr6, pwr7, pwr8, pwr9, pwr10;
int pwrbut1, pwrbut2, pwrbut3, pwrbut4, pwrbut5, pwrbut6, pwrbut7, pwrbut8, pwrbut9, pwrbut10;
int sensorVal1, sensorVal2;
int sump1ontime, sump2ontime, sump1onH, sump1onM, sump2onH, sump2onM, sump1offH, sump1offM, sump2offH, sump2offM;
int sumptimer1active, sumptimer2active;
//----- Storm
unsigned long lastTime = 0;
int waitTime = 0;
int mixer, srumble, brumble, stormstatus=0, stormbutton;
unsigned long stormMillis=0;
unsigned int storm1, storm2, storm3, storm4, storm5, storm6, storm7;
//----- Lighting
int savechangesbut; // button used to save new light levels
int resetchangesbut; // button used to reset lighting after editing
int resetarduinobut; // button used to reset the whooe Arduino
int lightedit=0; // editing lights? // 0-NOT EDITING 1-EDIT LUNAR 2-EDIT LOWSUN 3-EDIT MIDSUN 4-EDIT HIGHSUN
int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
int led5 = 6;
int led6 = 7;
int led7 = 8;
long lunartolowsunSec, lowsuntomidsunSec, midsuntohighsunSec, highsuntomidsunSec, midsuntolowsunSec, lowsuntolunarSec;
int globalfadedurationM;
unsigned long globalfadedurationS, globalfadedurationMS;
int lunartolowsunStartH, lunartolowsunStartM; // Start fade times
int lowsuntomidsunStartH, lowsuntomidsunStartM;
int midsuntohighsunStartH, midsuntohighsunStartM;
int highsuntomidsunStartH, highsuntomidsunStartM;
int midsuntolowsunStartH, midsuntolowsunStartM;
int lowsuntolunarStartH, lowsuntolunarStartM;
int fadeInProgress; // 0=false / 1=yes
int currentLightMode, transitionMode;
unsigned long ch1LightMillis, ch2LightMillis, ch3LightMillis, ch4LightMillis, ch5LightMillis, ch6LightMillis, ch7LightMillis;
int ch1timeincr, ch2timeincr, ch3timeincr, ch4timeincr, ch5timeincr, ch6timeincr, ch7timeincr;
int colorDif1, colorDif2, colorDif3, colorDif4, colorDif5, colorDif6, colorDif7;
unsigned long savelightsMillis = 0;
int butLunar, butLowsun, butMidsun, butHighsun;
int zero=0;
struct LEDS // for storing light intensity values
{
int ch1;
int ch2;
int ch3;
int ch4;
int ch5;
int ch6;
int ch7;
};
typedef struct LEDS LightColor;
LightColor currentColor = {
0,0,0,0,0,0,0}; // The current color of the light (used for fading)
LightColor lastColor = {
0,0,0,0,0,0,0}; // The previous color of the light (used for fading)
LightColor targetColor = {
0,0,0,0,0,0,0}; // The target color of the light (used for fading)
LightColor lunar = { // Lunar colours
0,0,0,0,0,0,0};
LightColor lowsun = { // Lowsun colours
0,0,0,0,0,0,0};
LightColor midsun = { // Midsun colours
0,0,0,0,0,0,0};
LightColor highsun = { // Highsun colours
0,0,0,0,0,0,0};
LightColor edit = { // Used to edit colours
0,0,0,0,0,0,0};
//----- Feeding
int feeding;
//----- RTC
unsigned long time;
tmElements_t tm;
//----- Dosing
long dose1startTime, dose2startTime, dose3startTime, dose4startTime;
void(* resetFunc) (void) = 0; //declare reset function @ address 0
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
///////////////////// ///////////////////////
///////////////////// B L Y N K I N P U T S ///////////////////////
///////////////////// ///////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
BLYNK_WRITE(V1)
{
switch (param.asInt())
{
case 1:
lightedit=0; // 0-NOT EDITING 1-EDIT LUNAR 2-EDIT LOWSUN 3-EDIT MIDSUN 4-EDIT HIGHSUN
edit.ch1=highsun.ch1;
edit.ch2=highsun.ch2;
edit.ch3=highsun.ch3;
edit.ch4=highsun.ch4;
edit.ch5=highsun.ch5;
edit.ch6=highsun.ch6;
edit.ch7=highsun.ch7;
Blynk.virtualWrite(V2, edit.ch1);
Blynk.virtualWrite(V3, edit.ch2);
Blynk.virtualWrite(V4, edit.ch3);
Blynk.virtualWrite(V5, edit.ch4);
Blynk.virtualWrite(V6, edit.ch5);
Blynk.virtualWrite(V7, edit.ch6);
Blynk.virtualWrite(V8, edit.ch7);
showeditleds();
break;
case 2: // E D I T L U N A R L I G H T I N G
lightedit=1; // 0-NOT EDITING 1-EDIT LUNAR 2-EDIT LOWSUN 3-EDIT MIDSUN 4-EDIT HIGHSUN
edit.ch1=lunar.ch1;
edit.ch2=lunar.ch2;
edit.ch3=lunar.ch3;
edit.ch4=lunar.ch4;
edit.ch5=lunar.ch5;
edit.ch6=lunar.ch6;
edit.ch7=lunar.ch7;
Blynk.virtualWrite(V2, edit.ch1);
Blynk.virtualWrite(V3, edit.ch2);
Blynk.virtualWrite(V4, edit.ch3);
Blynk.virtualWrite(V5, edit.ch4);
Blynk.virtualWrite(V6, edit.ch5);
Blynk.virtualWrite(V7, edit.ch6);
Blynk.virtualWrite(V8, edit.ch7);
showeditleds();
break;
case 3: // E D I T L O W S U N L I G H T I N G
lightedit=2; // 0-NOT EDITING 1-EDIT LUNAR 2-EDIT LOWSUN 3-EDIT MIDSUN 4-EDIT HIGHSUN
edit.ch1=lowsun.ch1;
edit.ch2=lowsun.ch2;
edit.ch3=lowsun.ch3;
edit.ch4=lowsun.ch4;
edit.ch5=lowsun.ch5;
edit.ch6=lowsun.ch6;
edit.ch7=lowsun.ch7;
Blynk.virtualWrite(V2, edit.ch1);
Blynk.virtualWrite(V3, edit.ch2);
Blynk.virtualWrite(V4, edit.ch3);
Blynk.virtualWrite(V5, edit.ch4);
Blynk.virtualWrite(V6, edit.ch5);
Blynk.virtualWrite(V7, edit.ch6);
Blynk.virtualWrite(V8, edit.ch7);
showeditleds();
break;
case 4: // E D I T M I D S U N L I G H T I N G
lightedit=3; // 0-NOT EDITING 1-EDIT LUNAR 2-EDIT LOWSUN 3-EDIT MIDSUN 4-EDIT HIGHSUN
edit.ch1=midsun.ch1;
edit.ch2=midsun.ch2;
edit.ch3=midsun.ch3;
edit.ch4=midsun.ch4;
edit.ch5=midsun.ch5;
edit.ch6=midsun.ch6;
edit.ch7=midsun.ch7;
Blynk.virtualWrite(V2, edit.ch1);
Blynk.virtualWrite(V3, edit.ch2);
Blynk.virtualWrite(V4, edit.ch3);
Blynk.virtualWrite(V5, edit.ch4);
Blynk.virtualWrite(V6, edit.ch5);
Blynk.virtualWrite(V7, edit.ch6);
Blynk.virtualWrite(V8, edit.ch7);
showeditleds();
break;
case 5: // E D I T H I G H S U N L I G H T I N G
lightedit=4; // 0-NOT EDITING 1-EDIT LUNAR 2-EDIT LOWSUN 3-EDIT MIDSUN 4-EDIT HIGHSUN
edit.ch1=highsun.ch1;
edit.ch2=highsun.ch2;
edit.ch3=highsun.ch3;
edit.ch4=highsun.ch4;
edit.ch5=highsun.ch5;
edit.ch6=highsun.ch6;
edit.ch7=highsun.ch7;
Blynk.virtualWrite(V2, edit.ch1);
Blynk.virtualWrite(V3, edit.ch2);
Blynk.virtualWrite(V4, edit.ch3);
Blynk.virtualWrite(V5, edit.ch4);
Blynk.virtualWrite(V6, edit.ch5);
Blynk.virtualWrite(V7, edit.ch6);
Blynk.virtualWrite(V8, edit.ch7);
showeditleds();
break;
}
}
BLYNK_WRITE(V2)
{
edit.ch1 = param.asInt();
analogWrite(led1, edit.ch1);
}
BLYNK_WRITE(V3)
{
edit.ch2 = param.asInt();
analogWrite(led2, edit.ch2);
}
BLYNK_WRITE(V4)
{
edit.ch3 = param.asInt();
analogWrite(led3, edit.ch3);
}
BLYNK_WRITE(V5)
{
edit.ch4 = param.asInt();
analogWrite(led4, edit.ch4);
}
BLYNK_WRITE(V6)
{
edit.ch5 = param.asInt();
analogWrite(led5, edit.ch5);
}
BLYNK_WRITE(V7)
{
edit.ch6 = param.asInt();
analogWrite(led6, edit.ch6);
}
BLYNK_WRITE(V8)
{
edit.ch7 = param.asInt();
analogWrite(led7, edit.ch7);
}
BLYNK_WRITE(V9) // Save Lighting Changes
{
savechangesbut = param.asInt();
if (savechangesbut == 1)
{
savevalues();
}
}
BLYNK_WRITE(V10) // Save Lighting Changes
{
resetchangesbut = param.asInt();
if (resetchangesbut == 1)void(* resetFunc) (void) = 0;
{
resetlights();
}
}
//======================================================================================
//================================================ LIGHTINGS (TIMES) V10 - V16 ======
//======================================================================================
//=============================================== FADE START TIMES
BLYNK_WRITE(V11) // LUNAR TO LOWSUN (TIME)
{
TimeInputParam t(param);
if (t.hasStartTime())
{
lunartolowsunStartH=t.getStartHour();
lunartolowsunStartM=t.getStartMinute();
}
}
BLYNK_WRITE(V12) // LOWSUN TO MIDSUN (TIME)
{
TimeInputParam t(param);
if (t.hasStartTime())
{
lowsuntomidsunStartH=t.getStartHour();
lowsuntomidsunStartM=t.getStartMinute();
}
}
BLYNK_WRITE(V13) // MIDSUN TO HIGHSUN (TIME)
{
TimeInputParam t(param);
if (t.hasStartTime())
{
midsuntohighsunStartH=t.getStartHour();
midsuntohighsunStartM=t.getStartMinute();
}
}
BLYNK_WRITE(V14) // HIGHSUN TO MIDSUN (TIME)
{
TimeInputParam t(param);
if (t.hasStartTime())
{
highsuntomidsunStartH=t.getStartHour();
highsuntomidsunStartM=t.getStartMinute();
}
}
BLYNK_WRITE(V15) // MIDSUN TO LOWSUN (TIME)
{
TimeInputParam t(param);
if (t.hasStartTime())
{
midsuntolowsunStartH=t.getStartHour();
midsuntolowsunStartM=t.getStartMinute();
}
}
BLYNK_WRITE(V16) // LOWSUN TO LUNAR (TIME)
{
TimeInputParam t(param);
if (t.hasStartTime())
{
lowsuntolunarStartH=t.getStartHour();
lowsuntolunarStartM=t.getStartMinute();
}
}
//=============================================== 'GLOBAL' FADE DURATION
BLYNK_WRITE(V17) // +/- BUTTONS
{
globalfadedurationM = param[0].asLong(); // Obtain fade minutes
// IF THIS IS PRINTED TO THE SCREEN LOTS AND LOTS OF TIMES THEN THIS IS BEING CALLED ALL OF THE TIME AND NOT JUST WHEN THE BUTTON IS PRESSED. YOU NEED TO RETHINK THE CALCUATIONS BELOW AND THE WRITE TO EEPROM.");
globalfadedurationS = globalfadedurationM * 60; // Calculate fade seconds
globalfadedurationMS = globalfadedurationS * 1000; // Calculate fade miliseconds
Blynk.virtualWrite(V12, globalfadedurationM); // fade time in minutes to V12 labled display
EEPROM.write(42, globalfadedurationM); // Save new values to EEPROM
//EEPROM.write(43, globalfadedurationS);
//EEPROM.write(44, globalfadedurationMS);
}
BLYNK_WRITE(V27) // Call reset
{
resetarduinobut = param.asInt();
if (resetarduinobut == 1)
{
resetFunc();
}
}
//======================================================================================
//==================================================== POWER SUPPLIES V30 - V39 =====
//======================================================================================
BLYNK_WRITE(V30) // UV
{
pwrbut1 = param.asInt();
if (pwrbut1 == 1) // 1 - UV
{
pwr1on();
}
else
{
pwr1off();
}
}
BLYNK_WRITE(V31) // ATO ----------> IN VOID LOOP
{
pwrbut2 = param.asInt();
}
BLYNK_WRITE(V32) // REACTOR PUMP
{
pwrbut3 = param.asInt();
if (pwrbut3 == 1) // 3 - REACTOR PUMP
{
pwr3on();
}
else
{
pwr3off();
}
}
BLYNK_WRITE(V33) // DOSER
{
pwrbut4 = param.asInt();
if (pwrbut4 == 1) // 4 - DOSER PUMP POWER
{
pwr4on();
}
else
{
pwr4off();
}
}
BLYNK_WRITE(V34) // SUMP LIGHT 1
{
pwrbut5 = param.asInt();
if (pwrbut5 == 1) // 5 - SUMP LIGHT
{
pwr5on();
}
else
{
pwr5off();
}
}
BLYNK_WRITE(V35) // COOLING FANS
{
pwrbut6 = param.asInt();
if ((pwrbut6 == 1) || (sump2ontime == 1)) // 6 - COOLING FANS
{
pwr6on();
}
else
{
pwr6off();
}
}
BLYNK_WRITE(V36) // HEATER
{
pwrbut7 = param.asInt();
if (pwrbut7 == 1) // 7 - HEATER
{
pwr7on();
}
else
{
pwr7off();
}
}
BLYNK_WRITE(V37) // SKIMMER ----------> IN VOID LOOP
{
pwrbut8 = param.asInt();
}
BLYNK_WRITE(V38) // POWER HEADS
{
pwrbut9 = param.asInt();
if ((pwrbut9 == 1) && (feeding == 0)) // 9 - POWER HEADS
{
pwr9on();
}
else
{
pwr9off();
}
}
BLYNK_WRITE(V39) // RETURN PUMP
{
pwrbut10 = param.asInt();
if (pwrbut10 == 1) // 10 - RETURN PUMP
{
pwr10on();
}
else
{
pwr10off();
}
}
BLYNK_WRITE(V60) // Call Full Lunar
{
butLunar = param[0].asLong();
if (butLunar == 1)
{
lunarFull();
}
}
BLYNK_WRITE(V61) // Call Full Lowsun
{
butLowsun = param[0].asLong();
if (butLowsun == 1)
{
lowsunFull();
}
}
BLYNK_WRITE(V62) // Call Full Midsun
{
butMidsun = param[0].asLong();
if (butMidsun == 1)
{
midsunFull();
}
}
BLYNK_WRITE(V63) // Call Full Highsun
{
butHighsun = param[0].asLong();
if (butHighsun == 1)
{
highsunFull();
}
}
BLYNK_WRITE(V64) // STORM BUTTON
{
stormbutton = param.asInt();
if (stormbutton == 1)
{
//stormstatus=1; // 0- Off 1- fade down 2- storm on 3- fade up
stormbegin();
}
}
BLYNK_WRITE(V94)
{
dose1startTime = param[0].asLong();
}
BLYNK_WRITE(V95)
{
dose2startTime = param[0].asLong();
}
BLYNK_WRITE(V96)
{
dose3startTime = param[0].asLong();
}
BLYNK_WRITE(V97)
{
dose4startTime = param[0].asLong();
}
BLYNK_READ(V90)
{
Blynk.virtualWrite(V90, dose1startTime);
}