Visual Data's software sketch for an Arduino -do-it-yourself- multi sensoring system

This is my general Arduino sketch.
This sketch is maynly designed to transform the Arduino data to a format that Prophetes can use. See the Prophetes pages on this website for more information.

I use it for a scala of sensoring and teherfore there are a couple of variabeles that may not apply to your use of it.
This one has a set up for my Water Monitor on my 'Amazone Biotope Aquarium', hence the settings for ThingSpeak.
All other settings are set to 'false' in order to neglect the output.

/*
************************************************************************
********* PythiaMultiSensorSystemAquarium_PH_ORP_Timer.ino **********
************************************************************************
************************************************************************
*********** Pythia Water Condition Sensor ***********
*********** Created and programmed by Jos Richters ***********
*********** Version 2.2.3 Date 2018-07-29 ***********
************************************************************************
************************************************************************
*/
//*********************************************************************************************************************************************************************************
#include "Timer.h"
#include
#include
#define int5Volt 5 //The 5 volt operational power.
#define ONE_WIRE_BUS 8 //Digital input on digital pin 8 for measuring temperature.
#define analogPinLightA0 A0 //AnalogPin for measuring light units.
#define analogPHpinA1 A1 //AnalogPin for measuring pH units.
#define analogORPpinA2 A2 //AnalogPin for measuring ORP units.
#define analogPinA3 A3 //AnalogPin for measuring (NotInUse).
#define analogPinA4 A4 //AnalogPin for measuring (NotInUse).
#define analogPinA5 A5 //AnalogPin for measuring (NotInUse).
#define digitalPinHertz6 6 //digitalPinHertz6 6.
#define digitalPinHertz7 7 //digitalPinHertz7 7.
#define digitalPinPH 12 //digitalPinPH 12.
#define digitalPinORP 13 //digitalPinORP 13.
#define NumSamples 60 //Number of samples collection.
//*********************************************************************************************************************************************************************************

//Headers.
#define LineVDW "#S|GOBETWINO|[ =*= Visual Data Webservices and Visual Data's Pythia: www.rca-pythia.net\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t=*=]#"
#define LineMail "#S|GOBETWINO|[ =*= For more information send mail a request to: info@visualdata.nl\t\t\t\t\t\t\t\t\t\t\t=*=]#"
#define LineInit "#S|GOBETWINO|[ =*= Initializing sensors. Please be patient, this will take about 1 minute...\t\t\t\t\t\t\t\t\t\t\t\t\t\t=*=]#"
#define LineLegend "#S|GOBETWINO|[ =*= (1)Light; (2)Temp; (3)pH; (4)ORP; (5)rH;\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t=*=]#"

//Miscellaneous.
#define Device1 "Controller temperature"
#define Device2 "Aquarium temperature"
#define Device3 "NotInUse"

#define SingleLine "#S|GOBETWINO|[ =*------------------------------------------------------------------------------------------------------------------------------------*=]#"
#define DoubleLine "#S|GOBETWINO|[ =*===================================================================================================================================*=]#"

#define LineVDWQ "#S|GOBETWINO|[ =*= Visual Data Webservices: www.rca-pythia.net\t\t\t\t\t\t\t=*=]#"
#define LineMailQ "#S|GOBETWINO|[ =*= For more information send a mail request to: info@visualdata.nl\t\t=*=]#"
//#define DoubleLineQ "#S|GOBETWINO|[\n\n\n\n\n\t\t\t\t\t=*===================================================================================*=]#"
#define DoubleLineQ "#S|GOBETWINO|[ =*=======================================================================*=]#"
//*********************************************************************************************************************************************************************************

//Timekeeping.
Timer tmeMinute;
bool showTiming = false; //Show the timing values for the delay in order to sample every one minute.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
unsigned long startSampleTime = 0; //Variable to store the start moment for the total delay time.
const unsigned long totalDelayValue = 60000; //Variable to store the total delay for one measurement on all sensors on one minute.
const int correctedDelay = 200; //Delay: 150; Variable to store the correction time in order to keep the sensoring period exactly 1 minute.
const unsigned long QuickTestTime = 10000; //Variable to store the quickTest delay for one measurement on all sensors on one minute.
unsigned long Delay = 20; //Variable to store the delay for the measurement loop.
/*
Increase correctedDelay with steps of 10 when the timing goes up during sampling, otherwise decrease.
When timing set all other sensor info's to their designated status and determine the correction time in order to run a loop in exactly 60.000 milliseconds (= one minute).
During looping thru the program, the date and time are displayed in the left columns. observe whether the second part is changing during this test.
When the next loop has another second in it, you will know that the timing needs adjustment; a second higher means subtracting the correctedDelay from the calculated delay value, and vice versa when otherwise.
Determine the difference between the timeCounts from the start moment and the first changed number of seconds. Set the numberOfReadings variable to this number and run the sketch again.
Adjust for a positive correctedDelay when the next second is HIGHER as the previous one; or correct for a negative correction in case otherwise.

Upload the sketch again and retrieve the timing calibration. Place this in variable [correctedDelay].
*/
//*********************************************************************************************************************************************************************************

//Calculate pH from Vcc = 5Volt.
static double Calculate_pH5Volt (double Vad, double temperature)
{
double E, E0, C, T;
const double R = 8.31441, N = 1, F = 96484.6;
T = (273.15) + temperature;
C = 2.3 * ((R * T)/(N * F));
E0 = 7 * C;
E = (2.5 - Vad) / 4.745;
return ((E0 - E) / C);
}//double Calculate_pH5Volt
//*********************************************************************************************************************************************************************************

//Calculate rH from ORP and pH.
static double Calculate_rH (double ORP, double pH)
{
double rH;
rH = (ORP / 29) + (2 * pH) + 6.76;
return rH;
}//double Calculate_rH

//Pin voltage determination.
/* Volt = (analogRead(pin) + k) * int5Volt / 1024;
with k of
0 for floor
0.5 for mean
1 for ceiling
*/
//*********************************************************************************************************************************************************************************

//StartSetChannels to Prophetes.
bool setChannelToCOM = false; //Channel to COM creates records to the COM port for Prophetes to listen to this Arduino on the USB/COM port.
bool setChannelToGoBetwino = false; //Channel Arduino output to Gobetwino.
String cmdToGoBetwino = "#S|GOBETWINO|";
//Output to Prophetes.
bool setChannelToSQL = false; //Channel Arduino output to Gobetwino.
String cmdToSQL = "#S|SQL|";
bool setChannelToCSV = false; //Channel Arduino output to CSV lets Prophetes create a comma separated file. Used for use in Excel or other applications that can import CSV files.
String cmdToCSV = "#S|CSV|";
bool setChannelToREQ = false; //Channel Arduino output to Prophetes and from there to a HTTP Request. Used for display graphs in ThinSpeak
String cmdToREQ = "#S|REQ|";
bool setChannelToTXT = false; //Channel Arduino output to TXT lets Prophetes create a text separated file. Used in any application that can read text files.
String cmdToTXT = "#S|TEXT|";
bool setChannelToEMAIL = false; //Channel Arduino output to TXT lets Prophetes create a text separated file. Used in any application that can read text files.
String cmdToMAIL = "#S|EMAIL|";
bool setChannelToThingSpeak = true; //Channel Arduino output to ThingSpeak.
String cmdToTSAPI = "[TS_API]";
double ProcessStressLevel = 0;
//EndSetChannels to Prophetes.
//*********************************************************************************************************************************************************************************

//Record reading.
//*********************************************************************************************************************************************************************************
unsigned long Entry_id = 0; //The entry_id value holds the number of written loglines for uploading the log to a ThingSpeak Channel
String Remark = "Remark: ";
int SampleCount = 0; //Counts the number of readings for all sensors during one loop.
int serInLen = 25;
char serInString[25];
int QuickRuns = 3; //Number of quickTest runs before the test exits.
bool prnPlotAll = false; //Set to TRUE when printing to the serial plotter in the Arduino compiler, when calibrating, might be helpful. You can either plot or list the output.
bool setTestAll = false; //When testing and calibrating the pH probe or the Quicktest. This must ALWAYS set to TRUE when testing or calibrating!
bool QuickTest = false; //QuickTest is for individual tests.
//*********************************************************************************************************************************************************************************

//Light.
//*********************************************************************************************************************************************************************************
bool ShowInfoLight = true; //Enable/disable luminance measurement (true or false).
bool prnInfoLight = false; //Enable or disable luminance measurement (true or false).
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
double LightPinUnits = 0.00; //Variable that holds the amount of light in Pin Units.
double PythiaValueLight = 0.00; //Variable to store the light luminescence value going to Pythia.
double LightHihgTolerance = 162.51; //Variable to store the high tolerance as a percentage from LightReference to ThingSpeak.
double LightReference = 150.00; //Variable to store the light reference value going to ThingSpeak.
double LightLowTolerance = 135.18; //Variable to store the low tolerance as a percentage from LightReference to ThingSpeak.
double LightStressImpactLevel = 0.25;
//*********************************************************************************************************************************************************************************

//Temperature.
//*********************************************************************************************************************************************************************************
bool ShowInfoTemperature = true; //Enable/disable pH temperature measurement (true or false).
bool prnInfoTemperature = false; //Enable or disable temperature measurement (true or false).
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire); //Pass our oneWire reference to Dallas Temperature sensor.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Start with the determination of the allowed margin (bandwidth) above and below the optimal pH for this process.
//Set the MarginPercentage to the value that you allow the optimal value to differ within save TemperatureTolerances.
float Celcius1 = 0, Celcius2 = 0, Celcius3 = 0, Fahrenheit1 = 0, Fahrenheit2 = 0, Fahrenheit3 = 0;
double TemperatureMarginPercentage = 0.15; //Set the deviation percentage to establish the margin TemperatureTolerances for the optimal value. (Default: 0.15%)
int TemperaturePinUnits = 0; //Variable that holds the amount of light in Pin Units.
double TemperatureVoltage = 0.00; //Variable to store the light luminescence value going to Pythia.
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//The CalibrationTemperature value must be preferably as close to the optimal temperature as possible. Best is between the tolerances.
const double CalibrationTemperature1 = 0.00; //Sensor 1: Variable only for the calibration. This is the actual temperature at the moment that is used for calibrating this parameter.
const double CalibrationTemperature2 = 0.00; //Sensor 2: Variable only for the calibration. This is the actual temperature at the moment that is used for calibrating this parameter.
const double CalibrationTemperature3 = 0.00; //Sensor 3: Variable only for the calibration. This is the actual temperature at the moment that is used for calibrating this parameter.

//Last Process calibration date (yyyy-mm-dd): 2018-04-05.

//Set this pin values to the actual measured Arduino output pin values. Conductivity and pH measurementsare influenced by temperature. So this value is being taken into account on these parameters, if you use them.
const double TemperatureProcessOptimalValue = 24.00; //Value of the optimal temperature. Used for both conductivity as for pH measurements.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
double PythiaValueTemperature = TemperatureProcessOptimalValue; //Variable to store the temperature value going to Pythia.
double TempHihgTolerance = 24.25; //Variable to store the high tolerance as a percentage from TempReference to ThingSpeak.
double TempReference = 22.5; //Variable to store the light reference value going to ThingSpeak.
double TempLowTolerance = 20.20; //Variable to store the low tolerance as a percentage from TempReference to ThingSpeak.
double TempStressImpactLevel = 5.00;
//*********************************************************************************************************************************************************************************

//pH
//*********************************************************************************************************************************************************************************
bool ShowInfoPH = true; //Enable/disable pH measurement (true or false).
bool prnInfoPH = false; //Enable/disable pH show on screen (true or false).
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Attention: The 'setTestAll' has to be 'true', otherwise no Process is executed.
//Step 1: The "zero" Process.
bool setTestShortCutPH = false; //When testing on the shortcut probe BNC plug for pH7.00
bool setTestAcidic = false; //When testing on an acidic calibration solution.
bool setTestNeutral = false; //When testing on the Neutral buffer solution.
bool setTestAlkaline = false; //When testing on an alkaline calibration solution.

//The pH sensor is now set and ready to calibrate against the buffer solutions.
//Start with the determination of the allowed margin (bandwidth) above and below the optimal pH for this process.
//Set the MarginPercentage to the value that you allow the optimal value to differ within save tolerances.
//Prepare the pH Process solutions in three containers and assign the pH values to the variables.
//This value will be added or subtracted from the optimal value in order to get the optimal range.
const int PinCalibrationShortCutUnits = 511; //Arduino pin units in the shortcut probe BNC plug.
const float pHCalibrationShortCutPH = 7.00; //Value of the pH in the shortcut probe BNC plug.

const int PinProcessUnitsTopHigh = 10; //Arduino pin units in the acidic buffer solution.
const double pHProcessValueTopHigh = 4.00; //Value of the pH in the acidic buffer solution.
const int pHProcessOptimalUnits = 580; //Arduino pin units in the neutral buffer solution.
const double pHProcessOptimalValue = 7.86; //Value of the pH in the neutral buffer solution.
const int pHProcessUnitsDownLow = 800; //Arduino pin units in the alkaline buffer solution.
const double pHProcessValueDownLow = 9.18; //Value of the pH in the alkaline buffer solution.

//After the completed calibration: Rinse the pH probe in clear de-mineralized water and set the "setTestPinValue" to 'false'; now place the pH probe in the aquarium.
//Now make the measurements and observe the result!
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int PHPinUnits = 0; //This variable holds the actual measurement from Arduino on the pH probe.
float pHVoltage = 0.00; //pH sensor voltage.
double pHValue = 0.00; //pH sensor value.
double PythiaValuePH = 0.00; //The end result goes in here and will be exported to the log file.
double PHHihgTolerance = 8.25; //Variable to store the high tolerance as a percentage from TempReference to ThingSpeak.
double PHReference = 6.62; //Variable to store the light reference value going to ThingSpeak.
double PHLowTolerance = 6.22; //Variable to store the low tolerance as a percentage from TempReference to ThingSpeak.
double PHStressImpactLevel = 4.00;
//*********************************************************************************************************************************************************************************

