First draft to the functional spec

Dependencies:   mbed Grove_LCD_RGB_Backlight DebounceIn

main.cpp

Committer:
bmcclure
Date:
2019-10-09
Revision:
4:d56051982cf5
Parent:
3:07d400d50a96

File content as of revision 4:d56051982cf5:

#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
            if(!simulateMode)
            {
                fanRelay    = OUT_ON;   //fan on   
            }
            damperRotate(1);        //damper opened       
            rgbLCD.locate(0,1);
            rgbLCD.print("Door open       ");
            doorHasOpened = true;        
            
            if(cycleStartBtt == IN_ON || stopBtt == IN_ON)
            {
                cancelPending = 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 && !simulateMode)
            {
                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);    
}