So i have had produced this code, but i cannot seem to sleep my Arduino Uno for my desired time. I need the Arduino Uno to sleep for 12 minutes, wake up and take readings after 3 minutes (warm up time for my sensors), then take readings for 5 minutes. I have got the wake up and reading times correct, just can't seem to get sleep time correct.
Can anyone help? These are the snippets of code that conrol the time:
const unsigned long eventInterval = (1000UL*60*3); //Assign the time in millis for event interval (every 15 minutes)
unsigned long startTime = millis()+ eventInterval;
unsigned long readingInterval= (1000UL*60*5); //Assign the time in millis for reading (every 5 minutes)
//SD stack select
const int chipSelect = 10;
//const int pingPin = 7;
//RTC Module Global Variables
const int time_interval= 12 ; // Sets the wakeup interval in minutes.
....and.....
/* This is the event */
if ((long)(millis()-startTime)>=0) {
delay(10);
unsigned long i=millis();
while ((long)((i+readingInterval)-millis())>=0){
//Get the values of the sensors
GetRTC_Readings();
GetVOC_Readings();
GetPM_Readings();
GetBME_Readings();
delay (5000); // to give time for PMS to take readings?
// Store the three sensor values to the SD card.
print2SD();
delay(5000);
}
digitalWrite(indicator,HIGH);
delay(2000);
digitalWrite(indicator,LOW);
Serial.println("Going to sleep for 24 seconds");
digitalWrite(Relay_pin,LOW);
digitalWrite(Relay_pin2,LOW);
delay(100);
for(int i = 0; i<= 6*time_interval; i++) //this is sleeping arduino for 12 seconds
{
LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,SPI_OFF, USART0_OFF, TWI_OFF);
}
delay(1000);
startTime = millis()+ eventInterval; //this is what affects the time
Serial.println("Arduino: Hey I just Woke up");
Serial.println("");
delay(1000);
}
}
Full code below:
//********************Start of code for TPH, PM, VOC sensor***********************
//*** TO DO LIST ***//
//pinmap with relay
//documentation
//- Calibrate BME
//- Calibrate VOC sensor (potentiometer on back adjusts zero threshold)
#include <RtcDS3231.h>
#include <DS3232RTC.h>
#include <LowPower.h>
#include <Adafruit_BusIO_Register.h>
#include <Adafruit_I2CDevice.h>
#include <Adafruit_I2CRegister.h>
#include <Adafruit_SPIDevice.h>
#include <avr/sleep.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <SoftwareSerial.h>
#include "Adafruit_PM25AQI.h"
#include <BME280I2C.h>
#include <SPI.h>
#include <SD.h>
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
//Real Time Clock
DS3232RTC rtc;
//BME280 - TPH
BME280I2C bme;
//PM Sensor
SoftwareSerial pmsSerial(3,4);
Adafruit_PM25AQI aqi = Adafruit_PM25AQI();
//#define 2
//TVOC sensor
#define Aout A0 //Define pins for TVOC sensor
#define Dout 7
//Set up pin 9
#define Relay_pin 9
#define Relay_pin2 6
uint32_t delayMS;
//eventinterval is when the arduino starts taking readings from sensos
//then redinginterval is how long the reading of sensor values happens
//time_interval is how long the arduino sleeps for
//meaning there will be a 3 minute warm up period for PMS and CJMCU-MS1100 until the next reading event
const unsigned long eventInterval = (1000UL*60*3); //Assign the time in millis for event interval (every 15 minutes)
unsigned long startTime = millis()+ eventInterval;
unsigned long readingInterval= (1000UL*60*5); //Assign the time in millis for reading (every 5 minutes)
//SD stack select
const int chipSelect = 10;
//const int pingPin = 7;
//RTC Module Global Variables
const int time_interval= 12 ; // Sets the wakeup interval in minutes.
unsigned int rtcd;
unsigned int rtcm;
unsigned int rtcy;
unsigned int rtcs;
unsigned int rtcmin;
unsigned int rtchr;
// Structure to hold pms sensor data.
struct pms5003data {
volatile uint16_t framelen;
volatile uint16_t pm10_standard, pm25_standard, pm100_standard;
volatile uint16_t pm10_env, pm25_env, pm100_env;
volatile uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
volatile uint16_t unused;
volatile uint16_t checksum;
} pms5003dataStruct;
//Declaring BME variables
float preshpa;
float corr_temp;
float corr_hum;
float corr_preshpa;
// Declaring VOC variables
byte a;
byte b;
//
#define interruptPin 2
#define indicator 8
PM25_AQI_Data data;
void setup() {
pinMode(Relay_pin, OUTPUT);
pinMode(Relay_pin2, OUTPUT);
digitalWrite(Relay_pin,HIGH);
digitalWrite(Relay_pin2,HIGH);
pinMode(indicator,OUTPUT);
// pinMode(interruptPin, INPUT_PULLUP);
digitalWrite(indicator, LOW);
// Open serial communications and wait for port to open:
//Serial.begin(9600);
// PM sensor debugging output
Serial.begin(115200);
while (!Serial) delay(10);
// PM sensor baud rate is 9600
pmsSerial.begin(9600);
//remember to copy and paste the RTC code from other code to reset RTC to current time!
//delay(1000);
//Find PM sensor
if (! aqi.begin_UART(&pmsSerial)) { // connect to the sensor over software serial
Serial.println(F("Could not find PM 2.5 sensor!"));
while (1) delay(10);
}
Serial.println(F("PM25 found!"));
//Find BME280 TPH sensor
while (!bme.begin())
{
Serial.println(F("Could not find BME280 sensor!"));
// delay(1000);
}
// bme.chipID(); // Deprecated. See chipModel().
switch (bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println(F("Found BME280 sensor! Success."));
break;
case BME280::ChipModel_BMP280:
Serial.println(F("Found BMP280 sensor! No Humidity available."));
break;
default:
Serial.println(F("Found UNKNOWN sensor! Error!"));
}
// Storing the CSV file header/title.
printHeader();
}
void loop() {
digitalWrite(Relay_pin,HIGH);
digitalWrite(Relay_pin2,HIGH);
/* This is the event */
if ((long)(millis()-startTime)>=0) {
delay(10);
unsigned long i=millis();
while ((long)((i+readingInterval)-millis())>=0){
//Get the values of the sensors
GetRTC_Readings();
GetVOC_Readings();
GetPM_Readings();
GetBME_Readings();
delay (5000); // to give time for PMS to take readings?
// Store the three sensor values to the SD card.
print2SD();
delay(5000);
}
digitalWrite(indicator,HIGH);
delay(2000);
digitalWrite(indicator,LOW);
Serial.println("Going to sleep for 24 seconds");
digitalWrite(Relay_pin,LOW);
digitalWrite(Relay_pin2,LOW);
delay(100);
for(int i = 0; i<= 6*time_interval; i++) //this is sleeping arduino for 24 seconds
{
LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,SPI_OFF, USART0_OFF, TWI_OFF);
}
delay(1000);
startTime = millis()+ eventInterval; //this is what affects the time
Serial.println("Arduino: Hey I just Woke up");
Serial.println("");
delay(1000);
}
}
//}
void printHeader(){
//Initialize and find SD card
Serial.print(F("Initializing SD card..."));
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println(F("Card failed, or not present"));
// don't do anything more:
while (1);
}
Serial.println(F("card initialized."));
File dataFile = SD.open("datalog.csv", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
//dataFile.print(cm); dataFile.print(",CM,");
dataFile.print("DATE,");
dataFile.print("TIME,");
dataFile.print("Temperature,");
dataFile.print("Pressure,");
dataFile.print("Humidity,");
dataFile.print("TVOC Digital,");
dataFile.print("TVOC Analogue,");
dataFile.print("PM 0.3,");
dataFile.print("PM 2.5,");
dataFile.print("PM 10");
// dataFile.print(aqi.read(&data)); dataFile.print
delay(2000);
dataFile.close();
}
}
void GetBME_Readings(){
/*****************Get Temp, Pressure and Humidity********************/
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);
preshpa = (pres / 100); //create space for conversion of pascals to hectopascals (hPa) which is more usual measure
corr_temp = (temp - 0.0); //create space for correction of temperature according to unique sensor validation (will be different for each sensor)
corr_hum = (hum + 0); //create space for correction of humidity according to unique sensor validation (will be different for each sensor)
corr_preshpa = (preshpa + 10); //create space for correction of pressure according to unique sensor validation (will be different for each sensor)
Serial.print(F("Temp: "));
Serial.print(corr_temp);
Serial.print("°" + String(tempUnit == BME280::TempUnit_Celsius ? 'C' : 'F'));
Serial.print(F("\t\tHumidity: "));
Serial.print(corr_hum);
Serial.print(F("% RH"));
Serial.print(F("\t\tPressure: "));
Serial.print(corr_preshpa);
Serial.println(F(" hPa"));
}
void GetPM_Readings(){
// /******************GET PM SENSOR DATA*****************************/
boolean ret = aqi.read(&data);
Serial.println(ret);
if (ret) {
Serial.println(F("AQI reading success"));
// Serial.println();
Serial.println(F("---------------------------------------"));
Serial.println(F("Concentration Units (standard)"));
Serial.println(F("---------------------------------------"));
Serial.print(F("PM 1.0: ")); Serial.print(data.pm10_standard);
Serial.print(F("\t\tPM 2.5: ")); Serial.print(data.pm25_standard);
Serial.print(F("\t\tPM 10: ")); Serial.println(data.pm100_standard);
Serial.println(F("Concentration Units (environmental)"));
Serial.println(F("---------------------------------------"));
Serial.print(F("PM 1.0: ")); Serial.print(data.pm10_env);
Serial.print(F("\t\tPM 2.5: ")); Serial.print(data.pm25_env);
Serial.print(F("\t\tPM 10: ")); Serial.println(data.pm100_env);
Serial.println(F("---------------------------------------"));
Serial.print(F("Particles > 0.3um / 0.1L air:")); Serial.println(data.particles_03um);
Serial.print(F("Particles > 0.5um / 0.1L air:")); Serial.println(data.particles_05um);
Serial.print(F("Particles > 1.0um / 0.1L air:")); Serial.println(data.particles_10um);
Serial.print(F("Particles > 2.5um / 0.1L air:")); Serial.println(data.particles_25um);
Serial.print(F("Particles > 5.0um / 0.1L air:")); Serial.println(data.particles_50um);
Serial.print(F("Particles > 10 um / 0.1L air:")); Serial.println(data.particles_100um);
Serial.println(F("---------------------------------------"));
}
}
void GetVOC_Readings(){
/*****************GET VOC**********************/
a = analogRead(Aout);
b = digitalRead(Dout);
Serial.print("D0:");
Serial.print(b);
Serial.print(" A0:");
Serial.println(a);
}
void print2SD(){
/*********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 = SD.open("datalog.csv", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
//dataFile.print(cm); dataFile.print(",CM,");
dataFile.print("\n");
dataFile.print(rtcy);
dataFile.print("/");
dataFile.print(rtcd);
dataFile.print("/");
dataFile.print(rtcm);
dataFile.print(",");
dataFile.print(rtchr);
dataFile.print(":");
dataFile.print(rtcmin);
dataFile.print(":");
dataFile.print(rtcs);
dataFile.print(",");
dataFile.print(corr_temp);
dataFile.print(",");
dataFile.print(corr_preshpa);
dataFile.print(",");
dataFile.print(corr_hum);
dataFile.print(",");
dataFile.print(b);
dataFile.print(",");
dataFile.print(a);
dataFile.print(",");
dataFile.print(data.particles_03um);
dataFile.print(",");
dataFile.print(data.particles_25um);
dataFile.print(",");
dataFile.print(data.particles_100um);
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(F("error opening datalog.csv"));
}
delay(20);
}
void GetRTC_Readings(){
/*********GET TIME ************/
time_t p; //create time object for time and date stamp
p=RTC.get(); //gets the time from RTC
Serial.print(year(p));
Serial.print('/');
Serial.print(month(p));
Serial.print('/');
Serial.print(day(p));
Serial.print(" (");
// Serial.print(daysOfTheWeek[dayOfTheWeek(p)]);
Serial.print(") ");
Serial.print(hour(p));
Serial.print(':');
Serial.print(minute(p));
Serial.print(':');
Serial.print(second(p));
Serial.println();
//Serial.println(String(hour(p))+":"+String(minutes(p))+":"+String(second(p)));
rtcs = second(p);
rtcmin = minute(p);
rtchr = hour(p);
rtcy = year(p);
rtcm = month(p);
rtcd = day(p);
}
// ***********************End of Code -- you are DONE!*******************************