Auto Fertigation System

so forgive my etiquette, but im struggling to grasp what it is im doing wrong here, ive built a system off the arduino mega, to control all aspects of nutrient dosing and irrigation for an indoor garden. i.e., dosing the nutrients to a mixing reservoir, correcting PH swings, & pumping it to plant pots. multiple rooms are separated by solenoid valves. id very much like to configure a sketch that allows me to save regimens per room but i do not have the resources to take on such a task at the moment. the schematic is below, as well as the sketch ive tweaked from open source. if anyone here can lend a hand as to what i can do to get it compile, it would be greatly appreciated.

heres the sketch setup....

#include <Wire.h>    //Include the software serial library for white shield
#include <Adafruit_NeoPixel.h>
#include <LiquidCrystal.h> //lib for interfacing with LCD screen
#include <SPI.h> //Suppoting lib for SD card
#include <SD.h> //SD card API
#include <EEPROM.h>

#include <Arduino_JSON.h> //Arduno Json (aka epic)
#include <DS3231.h> //Real time clock lib
#include "Globals.h" //All temp and PROGMEM global variables
#include "Core.h" //All core functions and variables
#include "Crops.h" //All crop functions and variables
#include "Pumps.h" //All pump functions and variables
#include "Regimens.h" //All session functions and variables
#include "Screens.h" //All screen functions and variables
#include "Menus.h" //All menu functions and variables
#include "DatesTime.h" //All date & time functions and variables
#include "Irrigation.h" //All irrigation related functions and variables
#include "Timers.h" //All timer related functions and variables

//OS main setup
void setup()
{
LiquidCrystal.createChar(0, upArrow);
LiquidCrystal.createChar(1, downArrow);
LiquidCrystal.begin(16, 2);
Adafruit_NeoPixel.begin(); // This initializes the NeoPixel library.
Adafruit_NeoPixel.setBrightness(128);
Adafruit_NeoPixel.show();

//If SD Card is not found, we can't proceed
if (!SD.begin(53)){
LiquidCrystal.print(F("SD Card Required"));
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("Insert And Reset"));
screenName = F("REQUIREDSD");
} else {//if SD card is found, proceed with crop load or setup
captureDateTime(); //Capture current time from real time clock
phRsvrMillis = phPlantMillis = ecMillis = millis(); //set first time use of timestamps

//Setup Flow Sensor Pins
pinMode(FlowPinIn, INPUT); //irrigation "in" flow meter
digitalWrite(FlowPinIn, HIGH);

pinMode(FlowPinOut, INPUT); //irrigation "out" flow meter
digitalWrite(FlowPinOut, HIGH);

   pinMode(FlowPinOut, INPUT); //irrigation "tent" flow meter
   digitalWrite(FlowPinOut, HIGH);

//irrigation flow meters being hooked into flow counter methods
attachInterrupt(digitalPinToInterrupt(FlowPinIn), countRsvrFill, RISING);
attachInterrupt(digitalPinToInterrupt(FlowPinOut), countRsvrDrain, RISING);
attachInterrupt(digitalPinToInterrupt(FlowPinTent), countRsvrDrain, RISING);

//Setup Relay Pins
pinMode(22, OUTPUT); //perstaltic pump 1
digitalWrite(22, HIGH);
pinMode(23, OUTPUT); //perstaltic pump 2
digitalWrite(23, HIGH);
pinMode(24, OUTPUT); //perstaltic pump 3
digitalWrite(24, HIGH);
pinMode(25, OUTPUT); //perstaltic pump 4
digitalWrite(25, HIGH);
pinMode(26, OUTPUT); //perstaltic pump 5
digitalWrite(26, HIGH);
pinMode(27, OUTPUT); //perstaltic pump 6
digitalWrite(27, HIGH);
pinMode(28, OUTPUT); //perstaltic pump 7
digitalWrite(28, HIGH);
pinMode(29, OUTPUT); //perstaltic pump 8
digitalWrite(29, HIGH);
pinMode(30, OUTPUT); //perstaltic pump 9
digitalWrite(30, HIGH);
pinMode(31, OUTPUT); //perstaltic pump 10
digitalWrite(31, HIGH);

pinMode(32, OUTPUT); //irrigation "D" valve
digitalWrite(32, HIGH);
pinMode(33, OUTPUT); //irrigation "C" valve
digitalWrite(33, HIGH);
   pinMode(34, OUTPUT); //irrigation "B" valve
   digitalWrite(34, HIGH);
   pinMode(35, OUTPUT); //irrigation "A" valve
   digitalWrite(35, HIGH);

pinMode(36, OUTPUT); //High voltage power receptical 1
digitalWrite(36, HIGH);
pinMode(37, OUTPUT); //High voltage power receptical 2
digitalWrite(37, HIGH);


//Serial.begin(9600);
Wire.begin();   // enable i2c ports.
coreInit(); //Loads or Creates Crops
}
}

