
ECE595 Hydroponics water balancing system (Project 2)
Dependencies: mbed phread TextLCD
main.cpp
- Committer:
- thecreid1
- Date:
- 2020-05-06
- Revision:
- 0:e628a132c5fa
File content as of revision 0:e628a132c5fa:
/** ECE595 Project 2: IoT Hydroponics ** ##Complete Firmware## **/ /* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * SPDX-License-Identifier: Apache-2.0 */ #include "mbed.h" #include "phread.h" #include "PwmOut.h" #include "TextLCD.h" #include <string> #include <sstream> #include <iomanip> Serial HC06(PTC15, PTC14); //Create serial object for the HC06 to be read from/written to Serial pc(USBTX,USBRX); //Create serial object for the COM port to interface with a terminal application Ticker timeKeep; //Create the time keeping interrupt. More information below in its definition //** Servo Initialization PwmOut smoto(PTA1); DigitalOut led1(LED1); DigitalOut phPump1(D0); DigitalOut phPump2(D1); PHread sensor(A0); //Serial pc(USBTX, USBRX); //** LCD pin intialization TextLCD lcd(PTC12, PTC4, PTD0, PTD2, PTD3, PTD1); // rs, e, d4-d7 //** Global ints to keep/track time int cthours = 0; //Current time integers int ctminutes = 0; //These are incremented using a ticker component to keep int ctseconds = 0; //real time. float phMeas = 7.0; int gallon_cnt = 5; //User set: gallons currently in the tank //tohours int min_cnt = 0; //Integer tracking the amount of time the pump is running char buffer[10]; //buffer for the serial comms between BT module and board, sent from mobile app to BT char *initarray[3]; //array for inital storage of timer info //** Delimiter section for parsing data char sdelim[] = " "; //seperation delimiter char cdelim[] = "c"; //current time command char gdelim[] = "g"; //Gallon Measurement Sent from the App bool pumpIt = false; std::string phOut; std::string timeOut; std::stringstream phStream; std::stringstream timeStream; //** prereference functions void timekeep(void); void hcRxCallback(void); float ph_measurement(void); void pumpOn(void); void pumpOff(void); void printTime(void); //** main function int main() { //*Baud rate init HC06.baud(9600); pc.baud(9600); //*interupt init timeKeep.attach(&timekeep, 0.999); HC06.attach(&hcRxCallback, Serial::RxIrq); //*infinite loop while(1) { if(pumpIt){ //if pump has not been run this hour if(phMeas > 7.5){ //run either pump for a second if needed phPump1.write(1); wait(1); phPump1 = 0; } else if(phMeas < 6.5){ phPump2 = 1; wait(1); phPump2 = 0; } else{} pumpIt = false; //stop pumps from running for another hour } } } //** Timekeeping function. This function is triggered every 0.999 seconds as an interrupt void timekeep() { ctseconds += 1; //Increment the seconds and compare to 60 if (ctseconds >= 60) { ctminutes += 1; ctseconds = 0; if(min_cnt == 1) //if the minute counter was just reset, turn on the pump pumpOn(); else if(min_cnt == 16){ //after 15 minutes, turn the pump off pumpOff(); min_cnt = 0; //stop minute counter } else{}; //empty else loop if(min_cnt % 2){ //on odd minutes, run this code phMeas = ph_measurement(); //read and set measurements printTime(); //set time lcd.printf("%s\n%s", phOut, timeOut); //send ph and time to LCD } if(min_cnt){ //if minute count is not 0, increment min_cnt++; } } if (ctminutes >= 60) { //compare minutes to 60 cthours += 1; ctminutes = 0; min_cnt = 1; //reset the minute counter pumpIt = true; //reset the boolean allowing the pumps to run } if (cthours >= 24) { //compare hours to 24 cthours = 0; } pc.printf("time: %d : %d : %d\n\n",cthours,ctminutes,ctseconds); return; } /* This the RX_IRQ. There are global variables altered within this function, ** therefore disabling IRQ will allow this to operate without any interruption ** ***Note*** this function will not exit and print unless the buffer has read ** into it 8 bits of data. **/ void hcRxCallback() { __disable_irq(); HC06.gets(buffer, 8); pc.printf("recieved: %s\n",buffer); //*String Concatenation int i = 0; char *p = strtok(buffer, sdelim); //Delimiter to parse the string into tokens while(p != NULL) { //loops while there is data to be read initarray[i++] = p; //Saves the value of P into the next slot of initarray p = strtok(NULL, sdelim); //rinse and repeat } /** For debug purposes, this will print the array elements for the ** user to review. **/ for(i = 0; i<3; i++) { pc.printf("%s\n",initarray[i]); } //*String sorting if (!strcmp(initarray[0], cdelim)) { //Compare the command character to the 'c' command cthours = atoi(initarray[1]); ctminutes = atoi(initarray[2]); pc.printf("new time: %d %d\n\n",cthours,ctminutes); } if (!strcmp(initarray[0], gdelim)) { //Compare the command character to the 'g' command gallon_cnt = atoi(initarray[1]); pc.printf("Current Gallon Amount: %d\n\n",gallon_cnt); } __enable_irq(); return; } //** Time Condition Begin, EveryHOur on the Hour, cycle a water pump for 15 min //** and add ph up and/or ph downt to the mixture for desired ph level float ph_measurement() { float phMeasurement; //Check ph phMeasurement = sensor.get_pH(); phStream << "pH : " << std::fixed << std::setprecision(2) << phMeasurement; phOut = phStream.str(); return phMeasurement; } void printTime() { std::stringstream sHours; std::stringstream sMinutes; if(cthours == 24) sHours << "00"; else if(cthours < 10) sHours << "0" << cthours; else sHours << cthours; if(ctminutes == 60) sMinutes << "00"; else if(ctminutes < 10) sMinutes << "0" << ctminutes; else sMinutes << ctminutes; timeStream << "Time : " << sHours.str() << ":" << sMinutes.str(); timeOut = timeStream.str(); } void pumpOn() { smoto.pulsewidth_ms(2.0f); } void pumpOff() { smoto.pulsewidth_ms(0.0f); }