//ORP.
//*********************************************************************************************************************************************************************************
bool ShowInfoORP = true; //Enable/disable ORP measurement (true or false).
bool prnInfoORP = false; //Enable or disable ORP measurement (true or false).
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int ORPPinUnits = 0; //Variable that holds the amount of ORP in Pin Units.
double ORPVoltage = 0.00; //Variable to store the ORP voltage.
double ORPValue = 0.00; //Variable to store the ORP value going to Pythia.
double PythiaORPVoltage = 0.00; //Variable to store the ORP value going to Pythia.
double ORPHihgTolerance = 400; //Variable to store the high tolerance as a percentage from TempReference to ThingSpeak.
double ORPReference = 350; //Variable to store the light reference value going to ThingSpeak.
double ORPLowTolerance = 300; //Variable to store the low tolerance as a percentage from TempReference to ThingSpeak.
double ORPStressImpactLevel = 0.50;

double rHValue = 0.00; //rH can only be calculated when ALL parameters (exept light) are measured!
double RHHihgTolerance = 36; //Variable to store the high tolerance as a percentage from TempReference to ThingSpeak.
double RHReference = 26; //Variable to store the light reference value going to ThingSpeak.
double RHLowTolerance = 16; //Variable to store the low tolerance as a percentage from TempReference to ThingSpeak.
double RHStressImpactLevel = 1.50;
//*********************************************************************************************************************************************************************************

void setup(void)
{
Serial.begin(9600);
sensors.begin(); //Start up the OneWire library.
if ((prnPlotAll == false) && (QuickTest == false))
{
tmeMinute.every(totalDelayValue - correctedDelay, LogAll); //Set logging timer on 1 minute.
if(setChannelToGoBetwino == true)
{
Header_VDW();
Header_Init();
}
}
else
{
Delay = 5000;
if (setTestAll == false)
{
Header_VDW_Quick();
}//if
}//if

}//setup
//*********************************************************************************************************************************************************************************

