Advertisement
siosin

UNO_serial

Sep 28th, 2020 (edited)
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 34.61 KB | None | 0 0
  1. /*
  2.  
  3. ElCheapo Arduino EC-PPM measurments and Nutrient Doser Script
  4.  
  5.  
  6.  
  7. This scrip uses a common USA two prong plug and a 1Kohm Resistor to measure the EC/PPM of a Aquaponics/Hydroponics Sytem.
  8.  
  9. Then It Increases the Nutrient content until the set point is reached
  10.  
  11. It Also Estimates the EC of the nutrient Source [For when you are using Urine/ unknown Nutrient EC]
  12.  
  13.  
  14.  
  15.  
  16.  
  17. 28/8/2015 Michael Ratcliffe Mike@MichaelRatcliffe.com
  18.  
  19.  
  20.  
  21.  
  22.  
  23. This program is free software: you can redistribute it and/or modify
  24.  
  25. it under the terms of the GNU General Public License as published by
  26.  
  27. the Free Software Foundation, either version 3 of the License, or
  28.  
  29. (at your option) any later version.
  30.  
  31.  
  32.  
  33.  
  34.  
  35. This program is distributed in the hope that it will be useful,
  36.  
  37. but WITHOUT ANY WARRANTY; without even the implied warranty of
  38.  
  39. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  40.  
  41. GNU General Public License for more details.
  42.  
  43.  
  44.  
  45.  
  46.  
  47. You should have received a copy of the GNU General Public License
  48.  
  49. along with this program. If not, see <http://www.gnu.org/licenses/>.
  50.  
  51.  
  52.  
  53. Parts:
  54.  
  55. -Arduino - Uno/Mega
  56.  
  57. -Standard American two prong plug
  58.  
  59. -1 kohm resistor
  60.  
  61. -DS18B20 Waterproof Temperature Sensor
  62.  
  63. -FluidPump [Smaller is better];
  64.  
  65.  
  66.  
  67. Limitations:
  68.  
  69. -Cell Constant [K] and ECSetpoint must be less than 5.0 or it will Mess with the way we save values in EEPROM
  70.  
  71. -A reset will change your set point and kell constant slightly, but not to a great extent
  72.  
  73. -EEPROM seems to survive a reflash, so changing values in the code will not change them in the flashed software. you will need to do it via the LCD
  74.  
  75.  
  76.  
  77. See www.MichaelRatcliffe.com/Projects for a Pinout and user guide or consult the Zip you got this code from
  78.  
  79. */
  80.  
  81. //************************** Libraries Needed To Compile The Script [See Read me In Download] ***************//
  82.  
  83. // Both below Library are custom ones [ SEE READ ME In Downloaded Zip If You Dont Know how To install] Use them or add a pull up resistor to the temp probe
  84.  
  85. #include <OneWire.h>
  86. #include <DallasTemperature.h>
  87. #include <LiquidCrystal.h> //Standard LCD Lbrary
  88. #include <EEPROM.h> //Standard EEPROM Library
  89.  
  90. //************************* User Defined Variables ******************************************************//
  91.  
  92. // Rememebr to ad .0 after any float definition or it will return to an initiger, ie 1.0 not 1
  93.  
  94. //********************** System Information *************************************//
  95.  
  96. float TankSize =10; //SystemVolume in Liters
  97. float PumpRate=0.; //Flow rate of dosing pump in L per min
  98. long DosingInterval =60; //How often you want to dose the tank in minutes, hour intervals will be fine for most systems
  99. long MixingTime =600; //The time for mixing of nutrients in minutes [I have a lot of water flow so 60 seonds is fine for me, if in doubt increase it to half a hour]
  100.  
  101. int Pump =2; //Pin Controlling relay for nutrient Pump
  102. int OFF =0;
  103. int ON=1;
  104.  
  105. //****************************** System EC Value *******************************//
  106.  
  107. //Changes for what plants you are growing, sun intensity and temperature
  108.  
  109. //###If you are using urine in a system and have not yet got a established Bacteria bed set this to ECSetpoint=0.7 for a week to let the bacteria become established##
  110.  
  111. float ECSetpoint =1.0; // How Strong you want the water system to be nutrient wise
  112.  
  113. //******************** Nut Tank EC *********************************************//
  114.  
  115. //the code will optimise this number after every dosing, so we are selecting the highest end and allowing the arduino to work the rest out its self
  116.  
  117. //You are using a nutrient that states the NPK and not a overpriced one that used the words "Boost" "flower" "Super" but hides the important NPK ratios?
  118.  
  119. //If not Save yourself a fortune and switch to a cheap one that is honest about its NPK
  120. //We need to put in a estimated start point for the controller to start with
  121. //For an estimate take the EC Estimate= (N*20) + (P*8.8) +(K*16)
  122.  
  123. float ECFluidEstimate =100.0; //if you dont know the value stick with 1000, it will sort itself out
  124.  
  125.  
  126. //***********************************EC Meter **********************************//
  127. //##################################################################################
  128. //----------- Do not Replace R1 with a resistor lower than 300 ohms ------------
  129. //##################################################################################
  130.  
  131. int R1= 1000; //The resitor we placed in voltage divider
  132. int Ra=25; //Resistance of Arduino Digital Pins
  133. //float Rp=0; //Resistance of figure 8 connector
  134. int ECPin= A1;
  135. int ECGround=A2;
  136. int ECPower =A4;
  137.  
  138. //************ Temp Probe Related *********************************************//
  139.  
  140. #define ONE_WIRE_BUS 13 // Data wire For Temp Probe is plugged into pin 10 on the Arduino
  141. const int TempProbePossitive =13; //Temp Probe power connected to pin 9
  142. const int TempProbeNegative=12; //Temp Probe Negative connected to pin 8
  143.  
  144. //************************* User Defined Variables ********************************************************//
  145.  
  146. float CalibrationEC=1.380; //EC value of Calibration solution is s/cm
  147.  
  148. //*********** Converting to ppm [Learn to use EC it is much better**************//
  149. // Hana [USA] PPMconverion: 0.5
  150. // Eutech [EU] PPMconversion: 0.64
  151. //Tranchen [Australia] PPMconversion: 0.7
  152. // Why didnt anyone standardise this?
  153.  
  154. float PPMconversion=0.5;
  155.  
  156. //********************** Cell Constant For Ec Measurements *********************//
  157. //Mine was around 2.9 , with plugs being a standard size they should all be the same
  158. //I Recommend Calibrating your probe but if that is not an option at this time the following cell constants [K] will give a good estimated readout:
  159. //EU plug: K= 1.76
  160. //US Plug K= 2.88
  161.  
  162. float K=2.88;
  163.  
  164. //*************Compensating for temperature ************************************//
  165. //The value below will change depending on what chemical solution we are measuring
  166. //0.019 is generaly considered the standard for plant nutrients [google "Temperature compensation EC" for more info
  167.  
  168. float TemperatureCoef = 0.02; //this changes depending on what chemical we are measuring
  169.  
  170. //***************************** END Of Recomended User Inputs *****************************************************************//
  171. //********************************************************//
  172.  
  173. // select the pins used on the LCD panel
  174.  
  175. LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  176.  
  177. // define some values used by the panel and buttons
  178.  
  179. int lcd_key = 0;
  180. int adc_key_in = 0;
  181. int button =0;
  182.  
  183. #define btnRIGHT 1
  184. #define btnUP 2
  185. #define btnDOWN 3
  186. #define btnLEFT 4
  187. #define btnSELECT 5
  188. #define btnNONE 6
  189.  
  190. int Screen =1;
  191.  
  192. OneWire oneWire(ONE_WIRE_BUS);// Setup a oneWire instance to communicate with any OneWire devices
  193. DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.
  194.  
  195. float Temperature=10;
  196. float EC=0;
  197. float EC25 =0;
  198. int ppm =0;
  199. float raw= 0;
  200. float Vin= 5;
  201. float Vdrop= 0;
  202. float Rc= 0;
  203. float PumpTime=0; //Variable for pumping duration
  204. long MixingInterval=0; //variable for when to check new EC
  205. float PostDocingEC=0;
  206. float PreDosingEC =0;
  207. long StartDosingMillis =0;
  208. int NutesAdded=0;
  209. long time=0;
  210.  
  211. //********************** Some Variables For Loging Min/Max Values ********************************//
  212.  
  213. float MinEC=100;
  214. float MaxEC=0;
  215. float MinT=100;
  216. float MaxT=0;
  217.  
  218. //************************** Just Some basic Definitions used for the Up Time LOgger ************//
  219.  
  220. long Day=0;
  221. int Hour =0;
  222. int Minute=0;
  223. int Second=0;
  224. int HighMillis=0;
  225. int Rollover=0;
  226.  
  227. //**************************Some Stuff For Calibration ******************************************//
  228.  
  229. float TemperatureFinish=0;
  230. float TemperatureStart=0;
  231. int i=0;
  232. float buffer=0;
  233. float Kt=0;
  234.  
  235. //***********************Some Stuff for Self Learning and Errors********************************//
  236.  
  237. float LastGoodEstimate= 0;
  238. float PumECRateStart=0;
  239. float PumECRate=0;
  240. int error=6; // 6 means no error
  241. long Doses=0;
  242. long LastRun=0;
  243. int ECHold=0;
  244.  
  245. //*********************** EPROM Stuff [So SetPoint and Cal Survive a reboot] ******************//
  246.  
  247. int value;
  248. int addresSetpoint=10;
  249. int addresCalibration=0;
  250.  
  251. //*********************************Setup - runs Once and sets pins etc ******************************************************//
  252.  
  253. void setup()
  254.  
  255. {
  256.  
  257. Serial.begin(9600);
  258. pinMode(TempProbeNegative , OUTPUT ); //seting ground pin as output for tmp probe
  259. digitalWrite(TempProbeNegative , LOW );//Seting it to ground so it can sink current
  260. pinMode(TempProbePossitive , OUTPUT );//ditto but for positive
  261. digitalWrite(TempProbePossitive , HIGH );
  262. pinMode(ECPin,INPUT);
  263. pinMode(ECPower,OUTPUT);//Setting pin for sourcing current
  264. pinMode(ECGround,OUTPUT);//setting pin for sinking current
  265. pinMode(Pump,OUTPUT);//setting pin for sinking current
  266. digitalWrite(Pump,OFF); //makes sure we are starting from a stop
  267. digitalWrite(ECGround,LOW);//We can leave the ground connected permanantly
  268. delay(100);// gives sensor time to settle
  269. sensors.begin();
  270.  
  271. //****************Converting to milli seconds********************//
  272.  
  273. DosingInterval =DosingInterval*60000; //Coveerting to milliseconds
  274. MixingTime =MixingTime*60000; // Converting to milliseconds
  275. MixingInterval=DosingInterval+MixingTime;
  276. PumpRate=PumpRate/60.0; //converting to L.Second-1
  277.  
  278.  
  279.  
  280. //***************Converting to MCU related units ****************//
  281.  
  282. PumECRate=ECFluidEstimate*(PumpRate/TankSize); // EC.Second-1
  283. PumECRate=PumECRate*2.0;//Just incase people overestimated some values
  284. LastGoodEstimate=PumECRate;
  285. PumECRateStart=PumECRate;
  286.  
  287. //************** Restart Protection Stuff ********************//
  288. //Setpoint
  289.  
  290. value = EEPROM.read(addresSetpoint);
  291. if (value <=254) ECSetpoint=value*0.02;
  292.  
  293. //Calibration
  294.  
  295. value = EEPROM.read(addresCalibration);
  296. if (value <=254) K=value*0.02;
  297.  
  298. R1=(R1+Ra); //Taking into acount Digital Pin Resitance
  299.  
  300. lcd.begin(16, 2); // start the library
  301. lcd.setCursor(0,0);
  302. delay(1000);
  303. lcd.print("Nutrient Doser");
  304. lcd.setCursor(0,1);
  305. delay(1000);
  306. lcd.print("Hydrobot ");
  307. lcd.setCursor(0,1);
  308. delay(1000);
  309. lcd.setCursor(0,1);
  310. lcd.print("MadLab ");
  311. delay(1000);
  312. lcd.setCursor(0,1);
  313. lcd.print("Hydrobot ");
  314. delay(1000);
  315. lcd.setCursor(0,1);
  316. lcd.print("MadLab ");
  317. delay(1000);
  318. lcd.setCursor(0,0);
  319. lcd.print("To Calibrate ");
  320. lcd.setCursor(0,1);
  321. lcd.print("Hold Select ");
  322. delay(3000);
  323. lcd.setCursor(0,0);
  324. lcd.print("To Navigate ");
  325. lcd.setCursor(0,1);
  326. lcd.print("Use Up-Down ");
  327. delay(3000);
  328.  
  329. GetEC(); //gets first reading for LCD and then resets max/min
  330. MinEC=100.0;
  331. MaxEC=0.0;
  332. MinT=100.0;
  333. MaxT=0.0;
  334.  
  335. };
  336.  
  337. //******************************************* End of Setup **********************************************************************//
  338.  
  339. //************************************* Main Loop - Runs Forever ***************************************************************//
  340.  
  341. //Moved Heavy Work To subroutines so you can call them from main loop without cluttering the main loop
  342.  
  343. //Dont Measure the EC more than once every five second "GetEC()" or you will get bad readings and wear your probe out
  344.  
  345. void loop()
  346. {
  347. //*********Takes care of millis rolover**************//
  348.  
  349. if(millis()<=5000){
  350. NutesAdded=0;
  351. digitalWrite(Pump,OFF);
  352. delay(5000);
  353. };
  354.  
  355. //*********Check if it is time to dose the system, we wont dose it if the probe is broken or if we are colse to the setppoint ********//
  356.  
  357. if( (button==1 || millis()%DosingInterval<=1000) && (error>=4 && EC25<=(ECSetpoint-0.1) && NutesAdded==0) ){
  358. NutrientAddition();
  359. NutesAdded=1;
  360. Doses++;
  361. };
  362.  
  363. //********This fine tunes for the perticular system **************//
  364.  
  365. if((millis()>=(PumpTime+MixingTime+StartDosingMillis)) && NutesAdded==1){
  366. EstimateEC(); // Goes to the script to estimate the nutrient source EC
  367. NutesAdded=0;
  368. };
  369.  
  370. //********** Runs the Function to estimate the EC of the hydroponics system **********//
  371.  
  372. if (millis()%5000<=1000 && ECHold==0){
  373. GetEC();
  374. ECHold=1;
  375. };
  376.  
  377. if (millis()%5000>=1000){
  378. ECHold=0;
  379. };
  380.  
  381. //**************** Turns the pump off at the end of the pumping time********************//
  382.  
  383. if (millis()>=StartDosingMillis+PumpTime){ //Still need to take care of millis rollover!?
  384. digitalWrite(Pump,OFF);
  385. };
  386.  
  387. read_LCD_buttons();
  388. Calibration();
  389. ChangeECSetpoint();
  390. Error();
  391. //PrintReadings(); // Cals Print routine [below main loop]
  392. komunikasi();
  393.  
  394. //************* Stopinf Funky Readings From unmixed solution**********//
  395.  
  396. if(NutesAdded==0) LogEC();
  397. delay(50);
  398.  
  399. }
  400.  
  401. //************************************** End Of Main Loop **********************************************************************//
  402.  
  403. //void main program
  404.  
  405. //void reques trigger
  406. void komunikasi()
  407. {
  408. //baca request dari MCU
  409. String minta = "";
  410. //baca reques dari MCU
  411. while(Serial.available()>0)
  412. {
  413. minta += char(Serial.read());
  414. }
  415. //buang spasi data
  416. minta.trim();
  417. //Uji variable minta
  418. if(minta == "Ya")
  419. {
  420. //kirim data
  421. kirimdata();
  422. }
  423. //kosongkan var minta
  424. minta = "";
  425. delay(1000);
  426. }
  427.  
  428. //void kirimdata
  429. void kirimdata()
  430. {
  431. //variable data kirim ke mcu
  432. String datakirim = String(ppm) + "#" + String(Temperature) + "#" + String(PumECRate);
  433. //kirim data ke MCU
  434. Serial.println(datakirim);
  435. }
  436. // End of void kirimdata
  437.  
  438.  
  439. //*******************************Turns on Pump To Dose System *********************************//
  440.  
  441. void NutrientAddition(){
  442.  
  443. PreDosingEC =EC25; //Makes note of the initial EC
  444. PumpTime=1000*((ECSetpoint-PreDosingEC)/PumECRate);
  445. StartDosingMillis=millis();
  446. digitalWrite(Pump,ON);
  447. };
  448.  
  449. //******************************** System Automatd Learning ************************************//
  450. //This Function optimises the dosing volume for the main tank volume and Strength of Nutrient tank
  451.  
  452. void EstimateEC(){
  453. PostDocingEC=EC25; //Makes Note of the EC at the end of the addition
  454.  
  455. //*********Rapidly change EC Estimation on startup************//
  456.  
  457. if(PostDocingEC>=(PreDosingEC+0.05)){
  458. PumECRate =(1000.0*((PostDocingEC-PreDosingEC)/PumpTime));
  459. LastGoodEstimate=PumECRate;
  460. }
  461.  
  462. else PumECRate=PumECRate/2.0;
  463. };
  464.  
  465. //************ This Loop Is called From Main Loop************************//
  466.  
  467. void GetEC(){
  468.  
  469. //*********Reading Temperature Of Solution *******************//
  470.  
  471. sensors.requestTemperatures();// Send the command to get temperatures
  472. Temperature=sensors.getTempCByIndex(0); //Stores Value in Variable
  473. raw= analogRead(ECPin);
  474.  
  475. //************Estimates Resistance of Liquid ****************//
  476.  
  477. digitalWrite(ECPower,HIGH);
  478.  
  479. //raw= analogRead(ECPin);
  480.  
  481. raw= analogRead(ECPin);// This is not a mistake, First reading will be low beause if charged a capacitor
  482. digitalWrite(ECPower,LOW);
  483.  
  484. //***************** Converts to EC **************************//
  485.  
  486. Vdrop= (Vin*raw)/1024.0;
  487. Rc=(Vdrop*R1)/(Vin-Vdrop);
  488. Rc=Rc-Ra;
  489. EC = 1000/(Rc*K);
  490. LogEC();
  491.  
  492. //*************Compensating For Temperaure********************//
  493.  
  494. EC25 = EC/ (1.0+ TemperatureCoef*(Temperature-25.0));
  495. ppm=(EC25)*(PPMconversion*1000);
  496. ;}
  497.  
  498. //***********This Loop Is called From Else Where- Prints to serial usefull info **************//
  499.  
  500. void PrintReadings(){
  501. Serial.print("EC: ");
  502. Serial.print(EC25);
  503. Serial.print(" Simens ");
  504. Serial.print(ppm);
  505. Serial.print(" ppm ");
  506. Serial.print(Temperature);
  507. Serial.print(" *C ");
  508. Serial.print("PumpRate EC/s: ");
  509. Serial.println( PumECRate);
  510.  
  511. //** First Screen Shows Temp and EC **//
  512.  
  513. if(Screen==1){
  514. lcd.setCursor(0,0);
  515. lcd.print("Hydrobot EC-PPM ");
  516. lcd.setCursor(0,1);
  517. lcd.print("EC: ");
  518. lcd.setCursor(3,1);
  519. lcd.print(EC25);
  520. lcd.setCursor(9,1);
  521. lcd.print(Temperature);
  522. lcd.print("'C");
  523. }
  524.  
  525. //** Second Screen Shows PPM **//
  526.  
  527. else if(Screen==2){
  528. lcd.setCursor(0,0);
  529. lcd.print("Arduino EC-PPM ");
  530. lcd.setCursor(0,1);
  531. lcd.print("PPM: ");
  532. lcd.setCursor(4,1);
  533. lcd.print(ppm);
  534. lcd.setCursor(9,1);
  535. lcd.print(Temperature);
  536. lcd.print("'C");
  537. }
  538.  
  539. //**Third Screen Shows Min and Max **//
  540.  
  541. else if(Screen==3){
  542. lcd.setCursor(0,0);
  543. lcd.print("Min: ");
  544. lcd.setCursor(4,0);
  545. lcd.print(MinEC);
  546. lcd.setCursor(9,0);
  547. lcd.print(MinT);
  548. lcd.print("'C");
  549. lcd.setCursor(0,1);
  550. lcd.print("Max: ");
  551. lcd.setCursor(4,1);
  552. lcd.print(MaxEC);
  553. lcd.setCursor(9,1);
  554. lcd.print(MaxT);
  555. lcd.print("'C");
  556. }
  557.  
  558. else if(Screen==4){
  559. lcd.setCursor(0,0);
  560. lcd.print("Uptime Counter: ");
  561. lcd.setCursor(0,1);
  562. lcd.print(" ");//Clearing LCD
  563. lcd.setCursor(0,1);
  564. lcd.print(Day);
  565. lcd.setCursor(3,1);
  566. lcd.print("Day");
  567. lcd.setCursor(8,1);
  568. lcd.print(Hour);
  569. lcd.setCursor(10,1);
  570. lcd.print(":");
  571. lcd.setCursor(11,1);
  572. lcd.print(Minute);
  573. lcd.setCursor(13,1);
  574. lcd.print(":");
  575. lcd.setCursor(14,1);
  576. lcd.print(Second);
  577. }
  578.  
  579. else if(Screen==5){
  580. lcd.setCursor(0,0);
  581. lcd.print("Factors ");
  582. lcd.setCursor(8,0);
  583. lcd.print("PPMC:");
  584. lcd.setCursor(13,0);
  585. lcd.print(PPMconversion);
  586. lcd.setCursor(0,1);
  587. lcd.print("K: ");
  588. lcd.setCursor(2,1);
  589. lcd.print(K);
  590. lcd.setCursor(9,1);
  591. lcd.print("a:");
  592. lcd.setCursor(11,1);
  593. lcd.print(TemperatureCoef);
  594. }
  595.  
  596. else if(Screen==6){
  597. lcd.setCursor(0,0);
  598. lcd.print("EC.Sec-1: ");
  599. lcd.setCursor(10,0);
  600. lcd.print(PumECRate,5);
  601. lcd.setCursor(0,1);
  602. lcd.print("Doses: ");
  603. lcd.setCursor(10,1);
  604. lcd.print(Doses);
  605. }
  606.  
  607. else if(Screen==7){
  608. lcd.setCursor(0,0);
  609. lcd.print("EC Setpoint: ");
  610. lcd.setCursor(12,0);
  611. lcd.print(ECSetpoint,3);
  612. lcd.setCursor(0,1);
  613. lcd.print("Hold Select Change ");
  614. }
  615.  
  616. if((millis()%6000)<=3000){
  617.  
  618.  
  619.  
  620. //************************* Printing any errors we have ***********//
  621.  
  622. if (error==1) {lcd.setCursor(0,0);
  623. lcd.print("Error: ");
  624. lcd.setCursor(8,0);
  625. lcd.print(error);
  626. lcd.setCursor(0,1);
  627. lcd.print("Probe Problem "); }
  628.  
  629. else if (error==2) {lcd.setCursor(0,0);
  630. lcd.print("Error: ");
  631. lcd.setCursor(8,0);
  632. lcd.print(error);
  633. lcd.setCursor(0,1);
  634. lcd.print("Large Overshoot "); }
  635.  
  636. else if (error==3) {lcd.setCursor(0,0);
  637. lcd.print("Error: ");
  638. lcd.setCursor(8,0);
  639. lcd.print(error);
  640. lcd.setCursor(0,1);
  641. lcd.print("Temp Problem "); }
  642.  
  643. else if (error==4) {lcd.setCursor(0,0);
  644. lcd.print("Error: ");
  645. lcd.setCursor(8,0);
  646. lcd.print(error);
  647. lcd.setCursor(0,1);
  648. lcd.print("Pump Problem "); }
  649.  
  650. else if (error==5 ) {lcd.setCursor(0,0);
  651. lcd.print("Error: ");
  652. lcd.setCursor(8,0);
  653. lcd.print(error);
  654. lcd.setCursor(0,1);
  655. lcd.print("System Learning "); }
  656.  
  657. else;
  658.  
  659. };
  660.  
  661. /*
  662. //********** Usued for Debugging ************
  663. Serial.print("Vdrop: ");
  664. Serial.println(Vdrop);
  665. Serial.print("Rc: ");
  666. Serial.println(Rc);
  667. Serial.print(EC);
  668. Serial.println("Siemens");
  669. //********** end of Debugging Prints *********
  670.  
  671. */
  672. };
  673.  
  674. void read_LCD_buttons(){
  675. adc_key_in = analogRead(0); // read the value from the sensor
  676.  
  677. // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  678.  
  679. // we add approx 50 to those values and check to see if we are close
  680.  
  681. if (adc_key_in > 1000) button =0;
  682. else if (adc_key_in < 60) button =1;
  683. else if (adc_key_in < 200) button =2;
  684. else if (adc_key_in < 400) button =3;
  685. else if (adc_key_in < 600) button =4;
  686. else if (adc_key_in < 800) button =5;
  687.  
  688. if(button==2){
  689. Screen++;
  690. }
  691.  
  692. else if (button==3){
  693. Screen--;
  694. };
  695.  
  696. if (Screen>=7) Screen=7;
  697. if(Screen<=1) Screen=1;
  698. };
  699. //******************************* LOGS Min/MAX Values and Uptime Counter*******************************//
  700.  
  701. void LogEC(){
  702. //**********So We dont Get First Few Readings**********//
  703.  
  704. if( Doses==5){
  705. MinEC=100.0;
  706. MaxEC=0.0;
  707. MinT=100.0;
  708. MaxT=0.0;
  709. };
  710.  
  711. if(EC25>=MaxEC) MaxEC=EC25;
  712. if(EC25<=MinEC) MinEC=EC25;
  713. if(Temperature>=MaxT) MaxT=Temperature;
  714. if(Temperature<=MinT) MinT=Temperature;
  715.  
  716.  
  717. //** Making Note of an expected rollover *****//
  718.  
  719. if(millis()>=3000000000){
  720. HighMillis=1;
  721. }
  722.  
  723. //** Making note of actual rollover **//
  724.  
  725. if(millis()<=100000&&HighMillis==1){
  726. Rollover++;
  727. HighMillis=0;
  728. }
  729.  
  730. long secsUp = millis()/1000;
  731. Second = secsUp%60;
  732. Minute = (secsUp/60)%60;
  733. Hour = (secsUp/(60*60))%24;
  734. Day = (Rollover*50)+(secsUp/(60*60*24)); //First portion takes care of a rollover [around 50 days]
  735. };
  736.  
  737. //******************************* Checks if Select button is held down and enters Calibration routine if it is ************************************//
  738.  
  739. void Calibration(){
  740.  
  741. if(Screen!=5) return;
  742. if(button!=5) return;
  743. else delay(1000);
  744. read_LCD_buttons();
  745. if(button!=5) return;
  746.  
  747. while(1){
  748. read_LCD_buttons();
  749. lcd.setCursor(0,0);
  750. lcd.print("Set Calibration EC ");
  751. lcd.setCursor(0,1);
  752. lcd.print("EC: ");
  753. lcd.setCursor(3,1);
  754. lcd.print(CalibrationEC);
  755.  
  756. if (button==2) CalibrationEC=CalibrationEC+0.01 ;
  757. if(button==3) CalibrationEC=CalibrationEC-0.01;
  758. if(button==1) break;
  759. delay(100);
  760. };
  761.  
  762. lcd.setCursor(0,0);
  763. lcd.print("Calibrating ");
  764. lcd.setCursor(0,1);
  765. lcd.print("EC: ");
  766. lcd.setCursor(3,1);
  767. lcd.print(CalibrationEC);
  768.  
  769. i=1;
  770. buffer=0;
  771. sensors.requestTemperatures();// Send the command to get temperatures
  772. TemperatureStart=sensors.getTempCByIndex(0); //Stores Value in Variable
  773.  
  774. //************Estimates Resistance of Liquid ****************//
  775.  
  776. while(i<=10){
  777. digitalWrite(ECPower,HIGH);
  778. raw= analogRead(ECPin);
  779. digitalWrite(ECPower,LOW);
  780. buffer=buffer+raw;
  781. i++;
  782. delay(5000);
  783. };
  784.  
  785. raw=(buffer/10.0);
  786. sensors.requestTemperatures();// Send the command to get temperatures
  787. TemperatureFinish=sensors.getTempCByIndex(0); //Stores Value in Variable
  788.  
  789. //*************Compensating For Temperaure********************//
  790.  
  791. EC =CalibrationEC*(1+(TemperatureCoef*(TemperatureFinish-25.0))) ;
  792.  
  793. //***************** Calculates R relating to Calibration fluid **************************//
  794.  
  795. Vdrop= (((Vin)*(raw))/1024.0);
  796. Rc=(Vdrop*R1)/(Vin-Vdrop);
  797. Rc=Rc-Ra; //Taking into account pin resistance
  798. Kt= 1000/(Rc*EC);
  799.  
  800. if (TemperatureStart==TemperatureFinish ){
  801. Serial.println(" Results are Trustworthy");
  802. Serial.print("Calibration Fluid EC: ");
  803. Serial.print(CalibrationEC);
  804. Serial.print(" S "); //add units here
  805. Serial.print("Cell Constant K");
  806. Serial.print(K);
  807.  
  808. lcd.setCursor(0,0);
  809. lcd.print("GoodResults ");
  810. lcd.setCursor(0,1);
  811. lcd.print("EC: ");
  812. lcd.setCursor(3,1);
  813. lcd.print(CalibrationEC);
  814. lcd.setCursor(9,1);
  815. lcd.print("K:");
  816. lcd.setCursor(11,1);
  817. lcd.print(Kt);
  818.  
  819. while (1) { // wee need to keep this function running until user opts out with return function
  820. read_LCD_buttons();
  821. if(button==4) return; //exits the loop without saving becauser user asked so
  822. if (button==5){
  823. K=Kt; //saving the new cell constant
  824.  
  825. //******8*Saving the new value to EEprom**********//
  826.  
  827. value=K/0.02;
  828. EEPROM.write(addresCalibration, value);
  829.  
  830. lcd.setCursor(0,0);
  831. lcd.print("Saved Calibration ");
  832. lcd.setCursor(0,1);
  833. lcd.print("K: ");
  834. lcd.setCursor(3,1);
  835. lcd.print(Kt);
  836. delay(2000);
  837. return;
  838. }
  839.  
  840. if(millis()%4000>=2000){
  841. lcd.setCursor(0,0);
  842. lcd.print("GoodResults ");
  843. lcd.setCursor(0,1);
  844. lcd.print("EC: ");
  845. lcd.setCursor(2,1);
  846. lcd.print(CalibrationEC);
  847. lcd.setCursor(9,1);
  848. lcd.print("K:");
  849. lcd.setCursor(11,1);
  850. lcd.print(Kt);
  851. }
  852.  
  853. else{
  854.  
  855. lcd.setCursor(0,0);
  856. lcd.print("Select To Save ");
  857. lcd.setCursor(0,1);
  858. lcd.print("Down to Exit ");
  859. };
  860. }
  861. }
  862. else{
  863. Serial.println(" Error Wait For Temperature To settle");
  864.  
  865. while (1) {
  866. read_LCD_buttons();
  867. if(button==2) Calibration();
  868. if(button==3) return;
  869. lcd.setCursor(0,0);
  870. lcd.print("Bad Results ");
  871. lcd.setCursor(0,1);
  872. lcd.print("Press DWN Exit ");
  873. }
  874. }
  875.  
  876. };
  877.  
  878. //**************************************** End OF CALIBRATION ROUTINE ******************************//
  879.  
  880.  
  881.  
  882. //**************************************Start OF Function To Change EC Setpoint*********************//
  883.  
  884.  
  885.  
  886. void ChangeECSetpoint(){
  887.  
  888. if(Screen!=7) return;
  889.  
  890. if(button!=5) return;
  891.  
  892.  
  893.  
  894. else delay(1000);
  895.  
  896. read_LCD_buttons();
  897.  
  898. if(button!=5) return;
  899.  
  900.  
  901.  
  902. while(1){
  903.  
  904. read_LCD_buttons();
  905.  
  906. lcd.setCursor(0,0);
  907.  
  908. lcd.print("Set EC SetPoint ");
  909.  
  910. lcd.setCursor(0,1);
  911.  
  912. lcd.print("R:exit EC: ");
  913.  
  914. lcd.setCursor(11,1);
  915.  
  916. lcd.print(ECSetpoint);
  917.  
  918.  
  919.  
  920. if (button==2) ECSetpoint=ECSetpoint+0.01 ;
  921.  
  922. if(button==3) ECSetpoint=ECSetpoint-0.01;
  923.  
  924. if(button==1) {
  925.  
  926. value=ECSetpoint/0.02;
  927.  
  928. EEPROM.write(addresSetpoint, value);
  929.  
  930. break;
  931.  
  932. }
  933.  
  934. delay(100);
  935.  
  936. };
  937.  
  938.  
  939.  
  940. };
  941.  
  942.  
  943.  
  944. //*******************************End OF Change EC Setpoint *********************************************//
  945.  
  946.  
  947.  
  948. //*********************************Function to Check for any errors**************************************//
  949.  
  950. void Error(){
  951.  
  952. error=6; //For Some Reason the Errors are not refreshing like they shoud, this fixes it
  953.  
  954. //*********Checking if the Probe is in the Solution********//
  955.  
  956. if(EC25<=0.05){
  957.  
  958. Serial.println("Probe Problem: Check it is in the liquid and not shorted ");
  959.  
  960. error=1;
  961.  
  962.  
  963.  
  964. }
  965.  
  966.  
  967.  
  968. //***********Checking if we seriosly overshot the setpoint**//
  969.  
  970. else if((EC25>=(ECSetpoint*1.3))&& NutesAdded==0){
  971.  
  972. Serial.println("Dosing Problem: We overshot the setpoint, Will attempt to fix its self ");
  973.  
  974. error=2;
  975.  
  976.  
  977.  
  978. }
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986. //******** Checking Temp Probe is In range ****************//
  987.  
  988. else if((Temperature>=50.0) || (Temperature<=0.5)){
  989.  
  990. Serial.println("Temperature Problem: Check Wiring [Also Check Probe has pull up] ");
  991.  
  992. error=3;
  993.  
  994. }
  995.  
  996.  
  997.  
  998. //****** Checking Dosing Pump Is working******************//
  999.  
  1000. else if( (PostDocingEC<=(PreDosingEC+0.05) ) && (NutesAdded==0 && EC25<=ECSetpoint-0.2) ){
  1001.  
  1002. Serial.println("Dosing Problem: Check Nute Tank is full and pump is not broken ");
  1003.  
  1004.  
  1005.  
  1006. if(Doses<=10){
  1007.  
  1008. //Still Geting a good estimate for the EC
  1009.  
  1010. //error=5;
  1011.  
  1012.  
  1013.  
  1014. };
  1015.  
  1016. if(Doses>=11) {
  1017.  
  1018. //Proberbly a pump problem
  1019.  
  1020. error=4;
  1021.  
  1022. };
  1023.  
  1024. }
  1025.  
  1026. else error=6;
  1027.  
  1028.  
  1029.  
  1030. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement