TPH x VOC sensor timings for samples


So I have been progressing well with getting my air quality sensor up and running using a Bosch TPH BME280 and CJMCU-1100 VOC sensor with an Arduino Uno.

However, I would like to programme this to take a sample every 15 minutes, with TPH sensor taking a reading for one minute every 14/15 minutes, subsequently followed by the VOC sensor. I would like the ending of the TPH sensor to trigger the VOC sensor to start up. The VOC sensor uses a hot plate method so needs ~3 minutes to start up.

I am just not sure how to programme this, especially since everything i see online uses a relay module.

Here is the code i currently have:

//********************Start of code for TPH sensor***********************

#include <Wire.h>
#include "RTClib.h"
#include <BME280I2C.h>
#include <SPI.h>
#include <SD.h>

BME280I2C bme; 

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

RTC_DS1307 rtc;

uint32_t delayMS;

const int chipSelect = 10;
const int pingPin = 7;

unsigned int rtcd;
unsigned int rtcm;
unsigned int rtcy;
unsigned int rtcs;
unsigned int rtcmin;
unsigned int rtchr;

//define start and end times of desired operation, may be just for relay module though?//

//const int OnHour = 12//
//const int OnMin = 05//
//const int OffHour = 12//
//const int OffMin = 06//

//This sensor measures changes in VOC gas levels//

#define Aout A0
#define Dout 2

void setup() {


  // Open serial communications and wait for port to open:


 if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
  // following line sets the RTC to the date & time this sketch was compiled
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2020, 12, 16, 10, 36, 0));

    Serial.println("Could not find BME280 sensor!");

  // bme.chipID(); // Deprecated. See chipModel().
     case BME280::ChipModel_BME280:
       Serial.println("Found BME280 sensor! Success.");
     case BME280::ChipModel_BMP280:
       Serial.println("Found BMP280 sensor! No Humidity available.");
       Serial.println("Found UNKNOWN sensor! Error!");


  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  Serial.println("card initialized.");

void loop() {

/*****************Get Temp, Pressure and Humidity********************/

  float temp(NAN), hum(NAN), pres(NAN);

   BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
   BME280::PresUnit presUnit(BME280::PresUnit_Pa);, temp, hum, tempUnit, presUnit);

float preshpa = (pres/100);  //create space for conversion of pascals to hectopascals (hPa) which is more usual measure
float corr_temp = (temp-0.0);  //create space for correction of temperature according to unique sensor validation (will be different for each sensor)
float corr_hum = (hum+0);  //create space for correction of humidity according to unique sensor validation (will be different for each sensor)
float corr_preshpa = (preshpa+10);  //create space for correction of pressure according to unique sensor validation (will be different for each sensor)

      Serial.print("Temp: ");
   Serial.print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
   Serial.print("\t\tHumidity: ");
   Serial.print("% RH");
   Serial.print("\t\tPressure: ");
   Serial.print(" hPa   ");

/*********GET VOC ************/
 int a=analogRead(Aout);
  int b=digitalRead(Dout);
  Serial.print("   A0:");

/*********GET TIME ************/

rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // uncommented //

    DateTime now =;
    Serial.print(now.year(), DEC);
    Serial.print(now.month(), DEC);
    Serial.print(, DEC);
    Serial.print(" (");
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(now.minute(), DEC);
    Serial.print(now.second(), DEC);
    //Serial.print(" since midnight 1/1/1970 = ");
    //Serial.print("s = ");
    //Serial.print(now.unixtime() / 86400L);

// DateTime now =;
  rtcs = now.second();
  rtcmin = now.minute();
  rtchr = now.hour();
  rtcy = now.year();
  rtcm = now.month();
  rtcd =;

/*********STORE DATA TO SD CARD ************/

// open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile ="datalog.csv", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {

    //dataFile.print(cm);        dataFile.print(",CM,");
    dataFile.print(rtchr);              dataFile.print(":");
    dataFile.print(rtcmin);             dataFile.print(":");
    dataFile.print(rtcs);               dataFile.print(",TIME,");
    dataFile.print(rtcd);               dataFile.print("/");
    dataFile.print(rtcm);               dataFile.print("/");
    dataFile.print(rtcy);             dataFile.print(",DATE,");
dataFile.print(corr_temp);             dataFile.print(",Temperature,");
dataFile.print(corr_preshpa);             dataFile.print(",Pressure,");
dataFile.print(corr_hum);             dataFile.print(",Humidity,");
dataFile.print(b);             dataFile.print(",TVOC Digital,");
dataFile.print(a);             dataFile.println(",TVOC Analogue");
    // print to the serial port too:
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.csv");



// ***********************End of Code -- you are DONE!*******************************

How does the VOC get power to the hotplate?

From the 5V pin along the analog side of the Uno shield. The bme280 uses the ‘5V GNG SDA SCL’ pins on the shield which correlate to A2,3,4&5.

I expect the reason for the relay is in cases where people are trying to save power between readings - is that what you need to do?

As to timing, you can use the usual blink without delay method of using millis to tell you when it's time to take readings again.

Yes exactly that.

I will try and do that with the blink, thank you. I am pretty new to it but will provide an updated code on here once i figure it out.


Here are the VOC specs.

You will need to have some sort of MOSFET or relay to turn the heater ON/OFF as it is too much current for an output direct.

0.350W = 5V x Current
Current = 0.350 / 5v = 0.07 A == 70mA


Tom... :grinning: :+1: :coffee: :australia:

Hi Tom,

Thank you so much. I am prototyping the sensor to run off battery pack, so is this still applicable?

Yes it is still applicable as the device needs to have a regulated 5V supply to ensure its proper operation.
So your battery pack needs to power a regulator to give 5V.

There are a number of switchmode small buck/boost power supplies that will run of a battery pack.

Here is an example;

Tom.. :grinning: :+1: :coffee: :australia: