Hello,
I am trying to code this sensor, well 3 sensors, (Grove PM2.5 Sensor, CJMCU-MS1100 TVOC sensor and BME280 TPH sensor together with a relay module) to take readings every 15 minutes, for 5 minutes (3 readings/hour), using the relay module. I understand i must use Millis() function and equation to create timed events. However, i am still very much a novice with code and have no idea how to integrate all codes for each sensor into one, with the relay and timed events.
Here is the code:
---------------------TPH, PM2.5 AND TVOC SENSOR WITH SD DATA LOG-------------------------//
//This sensor measures Temperature, Pressure, Humidity, Particulates <0.1 microns and Total Volotile Organic Compounds//
//--------------------------------------------------------------------------------------------
// LIBRARIES
//--------------------------------------------------------------------------------------------
#include <SPI.h> // library for SD logging
#include <SD.h>
#include "RTClib.h"
#include <BME280I2C.h> //BME Sensor
#include <RTClib.h> // library for the Real Time Clock
#include <Seeed_HM330X.h> //Grove PM2.5 Sensor
//--------------------------------------------------------------------------------------------
// DEFINES
//--------------------------------------------------------------------------------------------
#define Aout A0 //TVOC Pins
#define Dout 2
const int chipSelect = 10; // pin 10 for SD shield
const int pingPin = 7; // something
File DataFile; //create a file to store data
BME280I2C bme; //TPH sensor
RTC_DS1307 rtc; //RTC
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE // Grove PM2.5 Sensor
#define SERIAL_OUTPUT SerialUSB
#else
#define SERIAL_OUTPUT Serial
#endif
const unsigned long eventInterval = 900000; //Assign the time in millis for event interval (every 15 minutes)
unsigned long previousTime = 0; //Set previous time to 0 so that it can be subtracted from event interval in void loop
int relay in 1 = 9; //Relay = pin 9
int relay in 2 = 8; //Relay = pin 8
volatile byte relayState = LOW; //Relay is off (LOW voltage) until event begins
long debounceDelay = 300000; //Keep relay on for 5 minutes?? unsure if this will work without
const char* str[] = {"sensor num: ", "PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM10 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM1.0 concentration(Atmospheric environment,unit:ug/m3): ",
"PM2.5 concentration(Atmospheric environment,unit:ug/m3): ",
"PM10 concentration(Atmospheric environment,unit:ug/m3): ",
};
//--------------------------------------------------------------------------------------------
// SETUP
//--------------------------------------------------------------------------------------------
void setup() {
pinMode(10,OUTPUT); //Setup for Relay
pinMode(Aout,INPUT); // Setup for VOC
pinMode(Dout,INPUT);
Serial.begin(115200); //initializing Serial monitor
// setup for the RTC
while (!Serial);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
else {
//set RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
}
while(!bme.begin())
{
Serial.println("Could not find BME280 sensor!");
delay(1000);
}
// bme.chipID(); // Deprecated. See chipModel().
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
// setup for the SD card
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
//open file
DataFile = SD.open("Data.txt", FILE_WRITE);
// if the file opened ok, write to it:
if (DataFile) {
Serial.println("File opened ok");
// print the headings for data
DataFile.println("Date,Time,dBA");
}
DataFile.close();
}
HM330XErrorCode print_result(const char* str, uint16_t value) {
if (NULL == str) {
return ERROR_PARAM;
}
SERIAL_OUTPUT.print(str);
SERIAL_OUTPUT.println(value);
return NO_ERROR;
}
/*parse buf with 29 uint8_t-data*/
HM330XErrorCode parse_result(uint8_t* data) {
uint16_t value = 0;
if (NULL == data) {
return ERROR_PARAM;
}
for (int i = 1; i < 8; i++) {
value = (uint16_t) data[i * 2] << 8 | data[i * 2 + 1];
print_result(str[i - 1], value);
}
return NO_ERROR;
}
HM330XErrorCode parse_result_value(uint8_t* data) {
if (NULL == data) {
return ERROR_PARAM;
}
for (int i = 0; i < 28; i++) {
SERIAL_OUTPUT.print(data[i], HEX);
SERIAL_OUTPUT.print(" ");
if ((0 == (i) % 5) || (0 == i)) {
SERIAL_OUTPUT.println("");
}
}
uint8_t sum = 0;
for (int i = 0; i < 28; i++) {
sum += data[i];
if (sum != data[28]) {
SERIAL_OUTPUT.println("wrong checkSum!!!!");
}
SERIAL_OUTPUT.println("");
return NO_ERROR;
}
//--------------------------------------------------------------------------------------------
// FUNCTIONS
//--------------------------------------------------------------------------------------------
void loggingTime() ;
DateTime now = rtc.now();
DataFile = SD.open("Data.txt", FILE_WRITE);
if (DataFile) {
DataFile.print(now.year(), DEC);
DataFile.print('/');
DataFile.print(now.month(), DEC);
DataFile.print('/');
DataFile.print(now.day(), DEC);
DataFile.print(',');
DataFile.print(now.hour(), DEC);
DataFile.print(':');
DataFile.print(now.minute(), DEC);
DataFile.print(':');
DataFile.print(now.second(), DEC);
DataFile.print(",");
}
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.println(now.day(), DEC);
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.println(now.second(), DEC);
DataFile.close();
delay(800);
}
void loggingBME() ;
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, 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+7); //create space for correction of pressure according to unique sensor validation (will be different for each sensor)
Serial.print("Temp: ");
Serial.print(corr_temp);
Serial.print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
Serial.print("\t\tHumidity: ");
Serial.print(corr_hum);
Serial.print("% RH");
Serial.print("\t\tPressure: ");
Serial.print(corr_preshpa);
Serial.println(" hPa");
File dataFile = SD.open("Data.txt", FILE_WRITE);
if (DataFile) {
dataFile.print(corr_temp); dataFile.print(",Temperature,");
dataFile.print(corr_preshpa); dataFile.print(",Pressure,");
dataFile.print(corr_hum); dataFile.print(",Humidity,");
delay(1000);
dataFile.close();
delay(10);
// print to the serial port too:
//Serial.println(cm);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening data.txt");
}
}
void loggingVOC() ;
int a=analogRead(Aout);
int b=digitalRead(Dout);
Serial.print("D0:");
Serial.print(b);
Serial.print(" A0:");
Serial.println(a);
File dataFile = SD.open("Data.txt", FILE_WRITE);
if (DataFile) {
dataFile.print(b); dataFile.print(",TVOC Digital,");
dataFile.print(a); dataFile.println(",TVOC Analogue");
delay(1000);
dataFile.close();
delay(10);
// print to the serial port too:
//Serial.println(cm);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening data.txt");
}
void loggingPM(); {
HM330X sensor;
uint8_t buf[30];
const char* str[] = {"sensor num: ", "PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM10 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM1.0 concentration(Atmospheric environment,unit:ug/m3): ",
"PM2.5 concentration(Atmospheric environment,unit:ug/m3): ",
"PM10 concentration(Atmospheric environment,unit:ug/m3): ",
};
// delay(100);
SERIAL_OUTPUT.println("Serial start");
if (sensor.init()) {
SERIAL_OUTPUT.println("HM330X init failed!!!");
while (1);
}
if (sensor.read_sensor_value(buf, 29)) {
SERIAL_OUTPUT.println("HM330X read result failed!!!");
}
parse_result_value(buf);
parse_result(buf);
SERIAL_OUTPUT.println("");
}
//File dataFile = SD.open("Data.txt", FILE_WRITE);
if (DataFile) {
dataFile.print(str); dataFile.print(",Temperature,");
dataFile.println(value); dataFile.print("PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM10 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM1.0 concentration(Atmospheric environment,unit:ug/m3): ",
"PM2.5 concentration(Atmospheric environment,unit:ug/m3): ",
"PM10 concentration(Atmospheric environment,unit:ug/m3): ");
delay(1000);
dataFile.close();
delay(10);
// print to the serial port too:
//Serial.println(cm);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening data.txt");
}
}
//--------------------------------------------------------------------------------------------
// MAIN LOOP
//--------------------------------------------------------------------------------------------
void loop() ;
/* Updates frequently */
unsigned long currentTime = millis();
/* This is the event */
if (currentTime - previousTime >= eventInterval) {
/* Event code */
digitalWrite(relaye, HIGH) ;
/* Update the timing for the next time around */
previousTime = currentTime;
loggingTime();
loggingDecibels();
loggingBME();
loggingVOC();
loggingGrove();
delay(1000);
}
//-------------------------END-------------------------//
I am also getting the error message a lot:
" Combined_Sensors_HenryLayout:213:4: error: 'bme' does not name a type
bme.read(pres, temp, hum, tempUnit, presUnit);
^~~
Combined_Sensors_HenryLayout:220:7: error: 'Serial' does not name a type
Serial.print("Temp: ");
^~~~~~
Combined_Sensors_HenryLayout:221:4: error: 'Serial' does not name a type
Serial.print(corr_temp);
^~~~~~
Combined_Sensors_HenryLayout:222:4: error: 'Serial' does not name a type
Serial.print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
^~~~~~
Combined_Sensors_HenryLayout:223:4: error: 'Serial' does not name a type
Serial.print("\t\tHumidity: ");
^~~~~~
Combined_Sensors_HenryLayout:224:4: error: 'Serial' does not name a type
Serial.print(corr_hum);
^~~~~~
Combined_Sensors_HenryLayout:225:4: error: 'Serial' does not name a type
Serial.print("% RH");
^~~~~~
Combined_Sensors_HenryLayout:226:4: error: 'Serial' does not name a type
Serial.print("\t\tPressure: ");
^~~~~~
Combined_Sensors_HenryLayout:227:4: error: 'Serial' does not name a type
Serial.print(corr_preshpa);
^~~~~~
Combined_Sensors_HenryLayout:228:4: error: 'Serial' does not name a type
Serial.println(" hPa");
^~~~~~
Combined_Sensors_HenryLayout:231:1: error: expected unqualified-id before 'if'
if (DataFile) {
^~
Combined_Sensors_HenryLayout:242:3: error: expected unqualified-id before 'else'
else {
^~~~
Combined_Sensors_HenryLayout:245:3: error: expected declaration before '}' token
}
^
exit status 1
'bme' does not name a type "
It is probably how I have structured the code, but again, I am not sure as I am so new to C++ and coding in general.
Here is a picture of my connections, am I right in having my ground pins from the sensors connected to the normally closed pins on the relay, and the VCC pins from the sensors connected to the common pins on the relay?
Connections:
BME280 soldered to the 5V GND SDA SCL pins on RTC stack)
5V - Pin A2
GND - Pin A3
SDA - Pin A4
SCL - Pin A5
CJMCU-MS1100
GND - Relay NC pin
DOUT - Pin D2
AOUT - Pin A0
VCC - Relay COM pin
Grove PM2.5 HM-3300/3600 Dust Sensor
GND - Relay NC pin
VCC - Relay COM pin
SDA - SDA pin
SCL - SCL pin
2 Channel Relay
GND - GND pin
IN 1 - pin 9
IN 2 - pin 8
VCC - VCC pin
If anyone is able to help me code this correctly, to the correct hardware pins with the relay and produce the timed events required, I would be eternally grateful!!!!
Is anyone able to help me out? I know this code is also messy (well, looks like it to me) so any advice on clearer structure of code would be amazing too!
Hardware and Datasheets below:
BST-BME280-DS002-1509607.pdf (1.4 MB)
Grove PM2.5 Laser Sensor.pdf (744.8 KB)
MS1100-ETC.pdf (433.6 KB)
Thank you,
Callum.