//Wiring Guidelines for the Main Line Controller // //SD Card // MISO -50 // MOSI -51 // SCK -52 // CS -53 // //GPS // Power // Ground // RX2 -yellow // TX2 -Green // //Relay // Power // Ground // Relay 1 -10 // Relay 2 -13 // Relay 3 -11 // Relay 4 -12 // //Flow Meter // Power -yellow // Ground -Red // Signal -White 49 const int pressureInput = A0; //select the analog input pin for the pressure transducer const int pressureZero = 100; //analog reading of pressure transducer at 0psi const int pressureMax = 921.6; //analog reading of pressure transducer at 100psi const int pressuretransducermaxPSI = 200; //psi value of transducer being used float pressureValue = 0; //variable to store the value coming from the pressure transducer String dataGPS; String SLong; String SLat; String SGPStime; String SGPSdate; int noFixPin = 13; #include DS3231 rtc(SDA, SCL); //SD card----------------------------------------------------------- //Mega SPI Pins 50(MISO), 51(MOSI), 52(SCK), 53(SS) #include #include #define CS_PIN 53 // 12 X 10 array #define ROW_DIM 12 #define COL_DIM 10 // Array for data. int UserData[ROW_DIM][COL_DIM]; int i = 0; // First array index. int j = 0; // Second array index size_t n; // Length of returned field with delimiter. char str[20]; // Must hold longest field with delimiter and zero byte. char *ptr; // Test for valid field. File file; /* Read a file one field at a time. file - File to read. str - Character array for the field. size - Size of str array. delim - String containing field delimiters. return - length of field including terminating delimiter. Note, the last character of str will not be a delimiter if a read error occurs, the field is too long, or the file does not end with a delimiter. Consider this an error if not at end-of-file. */ size_t readField(File* file, char* str, size_t size, char* delim) { char ch; size_t n = 0; while ((n + 1) < size && file->read(&ch, 1) == 1) { // Delete CR. if (ch == '\r') { continue; } str[n++] = ch; if (strchr(delim, ch)) { break; } } str[n] = '\0'; return n; } //------------------------------------------------------------------------------ #define errorHalt(msg) {Serial1.println(F(msg)); while(1);} //------------------------------------------------------------------------------ String dataString = ""; //Global Variables for the data from the SD card String dataString1 = ""; //Global Variables for the data from the SD card float NDVIRAW1; //I wasn't able to put decimal values on the SD card so the nitrogen rich strip data is converted form NDVIRAW to NDVI by deviding it by 100 float NDVIRAW2; float NDVIRAW3; float NDVI1; float NDVI2; float NDVI3; float NRSSV1; //Nitrogen rich strip data to reference in each zone. these are fom the sd card and changes as the lateral moves float NRSSV2; float NRSSV3; float NRSSV4; float NRSSV5; float NRSSV6; float NRSSV7; float NRSSV8; float NRSSV9; float NRSSV10; float width1 = 22; //width of the plot and speed of the lateral for application math float width2 = 11; float Speed; float DAE; void convertData() { NDVIRAW1 = (UserData [11][0]); //Take variable parameters from SD card and set them to global values NDVIRAW2 = (UserData [11][1]); NDVIRAW3 = (UserData [11][2]); NDVI1 = ((NDVIRAW1) / 100); NDVI2 = ((NDVIRAW2) / 100); NDVI3 = ((NDVIRAW3) / 100); Speed = (UserData [11][7]); DAE = (UserData [11][9]); } void PrintData() { Serial1.print("NDVIRAW1- "); //the function prints data for trouble shooting on the simulator, serial1 port is for a serial pass through program because of the radio Serial1.println(NDVIRAW1); Serial1.print("NDVIRAW2- "); Serial1.println(NDVIRAW2); Serial1.print("NDVIRAW3- "); Serial1.println(NDVIRAW3); Serial1.print("NDVI1- "); Serial1.println(NDVI1); Serial1.print("NDVI2- "); Serial1.println(NDVI2); Serial1.print("NDVI3- "); Serial1.println(NDVI3); Serial1.print("Speed- "); Serial1.println(Speed); Serial1.print("DAE- "); Serial1.println(DAE); } //Flow Meter #include //this library is used to read the frequancy output for the flow meter #include //20 (SDA), 21(SCL) #include //I2C LCD screen library LiquidCrystal_I2C lcd(0x27, 20, 4); //enter the size of the LCD screen float flowRate; //decimal value fiven from the flow meter double sum = 0; //counts how many pulses come from the flow meter int count = 0; //count how many times you have gone through the loop int FlowMeterPin = 49; //input pin for the flow meter //Flow Control Valve float RflowRate = 1; //target flow rate given either by the calculation or the mock rate float plus2percentFR; //2% wiggle room for the flow control value so it doesn't take forever going back and forth float minus2perecentFR; bool CloseEnough; //boolean logic to kick out the flow control loop once the rate is secure int lower1 = 10; //Pins for the 4 relay board to change the direction of the electricity on the flow control valve int lower2 = 13; //the multi relay boards ue optocouplers, this reverses the signal. low is high and high is low. int higher1 = 11; int higher2 = 12; unsigned long FRAresetVector = 0; //Flow Rate Adjustment time out counter char incomingByte = 0; //character declaration for the incoming data through the radio String command; //string that the incoming byte is put in to be parsed float encoder = 0; //the encoder value int LED1 = 39; //Testing LEDs to make sure radios, parsing, and commands based on the encoder worked int LED2 = 41; int LED3 = 43; unsigned long EresetVector = 0; //Time out vectors for the encoder and radios unsigned long R1resetVector = 0; float Sensor1 = 0; //Sensor1 - 10 are the NDVI values collected from the greenseekers after parsing float Sensor2 = 0; float Sensor3 = 0; float Sensor4 = 0; float Sensor5 = 0; float Sensor6 = 0; float Sensor7 = 0; float Sensor8 = 0; float Sensor9 = 0; float Sensor10 = 0; float rate1; //rate 1 - 10 are the nitrogen rates for each zone float rate2; float rate3; float rate4; float rate5; float rate6; float rate7; float rate8; float rate9; float rate10; float requiredRate; //requiredRate is the target rate for the main line float requiredRateGPM; //requiredRate is the target rate for the main line void setup() { // put your setup code here, to run once: pinMode(FlowMeterPin, INPUT_PULLUP); lcd.begin(); lcd.backlight(); lcd.print("Time: Error Code:"); lcd.setCursor(0, 2); lcd.print("Freq: FRate:"); FreqMeasure.begin(); rtc.begin(); // The following lines can be uncommented to set the date and time //rtc.setDOW(TUESDAY); // Set Day-of-Week to SUNDAY //rtc.setTime(0, 43, 0); // Set the time to 12:00:00 (24hr format) //rtc.setDate(9, 8, 2020); // Set the date to January 1st, 2014 Serial.begin(9600); Serial1.begin(9600); Serial2.begin(9600); // Initialize the SD. if (!SD.begin(CS_PIN)) { errorHalt("begin failed"); } // Create or open the file. file = SD.open("READNUM.TXT", FILE_WRITE); if (!file) { errorHalt("open failed"); } // Rewind the file for read. file.seek(0); // Read the file and store the data. for (i = 0; i < ROW_DIM; i++) { for (j = 0; j < COL_DIM; j++) { n = readField(&file, str, sizeof(str), ",\n"); //if (n == 0) { // errorHalt("Too few lines"); // } UserData[i][j] = strtol(str, &ptr, 10); if (ptr == str) { errorHalt("bad number"); } if (j < (COL_DIM - 1) && str[n - 1] != ',') { errorHalt("line with too few fields"); } } // Allow missing endl at eof. if (str[n - 1] != '\n' && file.available()) { errorHalt("missing endl"); } } // Print the array. for (i = 0; i < ROW_DIM; i++) { for (j = 0; j < COL_DIM; j++) { if (j) { Serial1.print(' '); } Serial1.print(UserData[i][j]); } Serial1.println(); } // Serial.println("Done"); file.close(); convertData(); PrintData(); Serial1.println("SD Upload Finished"); //PinMode Setup---------------------------------------------------------------- Serial1.println("Preparing the Flow Control Valve"); pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); pinMode(LED3, OUTPUT); pinMode(lower1, OUTPUT); pinMode(lower2, OUTPUT); pinMode(higher1, OUTPUT); pinMode(higher2, OUTPUT); digitalWrite(lower1, HIGH); //Octocoupler on the relay board makes the logic counterintuitive, so for this high actually turns the relay low and low turns the relay high digitalWrite(lower2, HIGH); digitalWrite(higher1, LOW); digitalWrite(higher2, LOW); //`delay(24000); digitalWrite(higher1, HIGH); digitalWrite(higher2, HIGH); Serial1.println("Preparing the Flow Control Valve Finished"); } long bigTime; //************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************ void loop() { // put your main code here, to run repeatedly: //Serial1.println("reading GPS"); CheckClock(); readGPS(); checkEncoder(); collectNDVI(); //testRateDetermination(); RateDetermination(); sendRates(); CloseEnough = false; bigTime = millis() + 60000; while (bigTime >= millis()) { setMainLine(); } //Serial1.println("Sending Rates"); //sendRates(); Serial1.println("Saving Data"); getPressure(); dataString += "psi"; dataString += ","; dataString += pressureValue; dataString += ","; saveData(); } //Functions Start here: //*************************************************************************************** void testRateDetermination() { //This function is used for uniform and variable rate application testing //simply comment out the RateDetermination function and uncomment this function //in the main loop to use it if (/*(encoder > 0) &&*/ (encoder < 3)) { rate1 = 0.023776; //1.5ML/SEC rate2 = 0.023776; //1.5ML/SEC rate3 = 0.023776; //1.5ML/SEC rate4 = 0.023776; //1.5ML/SEC rate5 = 0.023776; //1.5ML/SEC rate6 = 0.023776; //1.5ML/SEC rate7 = 0.023776; //1.5ML/SEC rate8 = 0.023776; //1.5ML/SEC rate9 = 0.023776; //1.5ML/SEC rate10 = 0.023776; //1.5ML/SEC requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; requiredRateGPM = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; } if ((encoder > 3) && (encoder < 6)) { rate1 = 0.071327; //4.5ML/SEC rate2 = 0.071327; //4.5ML/SEC rate3 = 0.071327; //4.5ML/SEC rate4 = 0.071327; //4.5ML/SEC rate5 = 0.071327; //4.5ML/SEC rate6 = 0.071327; //4.5ML/SEC rate7 = 0.071327; //4.5ML/SEC rate8 = 0.071327; //4.5ML/SEC rate9 = 0.071327; //4.5ML/SEC rate10 = 0.071327; //4.5ML/SEC requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; requiredRateGPM = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; } if ((encoder > 6) && (encoder < 9)) { rate1 = 0.118878; //7.5ML/SEC rate2 = 0.118878; //7.5ML/SEC rate3 = 0.118878; //7.5ML/SEC rate4 = 0.118878; //7.5ML/SEC rate5 = 0.118878; //7.5ML/SEC rate6 = 0.118878; //7.5ML/SEC rate7 = 0.118878; //7.5ML/SEC rate8 = 0.118878; //7.5ML/SEC rate9 = 0.118878; //7.5ML/SEC rate10 = 0.118878; //7.5ML/SEC requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; requiredRateGPM = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; } if ((encoder > 9) && (encoder < 12)) { rate1 = 0.166429; //10.5ML/SEC rate2 = 0.166429; //10.5ML/SEC rate3 = 0.166429; //10.5ML/SEC rate4 = 0.166429; //10.5ML/SEC rate5 = 0.166429; //10.5ML/SEC rate6 = 0.166429; //10.5ML/SEC rate7 = 0.166429; //10.5ML/SEC rate8 = 0.166429; //10.5ML/SEC rate9 = 0.166429; //10.5ML/SEC rate10 = 0.166429; //10.5ML/SEC requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; requiredRateGPM = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; } if ((encoder > 12) && (encoder < 15)) { rate1 = 0.21398; //13.5ML/SEC rate2 = 0.21398; //13.5ML/SEC rate3 = 0.21398; //13.5ML/SEC rate4 = 0.21398; //13.5ML/SEC rate5 = 0.21398; //13.5ML/SEC rate6 = 0.21398; //13.5ML/SEC rate7 = 0.21398; //13.5ML/SEC rate8 = 0.21398; //13.5ML/SEC rate9 = 0.21398; //13.5ML/SEC rate10 = 0.21398; //13.5ML/SEC requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; requiredRateGPM = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; } if ((encoder > 15) && (encoder < 18)) { rate1 = 0.023776; //1.5ML/SEC rate2 = 0.21398; //13.5ML/SEC rate3 = 0.071327; //4.5ML/SEC rate4 = 0.21398; //13.5ML/SEC rate5 = 0.118878; //7.5ML/SEC rate6 = 0.023776; //1.5ML/SEC rate7 = 0.071327; //4.5ML/SEC rate8 = 0.166429; //10.5ML/SEC rate9 = 0.023776; //1.5ML/SEC rate10 = 0.118878; //7.5ML/SEC requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; requiredRateGPM = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; } if ((encoder > 21) && (encoder < 24)) { rate1 = 0.118878; //7.5ML/SEC rate2 = 0.166429; //10.5ML/SEC rate3 = 0.023776; //1.5ML/SEC rate4 = 0.21398; //13.5ML/SEC rate5 = 0.118878; //7.5ML/SEC rate6 = 0.023776; //1.5ML/SEC rate7 = 0.166429; //10.5ML/SEC rate8 = 0.071327; //4.5ML/SEC rate9 = 0.071327; //4.5ML/SEC rate10 = 0.21398; //13.5ML/SEC requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; requiredRateGPM = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; } if ((encoder > 27) && (encoder < 30)) { rate1 = 0.166429; //10.5ML/SEC rate2 = 0.071327; //4.5ML/SEC rate3 = 0.023776; //1.5ML/SEC rate4 = 0.118878; //7.5ML/SEC rate5 = 0.21398; //13.5ML/SEC rate6 = 0.071327; //4.5ML/SEC rate7 = 0.21398; //13.5ML/SEC rate8 = 0.023776; //1.5ML/SEC rate9 = 0.118878; //7.5ML/SEC rate10 = 0.166429; //10.5ML/SEC requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; requiredRateGPM = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; } } void CheckClock() { dataString = rtc.getDOWStr(); dataString += (","); dataString += rtc.getDateStr(); dataString += (","); dataString += rtc.getTimeStr(); dataString += (","); dataString += ("Temperature: "); dataString += (","); dataString += rtc.getTemp(); dataString += (","); dataString += (" C"); dataString += (","); } void checkEncoder() { encoder = 999999999; //set the encoder to something it would never be for the while loop //Serial1.print("ER = "); //communication through the serial1 port for troubleshooting Serial.println("ER,"); //ER, means encoder read. this signal tells the arduino with the encoder attached to send the encoder location to it. EresetVector = millis(); //set the EresetVector to the arduinos clock while (encoder == 999999999) { SerialFunction(); //serial function will catch the data form the radio and set the encoders new value as a global value to kick out of this while loop if (millis() > EresetVector + 500) //if the serial function fails to collect anything from the encoder this will kick it out of the loop after five seconds { encoder = (7); //7 is a timeout error //Serial1.println("encoder error"); } } //Serial1.println(encoder); dataString += encoder; //this saves the encoder data to a string that is saved to an SD card at the end of ever full loop dataString += ","; } void collectNDVI() { //Serial1.println("Inside Collecting NDVI"); Serial.println("SR,"); //this is the signal for all of the greenseekers to read. each nodes data will be collected individually //Serial1.println("SR,"); delay(3000); //wait a couple seconds for all of the nodes to parse out the signal, take the reading, and parse the reading. Sensor1 = 1000000; //set the sensor to any value to hold it in the while loop Serial.println("R1,"); //send the signal for node 1 to send its value or error code //Serial1.print("R1, "); R1resetVector = millis(); //set the reset vector to the arduinos clock while (Sensor1 == 1000000) { SerialFunction(); //serial function will parse out the NDVI value or the error code and change the Sensor1 value to kick it out of the while loop if (Sensor1 == 8) { //Serial1.println("Sensor 1 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor1 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 1 time out error, node offline."); //return; } if (Sensor1 == 9) { //Serial1.println("Sensor 1 time out error, problem on node."); //9 means the node had a problem but is responsive } } //Serial1.println(Sensor1); Sensor2 = 1000000; Serial.println("R2,"); //Serial1.print("R2, "); R1resetVector = millis(); while (Sensor2 == 1000000) { SerialFunction(); if (Sensor2 == 8) { //Serial1.println("Sensor 2 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor2 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 2 error"); //return; } } //Serial1.println(Sensor2); Sensor3 = 1000000; Serial.println("R3,"); //Serial1.print("R3, "); R1resetVector = millis(); while (Sensor3 == 1000000) { SerialFunction(); if (Sensor3 == 8) { //Serial1.println("Sensor 3 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor3 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 3 error"); //return; } } //Serial1.println(Sensor3); Sensor4 = 1000000; Serial.println("R4,"); //Serial1.print("R4, "); R1resetVector = millis(); while (Sensor4 == 1000000) { SerialFunction(); if (Sensor4 == 8) { //Serial1.println("Sensor 4 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor4 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 4 error"); //return; } } //Serial1.println(Sensor4); Sensor5 = 1000000; Serial.println("R5,"); //Serial1.print("R5, "); R1resetVector = millis(); while (Sensor5 == 1000000) { SerialFunction(); if (Sensor5 == 8) { //Serial1.println("Sensor 5 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor5 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 5 error"); //return; } } //Serial1.println(Sensor5); Sensor6 = 1000000; Serial.println("R6,"); //Serial1.print("R6, "); R1resetVector = millis(); while (Sensor6 == 1000000) { SerialFunction(); if (Sensor6 == 8) { //Serial1.println("Sensor 6 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor6 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 6 error"); //return; } } //Serial1.println(Sensor6); Sensor7 = 1000000; Serial.println("R7,"); //Serial1.print("R7, "); R1resetVector = millis(); while (Sensor7 == 1000000) { SerialFunction(); if (Sensor7 == 8) { //Serial1.println("Sensor 7 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor7 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 7 error"); //return; } } //Serial1.println(Sensor7); Sensor8 = 1000000; Serial.println("R8,"); //Serial1.print("R8, "); R1resetVector = millis(); while (Sensor8 == 1000000) { SerialFunction(); if (Sensor8 == 8) { //Serial1.println("Sensor 8 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor8 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 8 error"); //return; } } //Serial1.println(Sensor8); Sensor9 = 1000000; Serial.println("R9,"); //Serial1.print("R9, "); R1resetVector = millis(); while (Sensor9 == 1000000) { SerialFunction(); if (Sensor9 == 8) { //Serial1.println("Sensor 9 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor9 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 9 error"); //return; } } //Serial1.println(Sensor9); Sensor10 = 1000000; Serial.println("R10,"); //Serial1.print("R10, "); R1resetVector = millis(); while (Sensor10 == 1000000) { SerialFunction(); if (Sensor10 == 8) { //Serial1.println("Sensor 10 Too far or too close error"); } if (millis() > R1resetVector + 700) { Sensor10 = (7); //7 is an error code that means the node didn't respond //Serial1.println("Sensor 10 error"); //return; } } //Serial1.println(Sensor10); dataString += Sensor1; //save the NDVI data to the SD card string dataString += ","; dataString += Sensor2; dataString += ","; dataString += Sensor3; dataString += ","; dataString += Sensor4; dataString += ","; dataString += Sensor5; dataString += ","; dataString += Sensor6; dataString += ","; dataString += Sensor7; dataString += ","; dataString += Sensor8; dataString += ","; dataString += Sensor9; dataString += ","; dataString += Sensor10; dataString += ","; } void sendRates() { //Serial1.print("Inside Sending Rates"); String allRates; //this is the string that is sent to all of the nodes. each piece of information uses a special character so the nodes can parse out the different commands. I am sure there is a better way to do this. String OAATrates; //Nodes are having trouble. Try Sending data one at time. Probably slower though allRates = ("ML"); allRates = (allRates + "," + requiredRate + "," + "S1" + "," + rate1 + "," + "S2" + "," + rate2 + "," + "S3" + "," + rate3 + "," + "S4" + "," + rate4 + "," + "S5" + "," + rate5 + "," + "S6" + "," + rate6 + "," + "S7" + "," + rate7 + "," + "S8" + "," + rate8 + "," + "S9" + "," + rate9 + "," + "S10" + "," + rate10 + "," ); //Serial.println(allRates); //Serial1.print("allRates"); //Serial1.print(allRates); dataString += allRates; //save the command to the SD card string dataString += ","; //Mainline Rate ----------------------------------------------------------------------------- OAATrates = ("ML"); //One At A Time rates, see comment above OAATrates = (OAATrates + "," + requiredRate); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 1 ------------------------------------------------------------------------------------ OAATrates = ("S1"); OAATrates = (OAATrates + "," + rate1); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 2 ------------------------------------------------------------------------------------ OAATrates = ("S2"); OAATrates = (OAATrates + "," + rate2); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 3 ------------------------------------------------------------------------------------ OAATrates = ("S3"); OAATrates = (OAATrates + "," + rate3); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 4 ------------------------------------------------------------------------------------ OAATrates = ("S4"); OAATrates = (OAATrates + "," + rate4); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 5 ------------------------------------------------------------------------------------ OAATrates = ("S5"); OAATrates = (OAATrates + "," + rate5); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 6 ------------------------------------------------------------------------------------ OAATrates = ("S6"); OAATrates = (OAATrates + "," + rate6); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 7 ------------------------------------------------------------------------------------ OAATrates = ("S7"); OAATrates = (OAATrates + "," + rate7); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 8 ------------------------------------------------------------------------------------ OAATrates = ("S8"); OAATrates = (OAATrates + "," + rate8); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 9 ------------------------------------------------------------------------------------ OAATrates = ("S9"); OAATrates = (OAATrates + "," + rate9); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); //Rate 10 ------------------------------------------------------------------------------------ OAATrates = ("S10"); OAATrates = (OAATrates + "," + rate10); Serial.println(OAATrates); //Serial.print("\n"); OAATrates = (""); delay(10); } void setMainLine() { //Serial1.println("Inside Set Main Line"); FRAresetVector = millis(); while (CloseEnough == false) //make this false in the main loop so the while loop will run and check if its false { ReadFlowMeter(); //this function reads the flow meter sendUpdate(); //this function send the real flow rate to the nodes adjustRate(); //this function adjusts the rate if (millis() > FRAresetVector + 25000) //if more than twenty five seconds pass kick out of this loop { CloseEnough = true; //Serial1.println("Set MainLine Error"); //return; } } } String upDate; void sendUpdate() { upDate = "RU,"; upDate = upDate + flowRate; Serial.print(upDate); Serial1.print(upDate); } void ReadFlowMeter() { //Serial1.println("Inside Read Flow Meter"); boolean go; //float flowRate; go = true; while (go == true) { while (count < 31) { if (FreqMeasure.available()) { // average several reading together sum = sum + FreqMeasure.read(); count = count + 1; } } if (count > 10) { float frequency = FreqMeasure.countToFrequency(sum / count); lcd.setCursor(0, 3); lcd.print(frequency); lcd.print(" "); flowRate = (((frequency / 518) / 1000) * 60000); //conversion of frequency to flow rate in gal/min given by the tag on the flow meter lcd.print(flowRate); //Serial1.print("flowRate: "); //Serial1.println(flowRate); sum = 0; count = 0; } go = false; } } void adjustRate() { //Serial1.println("Inside Adjust Flow Rate"); RflowRate = requiredRateGPM; //convert the global value requiredRate to a global value specifically for this loop, if I was better at coding functions I would use more local variables plus2percentFR = ((RflowRate * .02) + RflowRate); //calculate 2% over the required Flow Rate Serial1.println("plus2percentFR"); Serial1.println(plus2percentFR); minus2perecentFR = (RflowRate - (RflowRate * .02)); //calculate 2% under the required Flow Rate Serial1.println("minus2perecentFR"); Serial1.println(minus2perecentFR); Serial1.println("Target_flowRate"); Serial1.println(requiredRateGPM); Serial1.println("flowRate"); Serial1.println(flowRate); if ((flowRate < plus2percentFR) && (flowRate > minus2perecentFR)) { //Serial1.print("rate secure"); //If the flow rate is within the 2% bounds on either side you can kick out of this loop using the boolean logic CloseEnough == true; } else { CloseEnough == false; //if the flow rate is not within the bounds this boolean statement keeps you in the adjust rate loop } if (CloseEnough == false) { while (flowRate > plus2percentFR) { flowControlLower(); //If the actual flow rate is higher than the LineRate close the flow control value return; //return to the start of the adjust rate loop was you're back from the flowControlLower loop } while (flowRate < minus2perecentFR) { flowControlHigher(); //If the actual flow rate is lower than the LineRate open the flow control value return; //return to the start of the adjust rate loop was you're back from the flowControlHigher loop } } } void flowControlHigher() { Serial1.println("Closing the Valve"); digitalWrite(lower1, HIGH); digitalWrite(lower2, HIGH); digitalWrite(higher1, LOW); digitalWrite(higher2, LOW); delay(750); digitalWrite(higher1, HIGH); digitalWrite(higher2, HIGH); delay(1); } void flowControlLower() { Serial1.println("opening the Valve"); digitalWrite(higher1, HIGH); digitalWrite(higher2, HIGH); digitalWrite(lower1, LOW); digitalWrite(lower2, LOW); delay(750); digitalWrite(lower1, HIGH); digitalWrite(lower2, HIGH); delay(1); } void SerialFunction() { if (Serial.available() > 0) //If data is coming in, stop and do this { incomingByte = Serial.read(); //anything coming in on the serial port is set as the chacter incomingByte if (incomingByte == '\n') //If the user hits enter it should be a null character, meaning they're finished inputing a command { parseCommand(command); //Go to the function parseCommand and take the string called command with you //Serial1.print("Command = "); //Serial1.println(command); command = ""; //empty the string called command } else //if this is not a null character { command += incomingByte; //add the incoming Bytes to the string "command" } } return; } void parseCommand(String com) //this is the function that (when called) takes the string "command" and parses it { String part1; String part2; int tool; //encoder "ER" = 01 //Solenoid1 "S1" = 11 //Solenoid2 "S2" = 12 //Solenoid3 "S3" = 13 part1 = com.substring(0, com.indexOf(",")); part2 = com.substring(com.indexOf(",") + 1); //Serial1.print("part 1 = "); //Serial1.print(part1); //Serial1.print("part 2 = "); //Serial1.print(part2); float pin = part2.toFloat(); //Serial1.print("pin = "); //Serial1.print(pin); if (part1.equalsIgnoreCase("ER")) //this whole parsing segment feels a little silly, but the way I put it together was to hold a value and then depending on what set of characters proceeded that value sends it to a switch case to assign it globally. I'm sure this is more convoluted than necessary, but this is what I came up with. One way to avoid this would be to use API mode with the radios so that the data comes from a known location. { encoder = pin; } else if (part1.equalsIgnoreCase("S1")) { Sensor1 = pin; } else if (part1.equalsIgnoreCase("S2")) { Sensor2 = pin; } else if (part1.equalsIgnoreCase("S3")) { Sensor3 = pin; } else if (part1.equalsIgnoreCase("S4")) { Sensor4 = pin; } else if (part1.equalsIgnoreCase("S5")) { Sensor5 = pin; } else if (part1.equalsIgnoreCase("S6")) { Sensor6 = pin; } else if (part1.equalsIgnoreCase("S7")) { Sensor7 = pin; } else if (part1.equalsIgnoreCase("S8")) { Sensor8 = pin; } else if (part1.equalsIgnoreCase("S9")) { Sensor9 = pin; } else if (part1.equalsIgnoreCase("S10")) { Sensor10 = pin; } } void saveData() { Serial1.println("SD"); // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. File dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.println(dataString); dataFile.close(); // print to the serial port too: Serial1.println(dataString); } // if the file isn't open, pop up an error: else { Serial1.println("error opening datalog.txt"); } dataString = ""; } boolean foundRMC; boolean readit; void readGPS() { //Serial1.println("Inside Read GPS"); foundRMC = false; readit = false; long GPSresetVector; long GPSreadTime; GPSreadTime = millis(); GPSresetVector = millis(); SGPStime = ""; SGPSdate = ""; while (readit == false) { if (Serial2.available()) { char c = Serial2.read(); if (c == '\n') //if its the end of sentence evaluate the contents { parseGPS(dataGPS); //Serial1.println(dataGPS); lcd.setCursor(0, 1); lcd.print(SGPStime); dataGPS = ""; //reset the dataGPS string to blank if (foundRMC == true) { dataString += (SGPSdate); dataString += ","; dataString += (SGPStime); dataString += ","; dataString += (SLat); dataString += ","; dataString += (SLong); dataString += ","; readit = true; } if (millis() > GPSreadTime + 2000) //if its the end of sentence evaluate the contents { dataGPS = ""; SGPSdate = "No DATA"; SGPStime = "No DATA"; SLat = "No DATA"; SLong = "No DATA"; dataString += (SGPSdate); dataString += ","; dataString += (SGPStime); dataString += ","; dataString += (SLat); dataString += ","; dataString += (SLong); dataString += ","; readit = true; } } else // if its not the end of the sentence keep adding the characters to the string { dataGPS += c; } } } //Serial1.print ("Date: "); //Serial1.println (SGPSdate); //Serial1.print ("Time: "); //Serial1.println (SGPStime); //Serial1.print ("Lat: "); //Serial1.println (SLat); //Serial1.print ("Long: "); //Serial1.println (SLong); lcd.setCursor(0, 1); lcd.print(SGPStime); } void parseGPS(String data) //Function for parsing the GPS data { //Serial1.println("Inside Parse GPS"); int dollarsignposition = dataGPS.indexOf('$'); //find the position of a reoccurring character int starsignposition = dataGPS.indexOf('*'); //find the position of a reoccurring character if (dataGPS.charAt(dollarsignposition + 3) == 'R') //if it is RMC find some stuff { if (dataGPS.charAt(dollarsignposition + 17) == 'A') //if it is RMC find some stuff { SLat = data.substring(dollarsignposition + 19, dollarsignposition + 21); //Record degrees SLat += (" "); // add a space SLat += data.substring(dollarsignposition + 21, dollarsignposition + 29); //record decimal degrees SLat += data.substring(dollarsignposition + 30, dollarsignposition + 31); //add the N or S SLong = data.substring(dollarsignposition + 33, dollarsignposition + 35); //Record degrees SLong += (" "); //add a space SLong += data.substring(dollarsignposition + 35, dollarsignposition + 43); //record the decimal degrees SLong += data.substring(dollarsignposition + 44, dollarsignposition + 45); //add E or W SGPStime = data.substring(dollarsignposition + 7, dollarsignposition + 9); //record the hour, consider doing a string to float hour time zone conversion SGPStime += (':'); //record a break SGPStime += data.substring(dollarsignposition + 9, dollarsignposition + 11); //record the minutes SGPStime += ('.'); //record a decimal to show seconds SGPStime += data.substring(dollarsignposition + 11, dollarsignposition + 13); //record seconds if (dataGPS.charAt(starsignposition - 3) == ',') //make sure this is a UBlox RMC line { SGPSdate = data.substring(starsignposition - 8, starsignposition - 6); //record the month SGPSdate += ('/'); //add a slash SGPSdate += data.substring(starsignposition - 10, starsignposition - 8); //record the day SGPSdate += ('/'); //add a slash SGPSdate += data.substring(starsignposition - 6, starsignposition - 4); //record the year } else { SGPSdate = data.substring(starsignposition - 12, starsignposition - 10); //record the month SGPSdate += ('/'); //add a slash SGPSdate += data.substring(starsignposition - 14, starsignposition - 12); //record the day SGPSdate += ('/'); //add a slash SGPSdate += data.substring(starsignposition - 10, starsignposition - 9); //record the year } foundRMC = true; } else { //Serial1.println("No FIX"); // let the user know theres no fix SGPSdate += ("No Fix"); SGPStime += ("No Fix"); foundRMC = true; readit = true; } } } void RateDetermination() { //This function checks the array uploaded by the user to see what soil EC classification each Zone falls into if (/*(encoder > 0) &&*/ (encoder < 3)) { rate1 = 1; rate2 = 1; rate3 = 1; rate4 = 1; rate5 = 1; rate6 = 1; rate7 = 1; rate8 = 1; rate9 = 1; rate10 = 1; requiredRate = 1.01; requiredRateGPM = 1.01; } if ((encoder > 3) && (encoder < 58)) { if (UserData [0][9] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [0][9] = 1) { NRSSV1 = NDVI2; } if (UserData [0][8] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [0][8] = 1) { NRSSV2 = NDVI2; } if (UserData [0][7] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [0][7] = 1) { NRSSV3 = NDVI2; } if (UserData [0][6] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [0][6] = 1) { NRSSV4 = NDVI2; } if (UserData [0][5] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [0][5] = 1) { NRSSV5 = NDVI2; } if (UserData [0][4] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [0][4] = 1) { NRSSV6 = NDVI2; } if (UserData [0][3] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [0][3] = 1) { NRSSV7 = NDVI2; } if (UserData [0][2] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [0][2] = 1) { NRSSV8 = NDVI2; } if (UserData [0][1] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [0][1] = 1) { NRSSV9 = NDVI2; } if (UserData [0][0] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [0][0] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 58) && (encoder < 118)) { if (UserData [1][9] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [1][9] = 1) { NRSSV1 = NDVI2; } if (UserData [1][8] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [1][8] = 1) { NRSSV2 = NDVI2; } if (UserData [1][7] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [1][7] = 1) { NRSSV3 = NDVI2; } if (UserData [1][6] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [1][6] = 1) { NRSSV4 = NDVI2; } if (UserData [1][5] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [1][5] = 1) { NRSSV5 = NDVI2; } if (UserData [1][4] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [1][4] = 1) { NRSSV6 = NDVI2; } if (UserData [1][3] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [1][3] = 1) { NRSSV7 = NDVI2; } if (UserData [1][2] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [1][2] = 1) { NRSSV8 = NDVI2; } if (UserData [1][1] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [1][1] = 1) { NRSSV9 = NDVI2; } if (UserData [1][0] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [1][0] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 118) & (encoder < 178)) { if (UserData [2][9] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [2][9] = 1) { NRSSV1 = NDVI2; } if (UserData [2][8] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [2][8] = 1) { NRSSV2 = NDVI2; } if (UserData [2][7] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [2][7] = 1) { NRSSV3 = NDVI2; } if (UserData [2][6] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [2][6] = 1) { NRSSV4 = NDVI2; } if (UserData [2][5] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [2][5] = 1) { NRSSV5 = NDVI2; } if (UserData [2][4] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [2][4] = 1) { NRSSV6 = NDVI2; } if (UserData [2][3] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [2][3] = 1) { NRSSV7 = NDVI2; } if (UserData [2][2] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [2][2] = 1) { NRSSV8 = NDVI2; } if (UserData [2][1] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [2][1] = 1) { NRSSV9 = NDVI2; } if (UserData [2][0] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [2][0] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 178) & (encoder < 238)) { if (UserData [3][9] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [3][9] = 1) { NRSSV1 = NDVI2; } if (UserData [3][8] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [3][8] = 1) { NRSSV2 = NDVI2; } if (UserData [3][7] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [3][7] = 1) { NRSSV3 = NDVI2; } if (UserData [3][6] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [3][6] = 1) { NRSSV4 = NDVI2; } if (UserData [3][5] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [3][5] = 1) { NRSSV5 = NDVI2; } if (UserData [3][4] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [3][4] = 1) { NRSSV6 = NDVI2; } if (UserData [3][3] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [3][3] = 1) { NRSSV7 = NDVI2; } if (UserData [3][2] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [3][2] = 1) { NRSSV8 = NDVI2; } if (UserData [3][1] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [3][1] = 1) { NRSSV9 = NDVI2; } if (UserData [3][0] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [3][0] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 238) & (encoder < 298)) { if (UserData [4][9] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [4][9] = 1) { NRSSV1 = NDVI2; } if (UserData [4][8] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [4][8] = 1) { NRSSV2 = NDVI2; } if (UserData [4][7] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [4][7] = 1) { NRSSV3 = NDVI2; } if (UserData [4][6] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [4][6] = 1) { NRSSV4 = NDVI2; } if (UserData [4][5] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [4][5] = 1) { NRSSV5 = NDVI2; } if (UserData [4][4] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [4][4] = 1) { NRSSV6 = NDVI2; } if (UserData [4][3] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [4][3] = 1) { NRSSV7 = NDVI2; } if (UserData [4][2] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [4][2] = 1) { NRSSV8 = NDVI2; } if (UserData [4][1] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [4][1] = 1) { NRSSV9 = NDVI2; } if (UserData [4][0] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [4][0] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 298) & (encoder < 358)) { if (UserData [5][9] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [5][9] = 1) { NRSSV1 = NDVI2; } if (UserData [5][8] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [5][8] = 1) { NRSSV2 = NDVI2; } if (UserData [5][7] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [5][7] = 1) { NRSSV3 = NDVI2; } if (UserData [5][6] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [5][6] = 1) { NRSSV4 = NDVI2; } if (UserData [5][5] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [5][5] = 1) { NRSSV5 = NDVI2; } if (UserData [5][4] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [5][4] = 1) { NRSSV6 = NDVI2; } if (UserData [5][3] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [5][3] = 1) { NRSSV7 = NDVI2; } if (UserData [5][2] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [5][2] = 1) { NRSSV8 = NDVI2; } if (UserData [5][1] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [5][1] = 1) { NRSSV9 = NDVI2; } if (UserData [5][0] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [5][0] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 358) & (encoder < 418)) { if (UserData [6][0] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [6][0] = 1) { NRSSV1 = NDVI2; } if (UserData [6][1] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [6][1] = 1) { NRSSV2 = NDVI2; } if (UserData [6][2] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [6][2] = 1) { NRSSV3 = NDVI2; } if (UserData [6][3] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [6][3] = 1) { NRSSV4 = NDVI2; } if (UserData [6][4] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [6][4] = 1) { NRSSV5 = NDVI2; } if (UserData [6][5] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [6][5] = 1) { NRSSV6 = NDVI2; } if (UserData [6][6] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [6][6] = 1) { NRSSV7 = NDVI2; } if (UserData [6][7] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [6][7] = 1) { NRSSV8 = NDVI2; } if (UserData [6][8] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [6][8] = 1) { NRSSV9 = NDVI2; } if (UserData [6][9] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [6][9] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 418) & (encoder < 478)) { if (UserData [7][0] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [7][0] = 1) { NRSSV1 = NDVI2; } if (UserData [7][1] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [7][1] = 1) { NRSSV2 = NDVI2; } if (UserData [7][2] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [7][2] = 1) { NRSSV3 = NDVI2; } if (UserData [7][3] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [7][3] = 1) { NRSSV4 = NDVI2; } if (UserData [7][4] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [7][4] = 1) { NRSSV5 = NDVI2; } if (UserData [7][5] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [7][5] = 1) { NRSSV6 = NDVI2; } if (UserData [7][6] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [7][6] = 1) { NRSSV7 = NDVI2; } if (UserData [7][7] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [7][7] = 1) { NRSSV8 = NDVI2; } if (UserData [7][8] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [7][8] = 1) { NRSSV9 = NDVI2; } if (UserData [7][9] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [7][9] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 478) & (encoder < 538)) { if (UserData [8][0] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [8][0] = 1) { NRSSV1 = NDVI2; } if (UserData [8][1] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [8][1] = 1) { NRSSV2 = NDVI2; } if (UserData [8][2] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [8][2] = 1) { NRSSV3 = NDVI2; } if (UserData [8][3] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [8][3] = 1) { NRSSV4 = NDVI2; } if (UserData [8][4] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [8][4] = 1) { NRSSV5 = NDVI2; } if (UserData [8][5] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [8][5] = 1) { NRSSV6 = NDVI2; } if (UserData [8][6] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [8][6] = 1) { NRSSV7 = NDVI2; } if (UserData [8][7] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [8][7] = 1) { NRSSV8 = NDVI2; } if (UserData [8][8] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [8][8] = 1) { NRSSV9 = NDVI2; } if (UserData [8][9] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [8][9] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 538) & (encoder < 598)) { if (UserData [9][0] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [9][0] = 1) { NRSSV1 = NDVI2; } if (UserData [9][1] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [9][1] = 1) { NRSSV2 = NDVI2; } if (UserData [9][2] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [9][2] = 1) { NRSSV3 = NDVI2; } if (UserData [9][3] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [9][3] = 1) { NRSSV4 = NDVI2; } if (UserData [9][4] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [9][4] = 1) { NRSSV5 = NDVI2; } if (UserData [9][5] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [9][5] = 1) { NRSSV6 = NDVI2; } if (UserData [9][6] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [9][6] = 1) { NRSSV7 = NDVI2; } if (UserData [9][7] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [9][7] = 1) { NRSSV8 = NDVI2; } if (UserData [9][8] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [9][8] = 1) { NRSSV9 = NDVI2; } if (UserData [9][9] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [9][9] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if ((encoder > 598) & (encoder < 655)) { if (UserData [10][0] = 0) { //determine the NRS NDVI to use in each plot- Plot1 NRSSV1 = NDVI1; } if (UserData [10][0] = 1) { NRSSV1 = NDVI2; } if (UserData [10][1] = 0) { //determine the NRS NDVI to use in each plot- Plot2 NRSSV2 = NDVI1; } if (UserData [10][1] = 1) { NRSSV2 = NDVI2; } if (UserData [10][2] = 0) { //determine the NRS NDVI to use in each plot- Plot3 NRSSV3 = NDVI1; } if (UserData [10][2] = 1) { NRSSV3 = NDVI2; } if (UserData [10][3] = 0) { //determine the NRS NDVI to use in each plot- Plot4 NRSSV4 = NDVI1; } if (UserData [10][3] = 1) { NRSSV4 = NDVI2; } if (UserData [10][4] = 0) { //determine the NRS NDVI to use in each plot- Plot5 NRSSV5 = NDVI1; } if (UserData [10][4] = 1) { NRSSV5 = NDVI2; } if (UserData [10][5] = 0) { //determine the NRS NDVI to use in each plot- Plot6 NRSSV6 = NDVI1; } if (UserData [10][5] = 1) { NRSSV6 = NDVI2; } if (UserData [10][6] = 0) { //determine the NRS NDVI to use in each plot- Plot7 NRSSV7 = NDVI1; } if (UserData [10][6] = 1) { NRSSV7 = NDVI2; } if (UserData [10][7] = 0) { //determine the NRS NDVI to use in each plot- Plot8 NRSSV8 = NDVI1; } if (UserData [10][7] = 1) { NRSSV8 = NDVI2; } if (UserData [10][8] = 0) { //determine the NRS NDVI to use in each plot- Plot9 NRSSV9 = NDVI1; } if (UserData [10][8] = 1) { NRSSV9 = NDVI2; } if (UserData [10][9] = 0) { //determine the NRS NDVI to use in each plot- Plot10 NRSSV10 = NDVI1; } if (UserData [10][9] = 1) { NRSSV10 = NDVI2; } calculateRate(); } if (encoder > 655) { rate1 = 0; rate2 = 0; rate3 = 0; rate4 = 0; rate5 = 0; rate6 = 0; rate7 = 0; rate8 = 0; rate9 = 0; rate10 = 0; requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; } } int calculateRate() { Speed = 427; //Serial1.println("Speed"); //Serial1.println(Speed); double NUE; NUE = 0.50; //Serial1.println("NUE"); //Serial1.println(NUE); double PercentN; PercentN = 0.04; //Serial1.println("PercentN"); //Serial1.println(PercentN); //Serial1.println("DAE"); //Serial1.println(DAE); double RI1; double RI2; double RI3; double RI4; double RI5; double RI6; double RI7; double RI8; double RI9; double RI10; double INSEY1; double INSEY2; double INSEY3; double INSEY4; double INSEY5; double INSEY6; double INSEY7; double INSEY8; double INSEY9; double INSEY10; double YP0_1; double YP0_2; double YP0_3; double YP0_4; double YP0_5; double YP0_6; double YP0_7; double YP0_8; double YP0_9; double YP0_10; double NRATE1; double NRATE2; double NRATE3; double NRATE4; double NRATE5; double NRATE6; double NRATE7; double NRATE8; double NRATE9; double NRATE10; double rate1GPA; double rate2GPA; double rate3GPA; double rate4GPA; double rate5GPA; double rate6GPA; double rate7GPA; double rate8GPA; double rate9GPA; double rate10GPA; double realRate1; double realRate2; double realRate3; double realRate4; double realRate5; double realRate6; double realRate7; double realRate8; double realRate9; double realRate10; double rate1GPM; double rate2GPM; double rate3GPM; double rate4GPM; double rate5GPM; double rate6GPM; double rate7GPM; double rate8GPM; double rate9GPM; double rate10GPM; double requiredRateGPM; //Filtered Sensor Data to keep the string from over flowing the memory, probably not the most effective way of solving this but will make due for now float FSensor1 = 0; float FSensor2 = 0; float FSensor3 = 0; float FSensor4 = 0; float FSensor5 = 0; float FSensor6 = 0; float FSensor7 = 0; float FSensor8 = 0; float FSensor9 = 0; float FSensor10 = 0; if (Sensor1 >= 1) { FSensor1 = (NRSSV1 - .01); } else { FSensor1 = Sensor1; } if (Sensor2 >= 1) { FSensor2 = (NRSSV2 - .01); } else { FSensor2 = Sensor2; } if (Sensor3 >= 1) { FSensor3 = (NRSSV3 - .01); } else { FSensor3 = Sensor3; } if (Sensor4 >= 1) { FSensor4 = (NRSSV4 - .01); } else { FSensor4 = Sensor4; } if (Sensor5 >= 1) { FSensor5 = (NRSSV5 - .01); } else { FSensor5 = Sensor5; } if (Sensor6 >= 1) { FSensor6 = (NRSSV6 - .01); } else { FSensor6 = Sensor6; } if (Sensor7 >= 1) { FSensor7 = (NRSSV7 - .01); } else { FSensor7 = Sensor7; } if (Sensor8 >= 1) { FSensor8 = (NRSSV8 - .01); } else { FSensor8 = Sensor8; } if (Sensor9 >= 1) { FSensor9 = (NRSSV9 - .01); } else { FSensor9 = Sensor9; } if (Sensor10 >= 1) { FSensor10 = (NRSSV10 - .01); } else { FSensor10 = Sensor10; } //Serial1.println("NRSSV1"); //Serial1.println(NRSSV1); //Serial1.println("Sensor1"); //Serial1.println(Sensor1); RI1 = (NRSSV1 / FSensor1); //Serial1.println("RI1"); //Serial1.println(RI1); RI2 = (NRSSV2 / FSensor2); RI3 = (NRSSV3 / FSensor3); RI4 = (NRSSV4 / FSensor4); RI5 = (NRSSV5 / FSensor5); RI6 = (NRSSV6 / FSensor6); RI7 = (NRSSV7 / FSensor7); RI8 = (NRSSV8 / FSensor8); RI9 = (NRSSV9 / FSensor9); RI10 = (NRSSV10 / FSensor10); INSEY1 = (Sensor1 / DAE); //Serial1.println("INSEY1"); //Serial1.println(INSEY1); INSEY2 = (FSensor2 / DAE); INSEY3 = (FSensor3 / DAE); INSEY4 = (FSensor4 / DAE); INSEY5 = (FSensor5 / DAE); INSEY6 = (FSensor6 / DAE); INSEY7 = (FSensor7 / DAE); INSEY8 = (FSensor8 / DAE); INSEY9 = (FSensor9 / DAE); INSEY10 = (FSensor10 / DAE); YP0_1 = 413.46 * (pow(2.7182818284590452353602874713527, (104.98 * INSEY1))); //Serial1.println("YP0_1"); //Serial1.println(YP0_1); YP0_2 = 413.46 * (pow(2.7182818284590452353602874713527 , (104.98 * INSEY2))); YP0_3 = 413.46 * (pow(2.7182818284590452353602874713527 , (104.98 * INSEY3))); YP0_4 = 413.46 * (pow(2.7182818284590452353602874713527 , (104.98 * INSEY4))); YP0_5 = 413.46 * (pow(2.7182818284590452353602874713527 , (104.98 * INSEY5))); YP0_6 = 413.46 * (pow(2.7182818284590452353602874713527 , (104.98 * INSEY6))); YP0_7 = 413.46 * (pow(2.7182818284590452353602874713527 , (104.98 * INSEY7))); YP0_8 = 413.46 * (pow(2.7182818284590452353602874713527 , (104.98 * INSEY8))); YP0_9 = 413.46 * (pow(2.7182818284590452353602874713527 , (104.98 * INSEY9))); YP0_10 = 413.46 * (pow(2.7182818284590452353602874713527 , (104.98 * INSEY10))); NRATE1 = ((((YP0_1 * RI1) - YP0_1) * PercentN) / NUE); //This is the pounds of N required per acre Serial1.println("NRATE1"); Serial1.println(NRATE1); NRATE2 = ((((YP0_2 * RI2) - YP0_2) * PercentN) / NUE); NRATE3 = ((((YP0_3 * RI3) - YP0_3) * PercentN) / NUE); NRATE4 = ((((YP0_4 * RI4) - YP0_4) * PercentN) / NUE); NRATE5 = ((((YP0_5 * RI5) - YP0_5) * PercentN) / NUE); NRATE6 = ((((YP0_6 * RI6) - YP0_6) * PercentN) / NUE); NRATE7 = ((((YP0_7 * RI7) - YP0_7) * PercentN) / NUE); NRATE8 = ((((YP0_8 * RI8) - YP0_8) * PercentN) / NUE); NRATE9 = ((((YP0_9 * RI9) - YP0_9) * PercentN) / NUE); NRATE10 = ((((YP0_10 * RI10) - YP0_10) * PercentN) / NUE); double TotalNRate; TotalNRate = (NRATE1 + NRATE2 + NRATE3 + NRATE4 + NRATE5 + NRATE6 + NRATE7 + NRATE8 + NRATE9 + NRATE10); rate1GPA = (NRATE1 / 2.63); //RNRate is the gallons of 25S needed per acre Serial1.println("rate1GPA"); Serial1.println(rate1GPA); rate2GPA = (NRATE2 / 2.63); rate3GPA = (NRATE3 / 2.63); rate4GPA = (NRATE4 / 2.63); rate5GPA = (NRATE5 / 2.63); rate6GPA = (NRATE6 / 2.63); rate7GPA = (NRATE7 / 2.63); rate8GPA = (NRATE8 / 2.63); rate9GPA = (NRATE9 / 2.63); rate10GPA = (NRATE10 / 2.63); rate1GPM = ((rate1GPA) * (Speed) * (width1) * (.0166667) / 43560); //convert GPA to GPM for the actual application, make sure width and acres are in feet for the conversion to work Serial1.println("rate1GPM"); Serial1.println(rate1GPM); rate2GPM = ((rate2GPA) * (Speed) * (width1) * (.0166667) / 43560); rate3GPM = ((rate3GPA) * (Speed) * (width1) * (.0166667) / 43560); rate4GPM = ((rate4GPA) * (Speed) * (width1) * (.0166667) / 43560); rate5GPM = ((rate5GPA) * (Speed) * (width1) * (.0166667) / 43560); rate6GPM = ((rate6GPA) * (Speed) * (width1) * (.0166667) / 43560); rate7GPM = ((rate7GPA) * (Speed) * (width1) * (.0166667) / 43560); rate8GPM = ((rate8GPA) * (Speed) * (width1) * (.0166667) / 43560); rate9GPM = ((rate9GPA) * (Speed) * (width1) * (.0166667) / 43560); rate10GPM = ((rate10GPA) * (Speed) * (width2) * (.0166667) / 43560); //requiredRate = rate1 + rate3 + rate5 + rate7 + rate9; //requiredRateGPM = rate1GPM + rate2GPM + rate3GPM + rate4GPM + rate5GPM + rate6GPM + rate7GPM + rate8GPM + rate9GPM + rate10GPM; //MAXNRATE = (RNRATE1+RNRATE2+RNRATE3+RNRATE4+RNRATE5+RNRATE6+RNRATE7+RNRATE8+RNRATE9+RNRATE10); //add all of the rates together to set the mainline flow rate realRate1 = (rate1GPM * 63.0901964); //(rate1GPA / 43560) * (Speed) * (1 / 60) * (width1) //convert rates from Gal/Min to ml/Sec Serial1.println("realRate1"); Serial1.println(realRate1); realRate2 = (rate2GPM * 63.0901964); realRate3 = (rate3GPM * 63.0901964); realRate4 = (rate4GPM * 63.0901964); realRate5 = (rate5GPM * 63.0901964); realRate6 = (rate6GPM * 63.0901964); realRate7 = (rate7GPM * 63.0901964); realRate8 = (rate8GPM * 63.0901964); realRate9 = (rate9GPM * 63.0901964); realRate10 = (rate10GPM * 63.0901964); if ((realRate1 >= 0) && (realRate1 < 3)) { rate1 = 1.5; } if ((realRate1 > 3) && (realRate1 < 6)) { rate1 = 4.5; } if ((realRate1 > 6) && (realRate1 < 9)) { rate1 = 7.5; } if ((realRate1 > 9) && (realRate1 < 12)) { rate1 = 10.5; } if ((realRate1 >= 12)) { rate1 = 13.5; } if ((realRate2 >= 0) && (realRate2 < 3)) { rate2 = 1.5; } if ((realRate2 > 3) && (realRate2 < 6)) { rate2 = 4.5; } if ((realRate2 > 6) && (realRate2 < 9)) { rate2 = 7.5; } if ((realRate2 > 9) && (realRate2 < 12)) { rate2 = 10.5; } if ((realRate2 >= 12)) { rate2 = 13.5; } if ((realRate3 > 0) && (realRate3 < 3)) { rate3 = 1.5; } if ((realRate3 > 3) && (realRate3 < 6)) { rate3 = 4.5; } if ((realRate3 > 6) && (realRate3 < 9)) { rate3 = 7.5; } if ((realRate3 > 9) && (realRate3 < 12)) { rate3 = 10.5; } if ((realRate3 >= 12)) { rate3 = 13.5; } if ((realRate4 >= 0) && (realRate4 < 3)) { rate4 = 1.5; } if ((realRate4 > 3) && (realRate4 < 6)) { rate4 = 4.5; } if ((realRate4 > 6) && (realRate4 < 9)) { rate4 = 7.5; } if ((realRate4 > 9) && (realRate4 < 12)) { rate4 = 10.5; } if ((realRate4 >= 12)) { rate4 = 13.5; } if ((realRate5 >= 0) && (realRate5 < 3)) { rate5 = 1.5; } if ((realRate5 > 3) && (realRate5 < 6)) { rate5 = 4.5; } if ((realRate5 > 6) && (realRate5 < 9)) { rate5 = 7.5; } if ((realRate5 > 9) && (realRate5 < 12)) { rate5 = 10.5; } if ((realRate5 >= 12)) { rate5 = 13.5; } if ((realRate6 >= 0) && (realRate6 < 3)) { rate6 = 1.5; } if ((realRate6 > 3) && (realRate6 < 6)) { rate6 = 4.5; } if ((realRate6 > 6) && (realRate6 < 9)) { rate6 = 7.5; } if ((realRate6 > 9) && (realRate6 < 12)) { rate6 = 10.5; } if ((realRate6 >= 12)) { rate6 = 13.5; } if ((realRate7 >= 0) && (realRate7 < 3)) { rate7 = 1.5; } if ((realRate7 > 3) && (realRate7 < 6)) { rate7 = 4.5; } if ((realRate7 > 6) && (realRate7 < 9)) { rate7 = 7.5; } if ((realRate7 > 9) && (realRate7 < 12)) { rate7 = 10.5; } if ((realRate7 >= 12)) { rate7 = 13.5; } if ((realRate8 >= 0) && (realRate8 < 3)) { rate8 = 1.5; } if ((realRate8 > 3) && (realRate8 < 6)) { rate8 = 4.5; } if ((realRate8 > 6) && (realRate8 < 9)) { rate8 = 7.5; } if ((realRate8 > 9) && (realRate8 < 12)) { rate8 = 10.5; } if ((realRate8 >= 12)) { rate8 = 13.5; } if ((realRate9 >= 0) && (realRate9 < 3)) { rate9 = 1.5; } if ((realRate9 > 3) && (realRate9 < 6)) { rate9 = 4.5; } if ((realRate9 > 6) && (realRate9 < 9)) { rate9 = 7.5; } if ((realRate9 > 9) && (realRate9 < 12)) { rate9 = 10.5; } if ((realRate9 >= 12)) { rate9 = 13.5; } if ((realRate10 >= 0) && (realRate10 < 3)) { rate10 = 1.5; } if ((realRate10 > 3) && (realRate10 < 6)) { rate10 = 4.5; } if ((realRate10 > 6) && (realRate10 < 9)) { rate10 = 7.5; } if ((realRate10 > 9) && (realRate10 < 12)) { rate10 = 10.5; } if ((realRate10 >= 12)) { rate10 = 13.5; } requiredRate = rate1 + rate2 + rate3 + rate4 + rate5 + rate6 + rate7 + rate8 + rate9 + rate10; requiredRateGPM = (requiredRate / 63.0901964); Serial1.println("Required Rate GPM"); Serial1.println(requiredRateGPM); saveData(); delay(10); dataString = "LB/N/acre"; dataString += ","; dataString += NRATE1; dataString += ","; dataString += NRATE2; dataString += ","; dataString += NRATE3; dataString += ","; dataString += NRATE4; dataString += ","; dataString += NRATE5; dataString += ","; dataString += NRATE6; dataString += ","; dataString += NRATE7; dataString += ","; dataString += NRATE8; dataString += ","; dataString += NRATE9; dataString += ","; dataString += NRATE10; dataString += ","; dataString += TotalNRate; dataString += ","; saveData(); delay(10); dataString += "real ml/Sec"; dataString += ","; dataString += realRate1; dataString += ","; dataString += realRate2; dataString += ","; dataString += realRate3; dataString += ","; dataString += realRate4; dataString += ","; dataString += realRate5; dataString += ","; dataString += realRate6; dataString += ","; dataString += realRate7; dataString += ","; dataString += realRate8; dataString += ","; dataString += realRate9; dataString += ","; dataString += realRate10; dataString += ","; saveData(); delay(10); dataString += "class ml/Sec"; dataString += ","; dataString += rate1; dataString += ","; dataString += rate2; dataString += ","; dataString += rate3; dataString += ","; dataString += rate4; dataString += ","; dataString += rate5; dataString += ","; dataString += rate6; dataString += ","; dataString += rate7; dataString += ","; dataString += rate8; dataString += ","; dataString += rate9; dataString += ","; dataString += rate10; dataString += ","; dataString += requiredRate; dataString += ","; } void getPressure() //loop routine runs over and over again forever { pressureValue = analogRead(pressureInput); //reads value from input pin and assigns to variable pressureValue = ((pressureValue - pressureZero) * pressuretransducermaxPSI) / (pressureMax - pressureZero); //conversion equation to convert analog reading to psi Serial1.print(pressureValue, 1); //prints value from previous line to serial Serial1.println("psi"); //prints label to serial }