(deleted)

id very much like to configure a sketch that allows me to save regimens per room but i do not have the resources to take on such a task at the moment.

you've posted some code that configures a bunch of pins.

what you describe as configure a sketch is probably weeks of effort

i have the rest of the code, this site only allows me to post every 5 minutes and i had other chores to tend.

heres some more code.

limit of 9000 characters per post tho so i have to disect it down in sections.

//Our runtime loop function
void loop()
{
Key = analogRead(0);

//Reset home screen and menu timers to current miliseconds after any interaction with LCD keys
if (Key >= 0 && Key <= 650){
homeMillis = menuMillis = millis();
}
//If no menu interactions have happened after 10 seconds
if ((millis() - menuMillis) >= 10000){

//OS monitors flowRates of both irrigation directions
if ((millis() - flowMillis) >= 1000){
checkFlowRates();
if (screenName == "RSVRVOL"){
printReservoirVolume();
}
}

//Home print, PH corrections
if ((millis() - homeMillis) >= 1000){
if (screenName == "") {
if (cropStatus == 1){
correctPlantPH(); //check if plant PH correction is needed
correctRsvrPH(); //check if reservoir PH correction is needed
checkRegimenDosing(); //check if we are ready for a regimen dosing (full or topoff)
}

if ((millis() - homeMillis) >= 2000) {
printHomeScreen();   //home print
homeMillis = millis(); //home millis reset 
}
}
}
}



//UI Menus
if (Key == 0 || Key == 408){
//Left & Right
if (screenName == "DATETIME"){
matrix = {
{ { 1, 1 }, { 4, 4 }, { 10, 10 }, { 13, 13 } },
{ { 3, 3 }, { 6, 6 }, { 13, 13 } }
};
}
if (screenName == "NEW"){
matrix = {
{ { 0, 7 } },
{ { 11, 11 } }
};
if (Key == 0){
cropRename(NULL);
LiquidCrystal.blink();
}
}
if (screenName == "OPEN"){
matrix = {
{ { 0, 0 } },
{ { 1, 1 }, { 9, 9 } }
};
}
if (screenName == "RESET"){
matrix = {
{ {0, 0} },
{ { 1, 1 }, { 11, 11 } }
};
}
if (screenName == "DELETE") {}
if (screenName == "STATUS") {
matrix = {
{ { 8, 8 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "PHRANGE"){
matrix = {
{ { 3, 3 }, {9, 9} },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "PHDLY"){
matrix = {
{ { 15, 15 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "PHAMNT") {
matrix = {
{ { 15, 15 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "RSVRVOL"){
matrix = {
{ { 0, 0 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "REGIMENS"){
matrix = {
{ { 1, 1 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "PUMPCAL"){
matrix = {
{ { 2, 2 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "PUMPDLY"){
matrix = {
{ { 2, 2 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "AMOUNT"){
matrix = {
{ { 12, 12 } },
{ { 1, 1 }, { 11, 11 } }
};
}
if (screenName == "TPFCCNT"){
matrix = {
{ { 0, 0 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "TPFAMNT"){
matrix = {
{ { 15, 15 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "TPFDLY"){
matrix = {
{ { 2, 2 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "DRNTIME"){
matrix = {
{ { 1, 1 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "PRIME"){
matrix = {
{ { 0, 0 } },
{ { 11, 11 } }
};
}
if (screenName == "STARTEND"){
matrix = {
{ { 0, 0 }, { 3, 3 }, { 5, 5 }, { 8, 8 }, { 13, 13 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "RECEP01" || screenName == "RECEP02"){
matrix = {
{ { 1, 1 }, { 6, 6 }, { 11, 11 }, { 14, 14 }, },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "FLOWCAL"){
matrix = {
{ { 5, 5 }, { 13, 13 } },
{ { 1, 1 }, { 13, 13 } }
};
}
if (screenName == "PHCAL" || screenName == "PHCALLOW" || screenName == "PHCALHI"){
matrix = {
{ { 0, 0 } },
{ { 1, 1 }, { 11, 11 } }
};
}
if (screenName == "MANFLUSH"){
matrix = {
{ { 0, 0 } },
{ { 1, 1 }, { 5, 5 }, {11, 11} }
};
}

more code...

cursorX = (Key == 0) ? cursorX + 1 : cursorX - 1;
if (Key == 408 && screenName == ""){
menusHistory.pop_back();
menuIndex = 0;
tmpFile = SD.open("dromatic/" + cropName + "/" + getMenuHistory());
getDirectoryMenus(tmpFile);
tmpFile.close();
LiquidCrystal.clear();
printScreenNames(menus.front());
printScrollArrows();
}
if (Key == 0 || Key == 408 && screenName != ""){
screenMatrix();
}
delay(250);
}
if (Key == 99 || Key == 255) {
//Up & Down
int dir = (Key == 99) ? 1 : -1;
if (screenName == "DATETIME"){
if (cursorY == 0){
printDateTime(dir);
} else if (cursorX == 1){
printDateTime(dir);
}
}
if (screenName == "NEW"){
cropRename(dir);
}
if (screenName == "OPEN"){
if (cursorX == 0 && cursorY == 0){
printOpen(dir);
}
}
if (screenName == "DELETE") {}
if (screenName == "STATUS") {
if (cursorX == 8 && cursorY == 0){
printStatus(dir);
}
}
if (screenName == "REGIMENS"){
if (cursorX == 1 && cursorY == 0){
printRegimenNumber(dir);
}
}
if (screenName == "PUMPCAL"){
if (cursorX == 2 && cursorY == 0){
printPumpCalibration(dir);
}
}
if (screenName == "PUMPDLY"){
if (cursorX == 2 && cursorY == 0){
printPumpDelay(dir);
}
}
if (screenName == "AMOUNT"){
if (cursorX == 12 && cursorY == 0){
printRegimenAmount(dir);
}
}
if (screenName == "TPFCCNT") {
if (cursorX == 0 && cursorY == 0){
printTopOffConcentrate(dir);
}
}
if (screenName == "TPFAMNT"){
if (cursorX == 15 && cursorY == 0){
printTopOffAmount(dir);
}
}
if (screenName == "TPFDLY"){
if (cursorX == 2 && cursorY == 0){
printTopOffDelay(dir);
}
}
if (screenName == "DRNTIME") {
if (cursorX == 1 && cursorY == 0){
printDrainTime(dir);
}
}
if (screenName == "PRIME") {
if (cursorX == 0 && cursorY == 0){
primePump(dir);
}
}
if (screenName == "STARTEND") {
if (cursorX == 0 || cursorX == 3 || cursorX == 5 || cursorX == 8 || cursorX == 13 && cursorY == 0){
printTimerStartEnd(dir);
}
}
if (screenName == "RECEP01" || screenName == "RECEP02") {
if (cursorX == 1 || cursorX == 6 || cursorX == 11 || cursorX == 14 && cursorY == 0){
printTimerStartEnd(dir);
}

}
if (screenName == "FLOWCAL") {
if (cursorX == 5 || cursorX == 13 && cursorY == 0){
printFlowCalibration(dir);
}
}
if (screenName == "PHRANGE"){
if (cursorX == 3 || cursorX == 9 && cursorY == 0){
printPHRange(dir);
}
}
if (screenName == "PHDLY") {
if (cursorX == 15 && cursorY == 0){
printPHDelay(dir);
}
}
if (screenName == "PHAMNT") {
if (cursorX == 15 && cursorY == 0){
printPHAmount(dir);
}
}
if (screenName == ""){
scrollMenus(dir);
}
delay(250);
}
if (Key == 639) {
//Select
if (screenName == ""){
LiquidCrystal.clear();
tmpFile = SD.open("dromatic/" + cropName + "/" + getMenuHistory() + "/" + menus[menuIndex]);
menusHistory.push_back(menus[menuIndex]);
getDirectoryMenus(tmpFile);
tmpFile.close();
if (menus.size() > 0){
menuIndex = 0;
tmpFile.close();
printScreenNames(menus.front());
printScrollArrows();
}
else {
screenName = menusHistory.back();
LiquidCrystal.blink();
LiquidCrystal.home();
if (screenName == "DATETIME"){
captureDateTime();
printDateTime();
cursorX = 1;
cursorY = 0;
}
if (screenName == "NEW"){
menus.clear();
menusHistory.clear();
currentAlphaIndex = 0;
currentPumpIndex = 1;
currentRegimenIndex = 1;
menuIndex = 0;
cursorX = cursorY = 0;
cropCreate();
}
if (screenName == "OPEN"){
printOpen();
}
if (screenName == "RESET"){
printReset();
}

if (screenName == "STATUS") {
printStatus();
}
if (screenName == "RSVRVOL"){
menuMillis = 9000; //bypasses the 10second menuMillis wait period
tmpFloats[0] = 0;
}
if (screenName == "REGIMENS"){
cursorX = 1;
cursorY = 0;
StaticJsonBuffer<cropBufferSize> buffer;
JsonObject& data = getCropData(buffer);
tmpInts[0] = data["maxReg"];
String totalDisplay;
totalDisplay = (tmpInts[0] < 10) ? "0" + String(tmpInts[0]) : String(tmpInts[0]);
LiquidCrystal.print(totalDisplay + F(" REGIMEN DOSES"));
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("<back>      <ok>"));
LiquidCrystal.setCursor(cursorX, cursorY);
}
if (screenName == "PUMPCAL"){
tmpInts[0] = pumpCalibration;
printPumpCalibration();
}
if (screenName == "PUMPDLY"){
tmpInts[0] = pumpDelay;
printPumpDelay();
}
if (screenName == "AMOUNT"){
printRegimenAmount();
}
if (screenName == "TPFCCNT"){
tmpInts[0] = topOffConcentrate;
printTopOffConcentrate();
}
if (screenName == "TPFAMNT"){
tmpInts[0] = topOffAmount;
printTopOffAmount();
}
if (screenName == "TPFDLY"){
tmpInts[0] = topOffDelay;
printTopOffDelay();
}
if (screenName == "DRNTIME"){
tmpInts[0] = drainTime;
printDrainTime();
}
if (screenName == "FLOWCAL"){
tmpFloats[0] = flowMeterConfig[0];
tmpFloats[1] = flowMeterConfig[1];
printFlowCalibration();
}
if (screenName == "PRIME"){
LiquidCrystal.write(byte(0));
LiquidCrystal.print(F(" TO PRIME CH0"));
LiquidCrystal.print(String(currentPumpIndex));
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("          <done>"));
cursorX = 0;
cursorY = 0;
LiquidCrystal.setCursor(cursorX, cursorY);
}
if (screenName == "STARTEND"){
StaticJsonBuffer<timerBufferSize> buffer;
JsonObject& data = getTimerSessionData(buffer);
JsonArray& start = data["start"].asArray();
JsonArray& end = data["end"].asArray();

tmpInts[0] = start[0];
tmpInts[1] = start[1];
tmpInts[2] = start[2];
tmpInts[3] = end[0];
tmpInts[4] = end[1];
tmpInts[5] = end[2];

String startAMPM = (tmpInts[2] == 0) ? F("AM") : F("PM");
String endAMPM = (tmpInts[2] == 0) ? F("AM") : F("PM");

LiquidCrystal.print(String(tmpInts[0]) + F(":") + String(tmpInts[1]) + startAMPM + F("-") + String(tmpInts[3]) + F(":") + String(tmpInts[4]) + endAMPM);
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("<back>      <ok>"));
cursorX = 3;
cursorY = 0;
LiquidCrystal.setCursor(cursorX, cursorY);
}
if (screenName == "RECEP01" || screenName == "RECEP02"){
String startDisplay, endDisplay;
String AMPM1, AMPM2;
StaticJsonBuffer<timerSessionBufferSize> buffer;
if (currentTimerSessionIndex < 1){ currentTimerSessionIndex = 1; }
JsonObject& data = getTimerSessionData(buffer, currentTimerIndex, currentTimerSessionIndex);

JsonArray& times = data["times"];

tmpInts[0] = times[0][0]; //start hour
tmpInts[1] = times[0][1]; //end hour
}
//start
if (cursorX == 1){
if (tmpInts[0] > 23){
tmpInts[0] = 0;
}
if (tmpInts[0] < 0) {
tmpInts[0] = 23;
}
}

if (tmpInts[0] > 12){
startDisplay = ((tmpInts[0] - 12) < 10) ? "0" + String(tmpInts[0] - 12) : String(tmpInts[0] - 12);
}
else{
if (tmpInts[0] == 0){
startDisplay = String(12);
}
else{
startDisplay = (tmpInts[0] < 10) ? "0" + String(tmpInts[0]) : String(tmpInts[0]);
}
}

//END
if (cursorX == 6){
if (tmpInts[1] > 23){
tmpInts[1] = 0;
}
if (tmpInts[1] < 0) {
tmpInts[1] = 23;
}
}

if (tmpInts[1] > 12){
endDisplay = ((tmpInts[1] - 12) < 10) ? "0" + String(tmpInts[1] - 12) : String(tmpInts[1] - 12);
}
else{
if (tmpInts[1] == 0){
endDisplay = String(12);
}
else{
endDisplay = (tmpInts[1] < 10) ? "0" + String(tmpInts[1]) : String(tmpInts[1]);
}
}

AMPM1 = (tmpInts[0] > 11) ? "PM" : "AM";
AMPM2 = (tmpInts[1] > 11) ? "PM" : "AM";

LiquidCrystal.print(startDisplay);
LiquidCrystal.print(AMPM1);
LiquidCrystal.print(F("-"));
LiquidCrystal.print(endDisplay);
LiquidCrystal.print(AMPM2);
LiquidCrystal.print(F(" Su/01"));
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("<back>      <ok>"));
cursorX = 6;
cursorY = 0;
LiquidCrystal.setCursor(cursorX, cursorY);
}
if (screenName == "PHRANGE"){
printPHRange(0); //0 = first print version
}
if (screenName == "PHAMNT") {
tmpFloats[0] = phAmount;
printPHAmount();
}
if (screenName == "PHDLY") {
tmpInts[0] = phDelay;
printPHDelay();
}
if (screenName == "PHCAL"){
printPHCalibrations("LOW", 4);
}
if (screenName == "MANFLUSH"){
printFullFlushing();
}
}
delay(350);
}

//Saves
if (screenName == "DATETIME"){
saveDateTime();
}
if (screenName == "NEW"){
if (cursorX == 11 && cursorY == 1){
String nameConfirm;
for (int i = 0; i < 15; i++){
nameConfirm = nameConfirm + nameArry[i];
}
if (nameConfirm == ""){
LiquidCrystal.clear();
LiquidCrystal.print(F("Sorry, No Blank"));
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("Crop Names"));
delay(3000);
LiquidCrystal.clear();
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("Crop Name <done>"));
cursorX = cursorY = 0;
LiquidCrystal.home();
}
else if (SD.exists("dromatic/" + nameConfirm)){
LiquidCrystal.clear();
LiquidCrystal.print(F("Sorry, Crop"));
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("Already Exists"));
delay(3000);
LiquidCrystal.clear();
LiquidCrystal.print(nameConfirm);
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("Crop Name <done>"));
cursorX = cursorY = 0;
LiquidCrystal.home();
}
else {
cropBuild();
}
}
}
if (screenName == "OPEN"){
cropChange();
}
if (screenName == "RESET"){
cropReset();
}
//if (screenName == "DELETE") {}

if (screenName == "STATUS") {
saveStatus();
}
if (screenName == "RSVRVOL") {
saveReservoirVolume();
}
if (screenName == "REGIMENS"){
if (cursorX == 13 && cursorY == 1){
LiquidCrystal.clear();
StaticJsonBuffer<cropBufferSize> buffer;
JsonObject& data = getCropData(buffer);

if (data["maxReg"] > tmpInts[0]){ //we are trimming sessions
LiquidCrystal.print(F("TRIM REGIMENS"));
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F(" PLEASE HOLD... "));
trimRegimens(data["maxReg"], tmpInts[0]);
}
else if (data["maxReg"] < tmpInts[0]){ //we are adding sessions
LiquidCrystal.print(F("ADDING REGIMENS"));
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F(" PLEASE HOLD... "));
addRegimens(data["maxReg"], tmpInts[0]);
}
data["maxReg"] = tmpInts[0]; //update pump's session total
maxRegimens = tmpInts[0];
setCropData(data, false);
}
if (cursorX == 1 && cursorY == 1 || cursorX == 13 && cursorY == 1){
tmpInts[0] = 0;
exitScreen();
}
}
if (screenName == "PUMPCAL"){
savePumpCalibration();
}
if (screenName == "PUMPDLY"){
savePumpDelay();
}
if (screenName == "AMOUNT"){
saveRegimenAmount();
}
if (screenName == "TPFCCNT"){
saveTopOffConcentrate();
}
if (screenName == "TPFAMNT"){
saveTopOffAmount();
}
if (screenName == "TPFDLY") {
saveTopOffDelay();
}
if (screenName == "FLOWCAL"){
saveFlowCalibration();
}
if (screenName == "DRNTIME") {
saveDrainTime();
}
if (screenName == "STARTEND"){
saveStartEnd();
}
if (screenName == "RECEP01" || screenName == "RECEP02") {
if (cursorX == 13 && cursorY == 1){
LiquidCrystal.clear();
StaticJsonBuffer<timerSessionBufferSize> saveBuffer;
JsonObject& saveData = getTimerSessionData(saveBuffer, currentTimerIndex, currentTimerSessionIndex);

saveData["times"].asArray()[currentTimerSessionDayIndex].asArray()[0] = tmpInts[0]; //start hour
saveData["times"].asArray()[currentTimerSessionDayIndex].asArray()[1] = tmpInts[1]; //end hour
setTimerSessionData(saveData);
checkTimers();
}
if (cursorX == 1 || cursorX == 13 && cursorY == 1){
tmpInts[0] = tmpInts[1] = tmpInts[2] = tmpInts[3] = 0;
exitScreen();
}
}
if (screenName == "PRIME"){
if (cursorX == 11 && cursorY == 1){
exitScreen();
}
}
if (screenName == "PHRANGE"){
savePHRange();
}
if (screenName == "PHCAL"){
if (cursorX == 1 && cursorY == 1){ //back
exitScreen();
}
if (cursorX == 11 && cursorY == 1){ //forward
setPHWaterProbeCalibration(112, 4.0, 'low'); //ph probe 1
setPHWaterProbeCalibration(114, 4.0, 'low'); //ph probe 2
printPHCalibrations("MID", 7);
screenName = F("PHCALMID");
}
}
if (screenName == "PHCALMID"){
if (cursorX == 1 && cursorY == 1){ //back
printPHCalibrations("LOW", 4);
screenName = F("PHCALLOW");
}
if (cursorX == 11 && cursorY == 1){ //forward
setPHWaterProbeCalibration(112, 7.0, 'mid'); //ph probe 1
printPHCalibrations("HI", 10);
screenName = F("PHCALHI");
}
}
if (screenName == "PHCALHI"){
if (cursorX == 1 && cursorY == 1){ //back
printPHCalibrations("MID", 7);
screenName = F("PHCALMID");
}
if (cursorX == 11 && cursorY == 1){ //forward
setPHWaterProbeCalibration(112, 10.0, 'high'); //ph probe 1
LiquidCrystal.clear();
LiquidCrystal.print(F("PH CALIBRATION"));
LiquidCrystal.setCursor(0, 1);
LiquidCrystal.print(F("NOW FINISHED!"));
delay(5000);
exitScreen();
}
}
if (screenName == "PHAMNT"){
savePHAmount();
}
if (screenName == "PHDLY"){
savePHDelay();
}
if (screenName == "MANFLUSH"){
if (cursorX == 1 && cursorY == 1){
RelayToggle(11, true);
RelayToggle(12, false);
}
if (cursorX == 5 && cursorY == 1){
RelayToggle(11, false);
RelayToggle(12, true);
}
if (cursorX == 11 && cursorY == 1){
RelayToggle(11, false);
RelayToggle(12, false);
exitScreen();
}
}
}
}

(Please use CTRL-T in the IDE to indent things properly, and the code tags button, </> in the menu, to post in the forum - Thanks, Moderator)

Yeah, you really need to start using code tags.

probably wouldve been easier to just link a repo but, se la vi. thats the code, libraries to include in the arduino ide are near the top.

so there is no confusion, i did not write the code, i modoified it to what i thought would be a workable state, deleting bits that i would not need from the original open source sketch.

im not a coder, i do not know much of how to read or write code, but ive tried to learn.

thing is, i really need to get this sketch 100% operational so im not devoted to the chores of horticulture any longer, as well as the added benefit of removing human error from the dosing and ph-ing aspect. the system would be much more efficient given that the amount of nutrients is exactly controlled and ph real time adjusted.

im using arduino ide 1.8.12 and cant get the damn code to compile, gives me some very long error codes that im not even sure how to interpret.

so im here A) asking for help
AND B) scouting for a coder to complete this project and possibly a reward for a operational sketch that can be paid via paypal, fb, square, zelle,

i need this sketch to properly operate a 3 room setup. like i said, for those interested only.

dont need to hear that im a noob, i know.

thanks.

sp. "c'est la vie"

thanks for the help.

You're welcome

berten-ernie42:
probably wouldve been easier to just link a repo

Yes, why didn't you?
I've seen this done before; code posted from an unnamed third party source, link to to source not provided, attempt made to conceal source (removal of attribution from beginning of file). I don't understand why people do it.

Most of the original code seems to be from an older and/or hacked version of DROMatic. The DROMatic repository doesn't seem to indicate any license terms, so I imagine that this is not free (as in libre) code. You certainly shouldn't have posted such a large portion of copyrighted code on the forum here without permission from the author.

Ignoring all that, since you admit to not being a coder, posting a version of code with your banjaxed "tweaks" is just presenting the folks here with a bigger headache. If you need help getting the original code working then link to the original code and ask for help on it. If you have the original code compiled and working and want tweaks done, then link to the original code and ask for the tweaks.

It is jot copyright, nor has it been able to compile. Hence why I'm here asking for help. Yes, original is dromatic, and nowhere was I attempting to conceal that fact since it's still written right at the top of the code...

The repo on github for the original dromatic is open source, anyone can modify it to their needs as they see fit. I'm not attempting to sell or make profit of this code. I jus need a working sketch.

If I knew how to create a repo I'd have done that.

berten-ernie42:
It is jot copyright, nor has it been able to compile. Hence why I'm here asking for help. Yes, original is dromatic, and nowhere was I attempting to conceal that fact since it's still written right at the top of the code...

It is not currently written at the top of the code you posted in your original post - it was in the original source and has been removed.

The code is absolutely copyrighted by the original author. The absence of more specific license terms (at least I didn't find any) means you are not entitled to modify it and then publish that modified version on a non-GitHub website.

berten-ernie42:
The repo on github for the original dromatic is open source, anyone can modify it to their needs as they see fit. I'm not attempting to sell or make profit of this code. I jus need a working sketch.

You can get away with modifying it for your own use, but not redistributing it away from GitHub.

berten-ernie42:
If I knew how to create a repo I'd have done that.

You didn't need to, there was already the one where you got the code in the first place.

Well I learned something from this thread: "fertigation" is a thing, although I had to look it up :slight_smile: (and the speel chekkah here gives it a wavy red underline....)

@arduarn, Why are you beating this guy up? I didn't see any copy write stuff on any of the source files I looked at. On the author's website he states its open source. I doubt he cares if he messes with his copy of it.

@berten-ernie42 Where are you located on the planet?

-jim lee

jimLee:
I didn't see any copy write stuff on any of the source files I looked at. On the author's website he states its open source. I doubt he cares if he messes with his copy of it.

In general, by virtue of an author creating an original work, it is automatically copyrighted. A copyright notice and licensing terms may confer additional rights to a third party. In this case, there was no license provided by the author that I could see, so the only applicable license would be that in the GitHub terms, some of which are:

If you set your pages and repositories to be viewed publicly, you grant each User of GitHub a nonexclusive, worldwide license to use, display, and perform Your Content through the GitHub Service and to reproduce Your Content solely on GitHub as permitted through GitHub's functionality (for example, through forking). You may grant further rights if you adopt a license. If you are uploading Content you did not create or own, you are responsible for ensuring that the Content you upload is licensed under terms that grant these permissions to other GitHub Users.

And no, I'm neither a lawyer nor a copyright nazi, but do occasionally get annoyed when folk take the piss, which brings us to the next point:

jimLee:
Why are you beating this guy up?

Hardly beating him up, but some of the issues I have with his posts are:

  • didn't read the forum posting guidelines
  • posted a large piece of copyrighted code
  • removed the attribution from the code
  • didn't use code tags for the post (kindly fixed by CrossRoads)
  • in any case, should've posted the sketch as an attachment due to size
  • spread segments of the code over 5 separate posts
  • posted incomplete code
  • didn't include a link to the location of the original code
  • admitted to not being much of a coder, but only provided his broken version of the code and not the original as well
  • stated that it would have been easier to link to a repo but didn't link to the original repo
  • argued about my criticism instead of just fixing the issues

I could probably go on, but this is already getting silly and I'm sure the OP has already moved on, with or without a solution.

Look guys, your absolutely right, I thought this site was a forum that would help to fix the issue with the original sketch. I reached out to the original author of the program, a very kind gentlemen by the name Devin Olsen. And he was very understanding and supportive for me or ANYONE to play with his code and modify or do as they see fit, as he stated to me. I removed the attribute because I had already started messing with the code, like I said in the OP.. So in my head, I didnt want to attribute his name and whatnot to the program in which I was trying to repair. Nor did I want to put his program out on blast that it's a bugged program, not working, and really way too big for me to even know where to start. I didnt think to post to the original repo, cuz like i said, i didnt need some parts and needed to modify others. You guys missed the point completely. And instead looked to point out my flaws and what I did wrong without even looking at the damn program or offering to guide me to get it to compile and run on a system that I just invested a shit ton of money to have a wall Decoration essentially. The parts and whatnot I had already purchased, spent countless hours building it and wiring it, all based off Mr. OLSENS hard work on his system. Nowhere was I trying to steal that man's thunder, I just need an operational fricking program so i can implement it and spend more time with my family. Instead of being tied to the chores of horticulture.

Heard good things about forums, as I'm on quite a few myself but never really had a horror story till now. Months later and the auto doser is still not functional. I'm in Michigan, Mr. JimLee. Thank you for not ripping g my head off for my "etiquette".

What you have to remember is that the forum is staffed by volunteers.

If you want free help, you have to either enthuse those volunteers, or find a helper with particular interest in your area of interest.

Otherwise, offer remuneration.