void loop(void)
{
startSampleTime = millis();
SampleCount++;

//----------------------------- Start Light Measurement AnalogRead ------------------------------------
if (ShowInfoLight == true)
{
LightPinUnits = 0;
while (LightPinUnits < analogRead(analogPinLightA0))
{
LightPinUnits = analogRead(analogPinLightA0);
if (setTestAll == true)
{
Serial.print("#S|GOBETWINO|[ =*= LightPinUnits: ");
Serial.print(LightPinUnits);
Serial.println(" units]#");
}//if
delay(Delay);
}//while
if (prnInfoLight == true)
{
Serial.print("#S|GOBETWINO|[ =*= LightPinUnits: ");
Serial.print(LightPinUnits);
Serial.println(" units]#");
Serial.println(SingleLine);
}//if
PythiaValueLight = PythiaValueLight + LightPinUnits;
}//if
//----------------------------- End Light Measurement AnalogRead --------------------------------------

//----------------------------- Start OneWire DS18B20 Temperature Measurement ------------------------------
if (ShowInfoTemperature == true)
{
//Because the DS18B20 temperature sensor is digital, there is no need to test every loop. Once in a sensing run is sufficient.
//Call sensors.requestTemperatures() to issue a global temperature request to all devices on the bus.
sensors.requestTemperatures(); //Send the command to get temperatures.
if (sensors.getTempCByIndex(0) > -127)
{
Celcius1 = sensors.getTempCByIndex(0) + CalibrationTemperature1;
Fahrenheit1 = sensors.toFahrenheit(Celcius1);
if ((prnInfoTemperature == true))
{
Serial.print("#S|GOBETWINO|[ =*= " Device1 " in Celsius: ");
Serial.print(Celcius1);
Serial.print(" °C; Fahrenheit: ");
Serial.print(Fahrenheit1);
Serial.println(" °F]#");
Serial.println(SingleLine);
}//if
if (sensors.getTempCByIndex(1) > -127)
{
Celcius2 = sensors.getTempCByIndex(1) + CalibrationTemperature2;
Fahrenheit2 = sensors.toFahrenheit(Celcius2);
if (prnInfoTemperature == true)
{
Serial.print("#S|GOBETWINO|[ =*= " Device2 " in Celsius: ");
Serial.print(Celcius2);
Serial.print(" °C; Fahrenheit: ");
Serial.print(Fahrenheit2);
Serial.println(" °F]#");
Serial.println(SingleLine);
}//if
}//if
if (sensors.getTempCByIndex(2) > -127)
{
Celcius3 = sensors.getTempCByIndex(2) + CalibrationTemperature3;
Fahrenheit3 = sensors.toFahrenheit(Celcius3);
if (prnInfoTemperature == true)
{
Serial.print("#S|GOBETWINO|[ =*= " Device3 " in Celsius: ");
Serial.print(Celcius3);
Serial.print(" °C; Fahrenheit: ");
Serial.print(Fahrenheit3);
Serial.println(" °F]#");
Serial.println(SingleLine);
}//if
}//if
} else
{
Serial.println("#S|GOBETWINO|[ =*= requestTemperature; Sensor ERROR!]#");
}//if else
PythiaValueTemperature = Celcius1;
}//if
//----------------------------- End OneWire DS18B20 Temperature Measurement ------------------------------

//----------------------------- Start pH Measurement -----------------------------------------
if (ShowInfoPH == true)
{
PHPinUnits = 0;
while (PHPinUnits < analogRead(analogPHpinA1))
{
PHPinUnits = analogRead(analogPHpinA1);
if (setTestAll == true)
{
Serial.print("#S|GOBETWINO|[ =*= PHPinUnits: ");
Serial.print(PHPinUnits);
Serial.println(" units]#");
}//if
delay(Delay);
}//while
pHVoltage = (PHPinUnits + 0.5) * (int5Volt / 1024.0);
pHValue = Calculate_pH5Volt(pHVoltage, PythiaValueTemperature);
if (prnInfoPH == true)
{
Serial.print("#S|GOBETWINO|[ =*= PHPinUnits: ");
Serial.print(PHPinUnits);
Serial.print(" units; pHVoltage: ");
Serial.print(pHVoltage);
Serial.print(" Volt; ProbeValuePH: ");
Serial.print(pHValue);
if ((setTestShortCutPH == true))
{
if (PHPinUnits < PinCalibrationShortCutUnits - 1)
{
Serial.print("; units to LOW; turn probe setting UP.");
} else if (PHPinUnits > PinCalibrationShortCutUnits + 1)
{
Serial.print("; units to HIGH; turn probe setting DOWN.");
} else
{
Serial.print("; units OK! pH set to " + String(pHCalibrationShortCutPH));
Serial.print("; pH to Unit ratio: ");
Serial.print(pHCalibrationShortCutPH /PHPinUnits);
Serial.print(" pH/Unit.");
}//if else
} else if (setTestAcidic == true)
{
Serial.print(" pH; Test on Acidic ");
Serial.print(PinProcessUnitsTopHigh);
} else if (setTestNeutral == true)
{
Serial.print("; Test on Neutral pH; ratio: ");
Serial.print(pHProcessOptimalValue / pHProcessOptimalUnits);
Serial.println(" pH/Unit]#");
Serial.print("#S|GOBETWINO|[ =*= pHProcessOptimalValue: ");
Serial.print(pHProcessOptimalValue);
} else if (setTestAlkaline == true)
{
Serial.print(" pH; Test on Alkaline ");
Serial.print(pHProcessValueDownLow);
}//if else
Remark = "at " + String(PythiaValueTemperature, 2) + " °C: ";
if (pHValue < 6.99)
{
Remark = Remark + "Acidic";
} else if (pHValue > 7.01)
{
Remark = Remark + "Alkaline";
} else
{
Remark = Remark + "Optimal/Neutral within tolerance of ± 0.01 pH";
}//if else
Serial.println(" pH; " + Remark + ".]#");
Serial.println(SingleLine);
}//if
PythiaValuePH = PythiaValuePH + pHValue;
}//if
//----------------------------- End pH Measurement -----------------------------------------

//----------------------------- Start ORP Measurement -----------------------------------------
if (ShowInfoORP == true)
{
ORPPinUnits = 0;
while (ORPPinUnits < analogRead(analogORPpinA2))
{
ORPPinUnits = analogRead(analogORPpinA2);
if (setTestAll == true)
{
Serial.print("#S|GOBETWINO|[ =*= ORPPinUnits: ");
Serial.print(ORPPinUnits);
Serial.println(" units]#");
}//if
delay(Delay);
}//while
ORPVoltage = (ORPPinUnits + 0.5) * (int5Volt / 1024.0);
ORPValue = ((2.5 - ORPVoltage) / 1.037) * 1000;
if (prnInfoORP == true)
{
Serial.print("#S|GOBETWINO|[ =*= ORPPinUnits: ");
Serial.print(ORPPinUnits);
Serial.print(" units; ORPVoltage: ");
Serial.print(ORPVoltage);
Serial.print(" Volt; ORP: ");
Serial.print(ORPValue);
Serial.println(" milliVolt]#");
Serial.println(SingleLine);
}//if
PythiaORPVoltage = PythiaORPVoltage + ORPValue;
}//if
//----------------------------- End ORP Measurement -----------------------------------------
if ((ShowInfoPH == true) && (ShowInfoORP == true))
{
rHValue = (Calculate_rH(ORPValue, pHValue));
}//if
if ((prnPlotAll == false) && (QuickTest == false))
{
tmeMinute.update();
}
else if (prnPlotAll == true)
{
if (ShowInfoLight == true)
{
Serial.print(LightPinUnits / 100);
Serial.print(",");
}//if
if (ShowInfoTemperature == true)
{
//Serial.print(Celcius1 / 10);
//Serial.print(",");
}//if
if (ShowInfoPH == true)
{
Serial.print(pHValue);
Serial.print(",");
}//if
if (ShowInfoORP == true)
{
Serial.print(ORPValue / 100);
Serial.print(",");
}//if
if ((ShowInfoPH == true) && (ShowInfoORP == true))
{
Serial.print(rHValue / 10);
Serial.print(",");
}//if
Serial.println();
}//if else
if ((QuickTest == true) && (setTestAll == false) && (SampleCount <= QuickRuns))
{
Serial.print("#S|GOBETWINO|[ =*------------- Sample: ");
Serial.print(SampleCount);
if (SampleCount == 1)
{
Serial.println(" -----------------------------------------------*=]#");
}
else
{
Serial.println(" -----------*=]#");
}//if else
rHValue = (Calculate_rH(ORPValue, pHValue));
Serial.print("#S|GOBETWINO|[ =*=\tTemperature:\t");
Serial.print(Celcius1);
Serial.println(" Celsius\t=*=]#");
Serial.print("#S|GOBETWINO|[ =*=\tORP:\t\t\t");
Serial.print(ORPValue);
Serial.println(" mVolt\t=*=]#");
Serial.print("#S|GOBETWINO|[ =*=\tAcidity:\t\t");
Serial.print(pHValue);
Serial.println(" pH\t\t\t=*=]#");
Serial.print("#S|GOBETWINO|[ =*=\tRedox:\t\t\t");
Serial.print(rHValue);
Serial.println(" rH\t\t=*=]#");
}
else if ((QuickTest == true) && (setTestAll == false) && (SampleCount > QuickRuns))
{
rHValue = (Calculate_rH(PythiaORPVoltage / SampleCount, PythiaValuePH / SampleCount));
Serial.println("#S|GOBETWINO|[ =*============ Conclusion ===============================================*=]#");
Serial.print("#S|GOBETWINO|[ =*= The acidity of this sample is ");
Serial.print(PythiaValuePH / SampleCount);
Serial.println(" pH.\t\t\t\t\t\t\t\t=*=]#");
Serial.print("#S|GOBETWINO|[ =*= The potential of this sample is ");
Serial.print(PythiaORPVoltage / SampleCount);
Serial.println(" mVolt.\t\t\t\t\t\t=*=]#");
Serial.print("#S|GOBETWINO|[ =*= The Relative Hydrogen Score is ");
Serial.print(rHValue);
Serial.println(" rH.\t\t\t\t\t\t\t=*=]#");
Serial.print("#S|GOBETWINO|[ =*= Due to the pH and ORP value, the rH of this sample is ");
if (rHValue < 10)
{
Remark = "Advice: Check the pH and replenish at least 60% with fresh water.\t=*=";
Serial.println("much to LOW.\t=*=]#");
}
else if ((rHValue >= 10) && (rHValue < 26))
{
Remark = "Advice: Check the pH and replenish at least 30% with fresh water.\t=*=";
Serial.println("to LOW.\t\t=*=]#");
}
else if ((rHValue >= 26) && (rHValue < 30))
{
Remark = "Well done!\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t=*=";
Serial.println("FINE.\t\t\t=*=]#");
}
else if ((rHValue >= 30) && (rHValue < 40))
{
Remark = "Advice: Check the pH and replenish at least 30% with fresh water.\t=*=";
Serial.println("to HIGH.\t\t=*=]#");
}
else if (rHValue >= 40)
{
Remark = "Advice: Check the pH and replenish at least 60% with fresh water.\t=*=";
Serial.println("much to HIGH.\t=*=]#");
}//if else
Serial.println("#S|GOBETWINO|[ =*= " + Remark + "]#");
Serial.println("#S|GOBETWINO|[ =*============ End of Test ==============================================*=]#");
delay(500);
exit(0);
}//if else
if ((showTiming == true) && (prnPlotAll == false) && (QuickTest == false))
{
Serial.print("#S|GOBETWINO|[ =*= sampleTime: ");
Serial.print(millis() - startSampleTime);
Serial.println(" mSec]#");
}//if
}//loop
//*********************************************************************************************************************************************************************************

void LogAll(void)
{
//----------------------------- Get the value as measurement recording -------------
PythiaValueLight = PythiaValueLight / SampleCount;
PythiaValuePH = PythiaValuePH / SampleCount;
PythiaORPVoltage = PythiaORPVoltage / SampleCount;

if (setChannelToCOM == true)
{
//This part creates the data for Pythia and send thru the COM port.
Entry_id += 1;
logAsText(PythiaValueLight, PythiaValueTemperature, PythiaValuePH, PythiaORPVoltage, rHValue);
}//if
if (setChannelToCSV == true)
{
logAsCSV(PythiaValueLight, PythiaValueTemperature, PythiaValuePH, PythiaORPVoltage, rHValue);
}//if
if (setChannelToTXT == true)
{
//This part creates the data for Pythia and send thru the COM port.
Entry_id += 1;
logAsText(PythiaValueLight, PythiaValueTemperature, PythiaValuePH, PythiaORPVoltage, rHValue);
}//if
if (setChannelToThingSpeak == true)
{
//The logDataThingSpeak routine logs the Arduino to ThingSpeak as a HTTP Request.
//Arduino determines whether or not a specific condition is met and sets the trigger accordinly.

if (((PythiaValueLight < LightLowTolerance) || (PythiaValueLight > LightHihgTolerance)))
{
ProcessStressLevel += LightStressImpactLevel;
}//if
if (((PythiaValueTemperature < TempLowTolerance) || (PythiaValueTemperature > TempHihgTolerance)))
{
ProcessStressLevel += TempStressImpactLevel;
}//if
if (((PythiaValuePH < PHLowTolerance) || (PythiaValuePH > PHHihgTolerance)))
{
ProcessStressLevel += PHStressImpactLevel;
}//if
if (((PythiaORPVoltage < ORPLowTolerance) || (PythiaORPVoltage > ORPHihgTolerance)))
{
ProcessStressLevel += ORPStressImpactLevel;
}//if
if (((rHValue < RHLowTolerance) || (rHValue > RHHihgTolerance)))
{
ProcessStressLevel += RHStressImpactLevel;
}//if
logDataThingSpeak(PythiaValueLight, PythiaValueTemperature, PythiaValuePH, PythiaORPVoltage, rHValue, ProcessStressLevel);
}//if
if (setChannelToEMAIL == true)
{
//The logAsEmail routine logs the Arduino data thru an E-mail application.
logAsEmail(PythiaValueLight, PythiaValueTemperature, PythiaValuePH, PythiaORPVoltage, rHValue);
}//if
if (setChannelToSQL == true)
{
//The logDataPythia routine logs the Arduino data thru Gobetwino.
logDataSQL(PythiaValueLight, PythiaValueTemperature, PythiaValuePH, PythiaORPVoltage, rHValue);
}//if
if (setChannelToGoBetwino == true)
{
//The logDataGobetwino routine logs the Arduino data thru Gobetwino.
logDataGobetwino(PythiaValueLight, PythiaValueTemperature, PythiaValuePH, PythiaORPVoltage, rHValue);
}//if
//Initialize all variables for the next loop.
Serial.flush();
Remark = "Remark: ";
SampleCount = 0;
PythiaValueLight = 0.00;
PythiaValueTemperature = TemperatureProcessOptimalValue;
PythiaORPVoltage = 0.00;
PythiaValuePH = 0.00;
ProcessStressLevel =0;
}//void LogAll
//*********************************************************************************************************************************************************************************

//Data logging

void logAsCSV(double Light, double Temperature, double PH, double ORP, double RH)
{
Serial.print(cmdToCSV); //Initialize CSV request command. String WaterPH, String LoopTimeWaterPH
Serial.print(String(Light, 2)); //#01 (Field1)
Serial.print(",");
Serial.print(String(Temperature, 2)); //#02 (Field2)
Serial.print(",");
Serial.print(String(PH, 2)); //#03 (Field3)
Serial.print(",");
Serial.print(String(ORP, 2)); //#04 (Field4)
Serial.print(",");
Serial.print(String(RH, 2)); //#05 (Field5)
Serial.println();
readSerialString(serInString, 1000); //Convert the values to strings.
}//void logAsCSV.
//*********************************************************************************************************************************************************************************

void logDataThingSpeak(double Light, double Temperature, double PH, double ORP, double RH, double PCL)
{
Serial.print(cmdToTSAPI); //Initialize HTTP request command. String WaterPH, String LoopTimeWaterPH
Serial.print("&field1=");
Serial.print(String(Light, 2)); //#01 (Field1)
Serial.print("&field2=");
Serial.print(String(Temperature, 2)); //#02 (Field2)
Serial.print("&field3=");
Serial.print(String(PH, 2)); //#03 (Field3)
Serial.print("&field4=");
Serial.print(String(ORP, 2)); //#04 (Field4)
Serial.print("&field5=");
Serial.print(String(RH, 2)); //#05 (Field5)
Serial.print("&field6=");
Serial.print(String(PCL, 2)); //#06 (Field6)
Serial.println();
readSerialString(serInString, 1000); //Convert the values to strings.
}//void logDataWeb.
//*********************************************************************************************************************************************************************************

