Appendix A: Function Library

checkConnection()

Checks serial connection to PM sensor and connection to SD card and returns 5 and 2 LED blinks, respectively, if successful.

void checkConnection() {
  if (my_status == 1){
    for (int i = 1; i < 6; i++){
      blink();
    }
    
    delay(3000);
  }
  else{
    digitalWrite(LED_BUILTIN, HIGH);
    delay(5000);  
    digitalWrite(LED_BUILTIN, LOW);
  }

   if (!SD.begin(chipSelect)) {
    return;
  }
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
        // don't do anything more:
        while (1) {
            blink();
            blink();
        }
    }
    for (int i = 1; i < 3; i++){
      blink();
    }
}

createFileName(int y, int m, int d)

Creates file name based on the current date.

String createFileName(int y, int m, int d) {
  return String(fillDigits(y)) + String(fillDigits(m)) + String(fillDigits(d)) + deviceID + ".txt";
}

fillDigits(int digits)

Adds a leading zero to a number if < 10.

String fillDigits(int digits) {
  if (digits < 10) {
    String digitsout = "0" + String(digits);
    return digitsout;
  }
  else return digits;
}

getTeensy3Time()

This function comes from the RTC example. It syncs the RTC time on the Teensy.

time_t getTeensy3Time() {
  return Teensy3Clock.get();
}

performPMReading()

Reads PM_2.5 data from sensor and returns it as a float.

float performPMReading() {
    float pavg = 0.0;
    float psum = 0.0;
    
    for (int i = 1; i < 21; i++) {
      my_status = my_hpm.read(&p25, &p10);
      if (i > 15) {         // throw away first points while it warms up
          psum = psum + p25;
          pavg = (psum)/(float(i)-15.0);
          }   
          delay(1000);    
    }
    return pavg;
}

printData()

Returns data string in standard format based on sensor ID string and measurements values (floats).

String printData(String ID, float t, float h, float p, float g, float pm25) {
  return String(ID) + '\t' + printDateTime(printDate(year(), month(), day()), printTime(hour(), minute(), second())) + '\t' + String(t) + '\t' + String(h) + '\t' + String(p/100.0) + '\t' + String(g/1000.0)+ '\t' + String(pm25);
}

printDate(int y, int m, int d)

Prints date string in standard YYYY-MM-DD format given Y, M, D integers.

String printDate(int y, int m, int d) {
  return String(y) + "-" + fillDigits(m) + "-" + fillDigits(d);
}

printDateTime(String d, String t)

Concatenates date (printDate()) and time (printTime()) strings as ‘YYYY-MM-DD HH:MM:SS’.

String printDateTime(String d, String t) {
  return d + ' ' + t;
}

printTime(int h, int m, int s)

Returns time string as HH:MM:SS based on integer H, M, S inputs.

String printTime(int h, int m, int s) {
  return fillDigits(h) + ":" + fillDigits(m) + ":" + fillDigits(s);
}

setBMESamplingParameters()

Sets the sampling and filtering parameters for the BME sensor.

void setBMESamplingParameters() {
  if (!bme.begin(0x76)) {
    return;
  }
  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms
}

turnSensorsOff()

Turns sensors off for hibernate.

void turnSensorsOff() {
  my_status = my_hpm.stop_measurement();
  Serial1.end();
  delay(500);
  digitalWrite(33, LOW);
}

turnSensorsOn()

Turns on the sensors and sets the RTC time. Can be used to wake from hibernate or start from off.

void turnSensorsOn() {
  digitalWrite(33, HIGH); // turn on relay
  delay(5000); // wait to stabilize
  setSyncProvider(getTeensy3Time);

  Serial1.begin(9600);
  while (!Serial1) {
    ; // wait for serial port to connect. Needed for native USB
  }
  Serial1.flush();
  my_status = my_hpm.stop_autosend();
  delay(500);
  my_status = my_hpm.start_measurement();  
  delay(500); 
}

writeFile(char filename[16])

Writes the measurement file to the SD card.

void writeFile(char filename[16], String dataString) {
    File dataFile = SD.open(filename, FILE_WRITE);
    if (dataFile) {
        dataFile.println(dataString);
        delay(500);
        dataFile.close();
     }
     else return;
}