POC Breath using SMD commercial sensors

Dependencies:   iAQ_Core Adafruit_SGP30_mbed mbed BME680

main.cpp

Committer:
mehrnaz
Date:
2019-07-25
Revision:
3:3d51f8870e91
Parent:
2:ef98576cd67b
Child:
5:646a7e58989e

File content as of revision 3:3d51f8870e91:

#include "mbed.h"
#include "flow.h"

/////////////////////////
// In this version of the program developed for the Breath project, flow and CO2, as well as 8 channel sensors,
// are measured in a separate .h file called: "flow.h" which is included in the
// main code. So 10 sets of data is streamed using a serial connection (TTL cable or Bluetooth)
// without any intruption. 
// This version is especially suitable to be used for KST.
// Also, a solenoid would be turned on and off based on calculating the standard deviation in CO2 profile.
//
// START POINT: calculates SD for 9 samples of CO2, if it's grater than 0.02 it enables the solenoid.
// END POINT: calculates SD for 9 samples of CO2, if it's grater thatn 0.05 it disables the solenoid.
//
// You can easily change the threshold of Standard deviation to detect plateau
//
// Generated by: Mehrnaz Javadipour
////////////////////////// 

Serial ttl(PC_12,PD_2);  //TTL cable TX,RX
DigitalOut sol(PC_5);   //Solenoid: Digital Output
PwmOut led(PB_6);



int main()
{
    ttl.baud(9600); //baudrate for the serial connection
    flow();         //calling flow from flow.h
    carbon();       //calling CO2 from flow.h
    s1();           //calling 8 channels from flow.h
    s2();
    s3();
    s4();
    s5();
    s6();
    s7();
    s8();
    getTemp();      //calling Temperature from flow.h
    
    //////////////////////////////
    // I defined a flag for each section of specific functions, so by enabling the
    // flag the section starts and by disabling the flag it finishes the section.
    // at the end of the program, I reset the flags so it would be ready for the next loop.   
    /////////////////////////////
    
    int bf=0;         //FLAG for detecting base flow
    int i=0;
    float bfArray[4]; //sampling flow for finding the average base flow          
    float sf=0;       //sum of flow samples for calculating base flow
    float fv=0;       //final value of base flow
    
    int measurement_started=0; //FLAG for starting calculations after detecting breath
    
    int solstart=0;         //FLAG for starting calculations for detecting plateau
    int m=0;
    int myArray[9];         //sampling 9 values of CO2
    unsigned int sum=0;     //sum of 9 samples of CO2
    int avg=0;              //average of 9 samples of CO2
    int difSum=0;           //used for the Standard deviation algorithm
    long double var=0.0;    //used for the Standard deviation algorithm
    float sigma=0.0;        //final value for standar deviation
    int flags=0;            //FLAG for keep taking samples from CO2 profile when it's too early to detect plateau
    
    int solend=0;           //FLAG for ending calculations for detecting plateau
    unsigned int sum2=0;    //same as before; used for finding standard deviation
    long double var2=0.0;
    float sigma2=0.0;
    int difSum2=0;
    int avg2=0;
    int flage=0;            //FLAG for keep taking samples from CO2 profile when it's too early to finish plateau
    
    int fin=0;
    

    
    while(1)
    {
        led=1.00f;      //an LED is fully turned on at the beginning, the brightness will be reduced when the plateau is detected.
        ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());

        if (bf==0)      //finding base flow before breath
            {
              for(i=0; i<4; i++) 
                  {
                    bfArray[i]=flow();  
                    sf+=bfArray[i];                  
                  }   
               fv=sf/4;
               fv=fv+0.2; 
               //ttl.printf("set\n");
               bf=1;
             }
        
        //Starts calculations when it detects breathing into the device:
        
        if ((flow()>fv) and (measurement_started ==0)) 
            {        
                measurement_started = 1;
            }
        
        //Starts detecting plateau:
        
        if ((measurement_started == 1) and (solstart==0)) 
            {
                //Takes 9 samples of CO2:
                //I have also included printing the values inside the loops so we don't loose any data during calculatins.
                for(m=0;m<9;m++)
                    {
                        ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                        myArray[m]=carbon();
                    }
                while(flags==0)
                    {
                        //While "flags" is enabled, keeps calculating the standard deviation.
                        for(int m=0;m<9;m++)
                            { 
                            ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                            sum+=myArray[m]; 
                            }
                        avg=sum/9;
                        for(int m=0;m<9;m++)
                            {
                            ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                            difSum+=(myArray[m]-avg)*(myArray[m]-avg); //Find sum of difference between value X and mean
                            }
                            var=difSum/9;
                            sigma=sqrt(var);
                        if (sigma<0.02)
                            {
                            
                            //if SD is less than 0.02 it means that it is too early to start the plateau
                            //So we shift all but the first sample and define the new set of arrays:
                            
                            for(int m=0;m<8;m++)
                             {
                              ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                              myArray[m]=myArray[m+1];  //Shift all CO2 values to the left by 1 value
                             }
                             myArray[8]=carbon();  //assign a new value for the 9th sample
                            }
                             //The new set of arrays are now generated and is sent back to be used for preveious SD calculations.
                             //If sigma for the new set is still small, a newer set will be generated and replaced
                             //Otherwise, it's accepted and will turn on the solenoid:
                            else
                            {
                            ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                            sol=1;      //Solenoid is ON
                            led=0.50f;  //The brightness is reduced to half during the plateau
                            flags=1;    //breakes the while loop
                            }
                     }
                solend=1;   //prepares the next section for finishing the plateau
                solstart =1;
            }
        if ((measurement_started == 1) and (solend==1)) 
        {
          // same process happens for finishing the plateau:
        
                for(m=0;m<9;m++)
                    {
                        ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                        myArray[m]=carbon();
                    }
                while(flage==0)
                    {
                        for(int m=0;m<9;m++)
                            { 
                            ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                            sum2+=myArray[m]; 
                            }
                        avg2=sum2/9;
                        for(int m=0;m<9;m++)
                            {
                            ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                            difSum2+=(myArray[m]-avg2)*(myArray[m]-avg2); 
                            }
                            var2=difSum2/9;
                            sigma2=sqrt(var2);
                        if (sigma2<0.05)
                            {
                            // here we defined the end threshold to be 0.05, it can be changed later based on experiment results
                            for(int m=0;m<8;m++)
                             {
                              ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                              myArray[m]=myArray[m+1];  
                             }
                             myArray[8]=carbon();   
                            }else
                            {
                            ttl.printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",getTemp(),flow(), carbon(),s1(),s2(),s3(),s4(),s5(),s6(),s7(),s8());
                            sol=0;  //Solenoid is OFF
                            flage=1;    //breakes the loop
                            }
                     }
        solend =0;  //end of this section
        led=1.00f;  //LED is back to full brightness
        bf=0;       //reset the detecting base flow flag
        fin=1;      //enables the next section flag
        }
     if((carbon()<10000) and (fin ==1)) 
            {
                //User has to wait for the CO2 level to drop less than 1% before testing again.
                //Once it is less than 1%, all the flags and parameters used in calculations are reset
                measurement_started =0;
                solstart=0;
                sum=0;
                var=0.0;
                sigma=0.0;
                difSum=0;
                 sum2=0;
                var2=0.0;
                sigma2=0.0;
                difSum2=0;
                avg2=0;
                avg=0;
                flags=0;
                flage=0;
                fin=0;
            }
    }
}