void logAsText(double Light, double Temperature, double PH, double ORP, double RH)
{
Serial.print(cmdToTXT); //Initialize TEXT command. String WaterPH, String LoopTimeWaterPH
Serial.print(String(Light, 2)); //#01 (Field1)
Serial.print(";");
Serial.print(String(Temperature, 2)); //#02 (Field2)
Serial.print(";");
Serial.print(String(PH, 2)); //#03 (Field3)
Serial.print(";");
Serial.print(String(ORP, 2)); //#04 (Field4)
Serial.print(";");
Serial.print(String(RH, 2)); //#05 (Field5)
Serial.println();
readSerialString(serInString, 1000); //Convert the values to strings.
}//void logAsText.
//*********************************************************************************************************************************************************************************

void logAsEmail(double Light, double Temperature, double PH, double ORP, double RH)
{
Serial.print(cmdToMAIL); //Initialize EMAIL command. String WaterPH, String LoopTimeWaterPH
Serial.print(",");
Serial.print(String(Light, 2)); //#01 (Field2)
Serial.print(",");
Serial.print(String(Temperature, 2)); //#02 (Field3)
Serial.print(",");
Serial.print(String(PH, 2)); //#03 (Field4)
Serial.print(",");
Serial.print(String(ORP, 2)); //#04 (Field5)
Serial.print(",");
Serial.print(String(RH, 2)); //#05 (Field1)
Serial.println();
readSerialString(serInString, 1000); //Convert the values to strings.
}//void logAsEmail.
//*********************************************************************************************************************************************************************************

void logDataSQL(double Light, double Temperature, double PH, double ORP, double RH)
{
Serial.print(cmdToSQL); //Initialize SQL command. String WaterPH, String LoopTimeWaterPH
Serial.print(String(Light, 2)); //#01 (Field1)
Serial.print(",");
Serial.print(String(Temperature, 2)); //#02 (Field2)
Serial.print(",");
Serial.print(String(PH, 2)); //#03 (Field3)
Serial.print(",");
Serial.print(String(ORP, 2)); //#04 (Field4)
Serial.print(",");
Serial.print(String(RH, 2)); //#05 (Field5)
Serial.println();
readSerialString(serInString, 1000); //Convert the values to strings.
}//void logAsEmail.
//*********************************************************************************************************************************************************************************

void logDataGobetwino(double Light, double Temperature, double PH, double ORP, double RH)
{
Serial.print(cmdToGoBetwino); //Initialize Gobetwino command. String WaterPH, String LoopTimeWaterPH
//Field #01 is date-time field.
Serial.print(String(Light, 2)); //#02
Serial.print(";");
Serial.print(String(Temperature, 2)); //#03
Serial.print(";");
Serial.print(String(PH, 2)); //#04
Serial.print(";");
Serial.print(String(ORP, 2)); //#05
Serial.print(";");
Serial.print(String(RH, 2)); //#06
Serial.println(";]#"); //Finalize Gobetwino command.
readSerialString(serInString, 1000); //Convert the values to strings.
}//void logDataGobetwino.
//*********************************************************************************************************************************************************************************

//Read a string from the serial and store it in an array.
//You must supply the array variable - return if timeOut ms passes before the sting is read.
void readSerialString (char * strArray, long timeOut)
{
long startTime = millis();
int i = 0;
while (!Serial.available()){
if ((unsigned)millis() - (unsigned)startTime >= (unsigned)timeOut) {
return;
}//if
}//while
while (Serial.available() && i < serInLen){
strArray[i] = Serial.read();
i++;
}//while
}//void readSerialString.
//*********************************************************************************************************************************************************************************

//Header_VDW
//*********************************************************************************************************************************************************************************
void Header_VDW(void)
{
Serial.println(DoubleLine);
Serial.println(LineVDW);
}//void Header_VDW

//Header_Init
//*********************************************************************************************************************************************************************************
void Header_Init(void)
{
Serial.println(DoubleLine);
Serial.println(LineInit);
Serial.println(LineLegend);
Serial.println(SingleLine);
}//void Header_Init
//*********************************************************************************************************************************************************************************

//Header_VDW
//*********************************************************************************************************************************************************************************
void Header_VDW_Quick(void)
{
//Serial.println(DoubleLineQ);
//Serial.println(LineVDWQ);
Serial.println(LineMailQ);
}//void Header_VDW_Quick
//*********************************************************************************************************************************************************************************
//End sketch

You can download your copy FREE!
Get your sketch for free HERE