#include <Adafruit_GFX.h>    // Core graphics library
#include <MCUFRIEND_kbv.h>   // Hardware-specific library
MCUFRIEND_kbv tft;

#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSerif12pt7b.h>

#include <FreeDefaultFonts.h>

#define BLACK   0x0000
#define RED     0xF800
#define GREEN   0x07E0
#define WHITE   0xFFFF
#define GREY    0x8410

#include <math.h>

int DustSensePin = 31;

//globals for ppd42 dust sensor

//unsigned int airreading[100] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned long starttime = 0;
unsigned long sampletime_ms = 10000;//sample 60s == 60000 ;
unsigned long lowpulseoccupancy = 0;
unsigned long duration = 0;
float ratio = 0;
float concentration = 0;
unsigned int x = 0;
unsigned int toplimit = 0;
unsigned long sum = 0; //highest number possible - 32 bit unsigned, so 4 billion
unsigned int average = 0;
//end ppd42


int brightnessread = 0;

int cat = 0;
int resultsread1 = 0;

int screenreadyforprint = 0;
double count = 0;

void setup(void)
{
    Serial.begin(9600);
    uint16_t ID = tft.readID();
    if (ID == 0xD3) ID = 0x9481;
    tft.begin(ID);
    tft.setRotation(1);
    tft.WriteCmdData(0x51, 0x00);
    //resultsread1 = tft.readReg(0x52);
    //writeData(0x51);
    pinMode(DustSensePin,INPUT);
    starttime = millis();//get the current time;
    
    
}

void loop(void)
{
 
    
    
    if(screenreadyforprint == 0){
    tft.fillScreen(BLACK);
    tft.WriteCmdData(0x51, 0x0000);
    tft.setTextColor(0XFFFF);
    tft.setTextSize(2);
    tft.setCursor(0, 36);
    tft.println("Starting Sensor");
    screenreadyforprint = 1;
    }


    duration = pulseIn(DustSensePin, LOW, 500000);

    lowpulseoccupancy = lowpulseoccupancy + duration;
    
    //tft.println(airreading)
    if ((millis()-starttime) > sampletime_ms)//if the sample time == 30s
    { 
        tft.fillScreen(BLACK);
        tft.WriteCmdData(0x51, 0x0000);
        tft.setTextColor(0XFFFF);
        tft.setTextSize(2);
        tft.setCursor(0, 36);
    
        ratio = lowpulseoccupancy/(sampletime_ms*10.0);  // Integer percentage 0=>100
        concentration = 1.1*powf(ratio,3)-3.8*powf(ratio,2)+520*ratio+0.62; // using spec sheet curve
        tft.print("Count: ");
        tft.println(count);
        tft.println(lowpulseoccupancy);
        //tft.print(",");
        tft.println(ratio);
        //tft.print(",");
        tft.print("Concentration is: ");
        tft.println(concentration);
        lowpulseoccupancy = 0;
        starttime = millis();
        //tft.println("Results printed.");
        count++;
        
    }
    
    
    
}

void showmsgXY(int x, int y, int sz, const GFXfont *f, const char *msg)
{
    int16_t x1, y1;
    uint16_t wid, ht;
    tft.drawFastHLine(0, y, tft.width(), WHITE);
    tft.setFont(f);
    tft.setCursor(x, y);
    tft.setTextColor(GREEN);
    tft.setTextSize(sz);
    tft.print(msg);
    delay(1000);
}


uint32_t readReg32(uint16_t reg)
{
    uint16_t h = tft.readReg(reg, 0);
    uint16_t l = tft.readReg(reg, 1);
    return ((uint32_t) h << 16) | (l);
}
