ECE595 Hydroponics water balancing system (Project 2)

Dependencies:   mbed phread TextLCD

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /**     ECE595 Project 2: IoT Hydroponics
00002  **         ##Complete Firmware##
00003 **/
00004 /* mbed Microcontroller Library
00005  * Copyright (c) 2018 ARM Limited
00006  * SPDX-License-Identifier: Apache-2.0
00007  */
00008 
00009 #include "mbed.h"
00010 #include "phread.h"
00011 #include "PwmOut.h"
00012 #include "TextLCD.h"
00013 #include <string>
00014 #include <sstream>
00015 #include <iomanip>
00016 
00017 Serial HC06(PTC15, PTC14);  //Create serial object for the HC06 to be read from/written to
00018 Serial pc(USBTX,USBRX);     //Create serial object for the COM port to interface with a terminal application
00019 Ticker timeKeep;            //Create the time keeping interrupt. More information below in its definition
00020 
00021 //**    Servo Initialization
00022 PwmOut smoto(PTA1);
00023 DigitalOut led1(LED1);
00024 DigitalOut phPump1(D0);
00025 DigitalOut phPump2(D1);
00026 PHread sensor(A0);
00027 //Serial pc(USBTX, USBRX);
00028 
00029 //**    LCD pin intialization
00030     TextLCD lcd(PTC12, PTC4, PTD0, PTD2, PTD3, PTD1); // rs, e, d4-d7
00031 
00032 
00033 //**    Global ints to keep/track time 
00034 int cthours     = 0;    //Current time integers
00035 int ctminutes   = 0;    //These are incremented using a ticker component to keep
00036 int ctseconds   = 0;    //real time.
00037 
00038 float phMeas = 7.0;
00039 int gallon_cnt  = 5;    //User set: gallons currently in the tank    //tohours
00040 
00041 int min_cnt     = 0;    //Integer tracking the amount of time the pump is running
00042 
00043 char buffer[10];        //buffer for the serial comms between BT module and board, sent from mobile app to BT
00044 char *initarray[3];     //array for inital storage of timer info
00045 
00046 //**    Delimiter section for parsing data
00047 char sdelim[] = " ";    //seperation delimiter
00048 char cdelim[] = "c";    //current time command
00049 char gdelim[] = "g";    //Gallon Measurement Sent from the App
00050 
00051 bool pumpIt = false;
00052 
00053 std::string phOut;
00054 std::string timeOut;
00055 
00056 std::stringstream phStream;
00057 std::stringstream timeStream;
00058 
00059 //**    prereference functions
00060 void timekeep(void);
00061 void hcRxCallback(void);
00062 float ph_measurement(void);
00063 void pumpOn(void);
00064 void pumpOff(void);
00065 void printTime(void);
00066 
00067 //**    main function
00068 int main()
00069 {
00070     //*Baud rate init
00071     HC06.baud(9600);
00072     pc.baud(9600);
00073     
00074     //*interupt init
00075     timeKeep.attach(&timekeep, 0.999);
00076     HC06.attach(&hcRxCallback, Serial::RxIrq);
00077 
00078     //*infinite loop
00079     while(1) {
00080         if(pumpIt){                 //if pump has not been run this hour
00081             if(phMeas > 7.5){       //run either pump for a second if needed
00082                 phPump1.write(1);
00083                 wait(1);
00084                 phPump1 = 0;
00085             }
00086             else if(phMeas < 6.5){
00087                 phPump2 = 1;
00088                 wait(1);
00089                 phPump2 = 0;
00090             }
00091             else{}
00092             pumpIt = false;         //stop pumps from running for another hour
00093         }
00094     }
00095 }
00096 
00097 //**    Timekeeping function. This function is triggered every 0.999 seconds as an interrupt
00098 void timekeep()
00099 {
00100 
00101     ctseconds += 1;             //Increment the seconds and compare to 60
00102     if (ctseconds >= 60) {
00103         ctminutes += 1;
00104         ctseconds  = 0;
00105         
00106         if(min_cnt == 1)        //if the minute counter was just reset, turn on the pump
00107             pumpOn();
00108         else if(min_cnt == 16){ //after 15 minutes, turn the pump off
00109             pumpOff();
00110             min_cnt = 0;        //stop minute counter
00111         }
00112         else{};                 //empty else loop
00113         
00114         if(min_cnt % 2){                //on odd minutes, run this code
00115             phMeas = ph_measurement();  //read and set measurements
00116             printTime();                //set time
00117             lcd.printf("%s\n%s", phOut, timeOut);   //send ph and time to LCD
00118         }
00119         
00120         
00121         if(min_cnt){                    //if minute count is not 0, increment
00122             min_cnt++;    
00123         }
00124     }
00125     if (ctminutes >= 60) {      //compare minutes to 60
00126         cthours  += 1;
00127         ctminutes = 0;
00128         min_cnt = 1;            //reset the minute counter
00129         pumpIt = true;          //reset the boolean allowing the pumps to run
00130     }
00131     if (cthours >= 24) {        //compare hours to 24
00132         cthours = 0;
00133     }
00134     
00135     pc.printf("time: %d : %d : %d\n\n",cthours,ctminutes,ctseconds);
00136     return;
00137 }
00138 
00139 /*   This the RX_IRQ. There are global variables altered within this function,
00140 **   therefore disabling IRQ will allow this to operate without any interruption
00141 **   ***Note*** this function will not exit and print unless the buffer has read
00142 **              into it 8 bits of data.
00143 **/
00144 void hcRxCallback()
00145 {
00146     __disable_irq();
00147     HC06.gets(buffer, 8);
00148     pc.printf("recieved: %s\n",buffer);
00149 
00150     //*String Concatenation
00151     int i = 0;
00152     char *p = strtok(buffer, sdelim);       //Delimiter to parse the string into tokens
00153     while(p != NULL) {                      //loops while there is data to be read
00154         initarray[i++] = p;                 //Saves the value of P into the next slot of initarray
00155         p = strtok(NULL, sdelim);           //rinse and repeat
00156     }
00157     /**   For debug purposes, this will print the array elements for the
00158      **   user to review.
00159      **/
00160     for(i = 0; i<3; i++) {
00161         pc.printf("%s\n",initarray[i]);
00162     }
00163     //*String sorting
00164     if (!strcmp(initarray[0], cdelim)) {    //Compare the command character to the 'c' command
00165         cthours = atoi(initarray[1]);
00166         ctminutes = atoi(initarray[2]);
00167         pc.printf("new time: %d %d\n\n",cthours,ctminutes);
00168     }
00169     if (!strcmp(initarray[0], gdelim)) {    //Compare the command character to the 'g' command
00170         gallon_cnt = atoi(initarray[1]);
00171         pc.printf("Current Gallon Amount: %d\n\n",gallon_cnt);
00172     }
00173     
00174     __enable_irq();
00175     return;
00176 }
00177 
00178 //** Time Condition Begin, EveryHOur on the Hour, cycle a water pump for 15 min 
00179 //** and add ph up and/or ph downt to the mixture for desired ph level
00180 float ph_measurement()
00181 {
00182     float phMeasurement;
00183     //Check ph
00184     phMeasurement = sensor.get_pH();
00185     phStream << "pH : " << std::fixed << std::setprecision(2) << phMeasurement;
00186     phOut = phStream.str();
00187     return phMeasurement;
00188 }
00189 
00190 void printTime()
00191 {
00192     std::stringstream sHours;
00193     std::stringstream sMinutes;
00194     
00195     if(cthours == 24)
00196         sHours << "00";
00197     else if(cthours < 10)
00198         sHours << "0" << cthours;
00199     else
00200         sHours << cthours;
00201         
00202     if(ctminutes == 60)
00203         sMinutes << "00";
00204     else if(ctminutes < 10)
00205         sMinutes << "0" << ctminutes;
00206     else
00207         sMinutes << ctminutes;
00208         
00209     timeStream << "Time : " << sHours.str() << ":" << sMinutes.str();
00210     timeOut = timeStream.str();
00211 }
00212 
00213 void pumpOn()
00214 {
00215     smoto.pulsewidth_ms(2.0f);
00216 }
00217 
00218 void pumpOff()
00219 {
00220     smoto.pulsewidth_ms(0.0f);
00221 }
00222