First draft to the functional spec
Dependencies: mbed Grove_LCD_RGB_Backlight DebounceIn
main.cpp
- Committer:
- bmcclure
- Date:
- 2019-10-08
- Revision:
- 3:07d400d50a96
- Parent:
- 2:829038a1352b
- Child:
- 4:d56051982cf5
File content as of revision 3:07d400d50a96:
#include "Grove_LCD_RGB_Backlight.h" #include "mbed.h" #include "DebounceIn.h" #define FOREVER (1) #define OUT_OFF (0) #define OUT_ON (1) #define IN_OFF (1) #define IN_ON (0) //input DebounceIn doorClosed(p5); //Check door status DebounceIn cycleStartBtt(p14); //cycle start button DebounceIn stopBtt(p15); //stop button //InterruptIn stopBtt(p15); //stop button //DigitalIn pot(p20); //output DigitalOut doorInterlock(p6); //Door interlock DigitalOut fanRelay(p7); //Fan control DigitalOut redRelay(p8); //Red light - DOOR OPENED DigitalOut yellowRelay(p11); //Yellow light - WASH IN PROGRESS DigitalOut greenRelay(p12); //Green light - DOOR UNLOCKED, TANK READY DigitalOut damperRelay(p13); //Damper solenoid control DigitalOut damperRelayAlt(p16); //Damper solenoid toggle control DigitalOut vfd(p17); //VFD Start relay Grove_LCD_RGB_Backlight rgbLCD(p9, p10); //Timer display bool cancelPending = false; bool damperIsOpen; bool simulateMode = false; bool doorHasOpened = false; bool cycleHasStarted = false; I2C i2c(p9, p10); //Serial pc(USBTX, USBRX); //extern "C" void mbed_reset(); // Function declarations void damperRotate(int damper); void fullLineItoA(int m, char* str); void countDown(int s); //countdown in sec void fullStop(); void debugMode(); int main() { //on power up status cycleStartBtt.mode(PullUp); cycleStartBtt.set_debounce_us(1000); cycleStartBtt.set_samples(100); wait(.1); doorClosed.mode(PullUp); doorClosed.set_debounce_us(1000); doorClosed.set_samples(100); wait(.1); stopBtt.mode(PullUp); stopBtt.set_debounce_us(1000); stopBtt.set_samples(100); wait(.5); rgbLCD.clear(); rgbLCD.setRGB(0x00, 0x66, 0xaa); //set the color rgbLCD.locate(0,0); if(cycleStartBtt == IN_ON && stopBtt == IN_ON) { simulateMode = true; rgbLCD.print("Simulating.... "); wait(5); } if(stopBtt == IN_ON) { debugMode(); } //Display startup countdown //Startin up and prep the tank rgbLCD.clear(); rgbLCD.locate(0,0); rgbLCD.print("Starting up... "); // Setup outputs vfd = OUT_OFF; doorInterlock = OUT_OFF; greenRelay = OUT_OFF; yellowRelay = OUT_OFF; redRelay = OUT_OFF; // Door locked, damper open and fan on - we're assuming it's been sitting for a while // and someone is about to open the door. Make them close the if open // so we can get venting. // Run the damper open twice to get to a known-good position of full-open damperIsOpen = false; //Assert and run the opener once damperRotate(1); //vent may be opened; damperIsOpen = false; //Assert and run the opener a second time damperRotate(1); //vent opened; // Start the fan whether or not the door is open if(!simulateMode) { fanRelay = OUT_ON; } else { fanRelay = OUT_OFF; } // Wait for the door to close if(doorClosed == IN_OFF) { redRelay = OUT_ON; rgbLCD.locate(0,0); rgbLCD.print("Close the door "); while(doorClosed == IN_OFF) { wait(1); } } rgbLCD.locate(0,0); rgbLCD.print("Venting "); doorInterlock = OUT_ON; redRelay = OUT_OFF; yellowRelay = OUT_ON; //wait 90sec countDown(90); // We turn off the fan because we don't know how long until someone is ready to open the door //Tank is ready rgbLCD.locate(0,0); rgbLCD.print("Tank is ready! "); yellowRelay = OUT_OFF; greenRelay = OUT_ON; //green light on doorInterlock = OUT_OFF; //interlock unlatched, ready to load material into the tank fanRelay = OUT_OFF; damperRotate(0); // damper is closed cancelPending = false; while(FOREVER) { if(cancelPending) { cancelPending = false; //Display status vfd = OUT_OFF; //pump off greenRelay = OUT_OFF; //green light OFF yellowRelay = OUT_OFF; //yellow light OFF redRelay = OUT_ON; //turn red light ON rgbLCD.clear(); rgbLCD.locate(0,0); rgbLCD.print("CYCLE STOPPED. "); if(doorClosed == IN_ON && !simulateMode) { doorInterlock = OUT_ON; //door latched fanRelay = OUT_ON; //fan on damperRotate(1); //damper opened //wait 60s, including the 30s damper rotation countDown(30); fanRelay = OUT_OFF; //fan stops damperRotate(0); //damper closed } else if(doorClosed == IN_OFF) { for(int i=0; i<3; i++) { wait(.5); redRelay = OUT_OFF; wait(.5); redRelay = OUT_ON; } } wait(0.5); redRelay = OUT_OFF; greenRelay = OUT_ON; doorInterlock=OUT_OFF; //door unlatched rgbLCD.locate(0,0); rgbLCD.print("Tank is ready! "); doorHasOpened = false; } if(doorClosed==IN_ON) //door closed { /* * Get set up for the wash, and wait for the start button */ greenRelay = OUT_ON; //green light stays on yellowRelay = OUT_OFF; //yellow light off redRelay = OUT_OFF; //red light off doorInterlock = OUT_OFF; //door unlocked fanRelay = OUT_OFF; damperRotate(0); //damper closed rgbLCD.locate(0,1); rgbLCD.print("Door closed "); while(cycleStartBtt != IN_ON && !(doorClosed == IN_OFF || cancelPending)) { if(stopBtt == IN_ON) { cancelPending = true; break; } wait(.25); } if(doorClosed == IN_OFF || cancelPending) { continue; } /* * Cycle start button pressed - wash for 2 minutes */ cycleHasStarted = true; rgbLCD.clear(); rgbLCD.locate(0,0); rgbLCD.print("CYCLE STARTED! "); greenRelay = OUT_OFF; //green light off yellowRelay = OUT_ON; //yellow light on if(!simulateMode) { doorInterlock = OUT_ON; //door locked vfd = OUT_ON; //vfd for pump up to speed } doorHasOpened = false; countDown(120); //start timer for 2min if(doorClosed == IN_OFF || cancelPending) { continue; } /* * Finished washing - turn off the pump */ vfd = OUT_OFF; //pump off rgbLCD.clear(); rgbLCD.locate(0,0); rgbLCD.print("CYCLE FINISHED! "); wait(1); if(doorClosed == IN_OFF || cancelPending) { continue; } /* * Drip dry and vent after washing for 5 minutes */ rgbLCD.clear(); rgbLCD.locate(0,0); rgbLCD.print("DRIP DRYING! "); if(!simulateMode) { fanRelay = OUT_ON; //fan on } damperRotate(1); //vent opened countDown(270); // 5 minutes, including the damper opening if(doorClosed == IN_OFF || cancelPending) { continue; } /* * Entire cycle is done, close up and go back to waiting */ fanRelay = OUT_OFF; //fan off damperRotate(0); //vent closed rgbLCD.clear(); rgbLCD.locate(0,0); rgbLCD.print("Tank is ready! "); doorInterlock = OUT_OFF; //door unlocked greenRelay = OUT_ON; //green light on yellowRelay = OUT_OFF; //yellow light off } else //door open { greenRelay = OUT_OFF; //green light OFF yellowRelay = OUT_OFF; redRelay = OUT_ON; //turn red light ON fanRelay = OUT_ON; //fan on damperRotate(1); //damper opened rgbLCD.locate(0,1); rgbLCD.print("Door open "); doorHasOpened = true; } wait(1); } } void damperRotate(int damper) //damper condition { if(damper==0 && damperIsOpen == true && !simulateMode) { damperRelayAlt=OUT_ON; //toggle damper relay rgbLCD.locate(0,1); rgbLCD.print("Closing damper "); wait(30); damperRelayAlt=OUT_OFF; //time out to reduce wear damperIsOpen = false; } else if(damper == 1 && damperIsOpen == false && !simulateMode) { damperRelay=OUT_ON; //toggle damper relay rgbLCD.locate(0,1); rgbLCD.print("Opening damper "); wait(30); damperRelay=OUT_OFF; //time out to reduce wear damperIsOpen = true; } } void fullLineItoA(int m, char* str) { if(str == NULL) { return; } // Empty the array to 16 white spaces for(int j=0; j < 16; j++) { str[j] = ' '; } str[16] = 0; // Put our counter in it, with the least-significant digit in col 4. int i = 3; do { str[i] = m%10 + '0'; m /= 10; i--; }while(m > 0 && i >= 0); } void countDown(int s) //countdown in sec { int m=0; char count[12]; // make a 'count' string for(m=s; m>0; m--) { if(stopBtt == IN_ON) { cancelPending = true; break; } fullLineItoA(m, count); rgbLCD.locate(0,1); rgbLCD.print(count); wait(1); } } void debugMode() { char displayLine1[17]; char displayLine2[17]; unsigned int count = 0; bool stopReleased = false; damperRelay = OUT_OFF; //Damper solenoid control damperRelayAlt = OUT_OFF; //Damper solenoid toggle control vfd = OUT_OFF; //VFD Start relay rgbLCD.clear(); rgbLCD.locate(0,0); do { strcpy(displayLine1, "Door= "); if(doorClosed == 1) { strcat(displayLine1, "1"); } else { strcat(displayLine1, "0"); } strcat(displayLine1, ",Start="); if(cycleStartBtt == 1) { strcat(displayLine1, "1 "); } else // start pressed { strcat(displayLine1, "0 "); if(stopBtt == IN_OFF && doorClosed == IN_OFF) { fanRelay = OUT_ON; } } strcpy(displayLine2, "Stop= "); if(stopBtt == 1) { strcat(displayLine2, "1 "); stopReleased = true; } else { strcat(displayLine2, "0 "); fanRelay = OUT_OFF; } // Every 2s, change the outputs if((count&7) == 0) // only do it 1 time out of 8 { doorInterlock = OUT_OFF; //Door interlock redRelay = OUT_OFF; //Red light yellowRelay = OUT_OFF; //Yellow light greenRelay = OUT_OFF; //Green light switch((count>>3)%4) // ignore the bottom 3 bits, and then roll over when you've counted to 4 { case 0: doorInterlock = OUT_ON; //Door interlock strcat(displayLine2, " Lock "); break; case 1: redRelay = OUT_ON; //Red light strcat(displayLine2, " Red "); break; case 2: yellowRelay = OUT_ON; //Yellow light strcat(displayLine2, " Yellow "); break; case 3: greenRelay = OUT_ON; //Green light strcat(displayLine2, " Green "); break; } } // Adjust the damper with start/stop if the door is closed if(cycleStartBtt == IN_ON && stopBtt == IN_OFF && stopReleased == true && doorClosed == IN_ON) { damperRelay = OUT_ON; } else if(stopBtt == IN_ON && cycleStartBtt == IN_OFF && stopReleased == true && doorClosed == IN_ON) { damperRelayAlt = OUT_ON; } else { damperRelay = OUT_OFF; damperRelayAlt = OUT_OFF; } rgbLCD.locate(0,0); rgbLCD.print(displayLine1); rgbLCD.locate(0,1); rgbLCD.print(displayLine2); wait(0.25); count++; } while(cycleStartBtt == IN_OFF || stopBtt == IN_OFF || doorClosed == IN_OFF); }