Hi,
been trying to solve that for over a mont, but no chance. Random freezing after a few hours. I suspect a memory leak in either of the 2 functions:
char * timeprint(DateTime nowtime)
void logsd(float array_sensor[6][2], byte hyst, const char *datastatus)
// TO FIX
//xxxincrease hysteresis to 10
//add solar panel
//xxxfix writing
//xxxfix error 85 and wrong number
// check if better to use temp tuy for stopping
// ********************* LIBS *************************************
// For ds18b20 temperature sensor to work, needs 2 libraries: DallasTemperature by Miles Burton & al and OneWire by Jim Studt & al
#include <OneWire.h> //downgrading from 2.35 to 2.30 as a possible solution for the 85 deg problem
#include <DallasTemperature.h>
// For I2C (LCD and clock)
#include <Wire.h>
// For LCD
#include <LiquidCrystal_I2C.h> //needs to add library
// For SD
#include <SPI.h>
#include <SD.h>
// For sleep
#include <LowPower.h>
// For clock
#include <RTClib.h>
//for watchdog
#include <avr/wdt.h>
#include <avr/pgmspace.h>
// ********************* CONST *************************************
// pins const byte vs define doesn't change memory use or even using number in code
#define WAKEUPPIN 2 //get the clock signal
#define BUTTONPIN 3 //button to show screen
#define DAMPERCLOSEPIN 4 //to close the damper and set fan to blow inside house
#define DAMPEROPENPIN 5 //to open the damper and set fan to blow inside capteur
#define FANPIN 6 //to start fan either direction
#define ONE_WIRE_BUS 8 //bus to read temp sensors
#define BATTERYV A1 // battery voltage
#define POT A3 //potentiometer to set temp diff
// temp sensors in one wire bus and in sensor array and in tsensor
#define TEMPCAP 0 //sensor nber for temp inside capteur
#define TEMPTUY 1 //sensor nber for temp exit pipe
#define TEMPEXT 2 //sensor nber for temp ext
#define TEMPMAIS 3 //sensor nber for temp int mais
//index in sensor array
#define TEMPDIFF 4
#define BATT 5
//const
#define FILEDATA "logfile.csv"
#define HYSTERESIS 10 //in degree
#define LOGDELAY 1 //number of sleep interrupts between logs under 255
#define LCDDELAY 30 //lcd stays on for that many seconds after button pressed
#define ALARMSECONDS 60 //nber of seconds between each wake up, need to be high than time to process loop >4s
#define BUFF_SIZE 10 // 10 data piece for each sensor
#define LOGTIME 10 // time in s to log after alarm triggered SHOULD BE BIGGER THAN DURATION OF LOOP AND LOWER THAN ALARMSECONDS
// ********************* GLOBAL VAR AND OBJECTS *************************************
// Global variables
unsigned long PreviousSecondsLCD = 0; // last we wrote to lcd
volatile boolean SDok = false; // status of SD reader
volatile byte syststatus = 4; // 0 for off, 1 for normal run, 2 for summer run, 4 for start undetermined
volatile boolean ButtonPressed = false; // status of button
boolean lcdon = false; // status of lcd
volatile boolean alarmset = false; //alarm status
volatile byte timeforsaving = 0; //keeps track of number of wake up of alarm for knowing when to save data, under 255
boolean writtingps = false; //is writing on SD in ps
volatile unsigned long timesetalarm=0; //time for next alarm
volatile unsigned long ventstarttime=0; //last time the vent started operating
volatile float testtemp=2; //timer in unixtime
volatile int nbersensorpb=0; //becomes true if more than 10 sensor problems in a row
volatile long nberrun=0;
// Global object for sensors
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with sensors
DallasTemperature sensors(&oneWire); // Pass oneWire reference to DallasTemperature library
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display
RTC_DS3231 rtc; //for the clock
DeviceAddress tsensor[4]=
{
{ 0x28, 0xEE, 0x16, 0xBE, 0x33, 0x20, 0x01, 0xE5 }, //temp capt num 0
{ 0x28, 0x11, 0x3E, 0xC0, 0x63, 0x20, 0x01, 0xB3 }, //temp tuyau num 1
{ 0x28, 0x73, 0x29, 0x90, 0x63, 0x20, 0x01, 0xEB }, //temp ext num 2
{ 0x28, 0x97, 0x94, 0xD2, 0x33, 0x20, 0x01, 0x21 } //temp mais num 3
};
//text string in progmem to save memory
const char msg_start[] PROGMEM = {"************************** STARTING *****************************"};
const char msg_header[] PROGMEM = {"temp_cap,temp_tuy,temp_ext,temp_mais,temp_diff,hyst,battv,syststatus"};
const char msg_sensorerror[] PROGMEM = {"Not doing anything as sensor trouble"};
const char msg_startnormal[] PROGMEM = {"Starting normal operations"};
const char msg_stopnormal[] PROGMEM = {"Stopping normal operations"};
const char msg_startsummer[] PROGMEM = {"Starting summer operations"};
const char msg_stopsummer[] PROGMEM = {"Stopping summer operations"};
const char msg_stoptrouble[] PROGMEM = {"Stopping Sensor trouble"};
const char msg1[] PROGMEM = {"1"};
const char msg2[] PROGMEM = {"2"};
const char msg3[] PROGMEM = {"3"};
const char msg4[] PROGMEM = {"4"};
const char msg5[] PROGMEM = {"5"};
const char msg6[] PROGMEM = {"6"};
const char msg7[] PROGMEM = {"7"};
const char msg8[] PROGMEM = {"8"};
const char msg9[] PROGMEM = {"9"};
const char msg10[] PROGMEM = {"10"};
const char msg11[] PROGMEM = {"11"};
const char msg12[] PROGMEM = {"12"};
const char msg13[] PROGMEM = {"13"};
const char msg14[] PROGMEM = {"14"};
const char msg15[] PROGMEM = {"15"};
const char msg16[] PROGMEM = {"16"};
const char msg17[] PROGMEM = {"17"};
const char msg18[] PROGMEM = {"18"};
const char msg19[] PROGMEM = {"19"};
const char msg_sleep[] PROGMEM = {"going to sleep"};
const char msg_wakeup[] PROGMEM = {"waking up"};
const char type_linetype[] PROGMEM = {"line_type"};
const char type_status[] PROGMEM = {"status"};
const char datatype_status[] PROGMEM = {"statusdata"};
const char datatype_data[] PROGMEM = {"data"};
// ********************* FUNCTIONS *************************************
//return temperature for one of the sensor, need to have the sensors initialised before calling
float readTemp(int sensor)
{
return sensors.getTempC(tsensor[sensor]);
}
//return pot value
float readPot(){
float temppot;
temppot=0;
for (int i=0; i< BUFF_SIZE; i++) {
temppot=temppot+map(analogRead(POT),0,1023,0,40);
}
return temppot/BUFF_SIZE;
}
//return batt value
//resistor of 333 and 1000 ohm
float readBatt(){
float tempbat;
tempbat=0;
for (int i=0; i< BUFF_SIZE; i++) {
tempbat=tempbat+1333 / 333 * analogRead(BATTERYV) * (5.0 / 1023.0);
}
return tempbat/BUFF_SIZE;
}
//print the data on lcd
void lcdprintvalue(float sensor_array[6][2], byte hysteresis)
{
if (!lcdon){
PreviousSecondsLCD = rtc.now().unixtime();
lcdon=true;
}
if (rtc.now().unixtime() - PreviousSecondsLCD < LCDDELAY){
if (nbersensorpb<=10){
lcd.setCursor(0, 0); lcd.print(F("Cap=")); lcd.setCursor(4, 0); lcd.print(sensor_array[0][0],1);
lcd.setCursor(10, 0); lcd.print(F("Tuy=")); lcd.setCursor(14, 0); lcd.print(sensor_array[1][0],1);
lcd.setCursor(0, 1); lcd.print(F("Ext=")); lcd.setCursor(4, 1); lcd.print(sensor_array[2][0],1);
lcd.setCursor(10, 1); lcd.print(F("Mai=")); lcd.setCursor(14, 1); lcd.print(sensor_array[3][0],1);
lcd.setCursor(0, 2); lcd.print(F("Diff=")); lcd.setCursor(5, 2); lcd.print((byte)sensor_array[4][0]);
lcd.setCursor(10, 2); lcd.print(F("Hy=")); lcd.setCursor(14, 2); lcd.print((byte)hysteresis);
lcd.setCursor(0, 3); lcd.print(F("BatV=")); lcd.setCursor(5, 3); lcd.print(sensor_array[5][0]);
lcd.setCursor(13, 3); lcd.print(F("Fan "));
lcd.setCursor(17, 3);
switch (syststatus) {
case 0:
lcd.print(F("off"));
break;
case 1:
lcd.print(F("on "));
break;
case 2:
lcd.print(F("sum"));
break;
case 4:
lcd.print(F("xxx"));
break;
}
}
else{
// Serial.print(F("in the sensor problem loop"));
lcd.setCursor(0, 0); lcd.print(F("Sensor trouble"));
}
}
else {
noInterrupts();
ButtonPressed=false;
interrupts();
}
}
//return byte 2 digits with leading 0
char * convert2digits(byte x){
char static xtrg[3]; // static so the result is available outside but memory is never freed, still more readable than global var
char tempstr[3];
itoa(x,tempstr,10);
if (x<10){
strcpy(xtrg,"0");
strcat(xtrg,tempstr);
}
else {
strcpy(xtrg,tempstr);
}
return xtrg;
}
// return char with time
char * timeprint(DateTime nowtime){
char yr[5];
char static timetoprint[20]; // static so the result is available outside but memory is never freed, still more readable than global var
itoa(nowtime.year(),yr,10);
strcpy(timetoprint,yr);
strcat(timetoprint,"-");
strcat(timetoprint,convert2digits(nowtime.month()));
strcat(timetoprint,"-");
strcat(timetoprint,convert2digits(nowtime.day()));
strcat(timetoprint," ");
strcat(timetoprint,convert2digits(nowtime.hour()));
strcat(timetoprint,":");
strcat(timetoprint,convert2digits(nowtime.minute()));
strcat(timetoprint,":");
strcat(timetoprint,convert2digits(nowtime.second()));
return timetoprint;
}
void WriteMsgSD(const char *msg, const char *linetype){
WriteMsgSD(msg11,type_status);
while (writtingps) {
; // wait for previous writing to be finished
}
writtingps=true;
char fullline[100];
File myFile;
myFile = SD.open(FILEDATA, FILE_WRITE);
if (myFile){
strcpy(fullline,timeprint(rtc.now()));
strcat(fullline,",");
strcat_P(fullline,linetype);
strcat(fullline,",");
strcat_P(fullline,msg);
myFile.println(fullline);
//Serial.print(F("writemsgsd saving: "));Serial.println(fullline);
myFile.close();
}
writtingps=false;
WriteMsgSD(msg12,type_status);
}
//log sensor data to SD with data status msg, hysteresis and system status(global)
// need to make sure that each string as a an additional space for \0 otherwise random bug
void logsd(float array_sensor[6][2], byte hyst, const char *datastatus){
char temp_cap_c[8], temp_tuy_c[8],temp_ext_c[8], temp_mais_c[8], temp_diff_c[3],hyst_c[3],battv_c[6],syststatus_c[2];
char linetowrite[80];
WriteMsgSD(msg13,type_status);
while (writtingps) {
; // wait for previous writing to be finished
}
writtingps=true;
File myFile;
myFile = SD.open(FILEDATA, FILE_WRITE);
if (myFile){
timeprint(rtc.now());
strcpy(linetowrite,timeprint(rtc.now()));
strcat(linetowrite,",");
strcat_P(linetowrite,datastatus);
strcat(linetowrite,",");
dtostrf(array_sensor[0][0],6, 2, temp_cap_c);
strcat(linetowrite,temp_cap_c);
strcat(linetowrite,",");
dtostrf(array_sensor[1][0],6, 2, temp_tuy_c);
strcat(linetowrite,temp_tuy_c);
strcat(linetowrite,",");
dtostrf(array_sensor[2][0],6, 2, temp_ext_c);
strcat(linetowrite,temp_ext_c);
strcat(linetowrite,",");
dtostrf(array_sensor[3][0],6, 2, temp_mais_c);
strcat(linetowrite,temp_mais_c);
strcat(linetowrite,",");
itoa(array_sensor[4][0],temp_diff_c,10);
strcat(linetowrite,temp_diff_c);
strcat(linetowrite,",");
itoa(hyst,hyst_c,10);
strcat(linetowrite,hyst_c);
strcat(linetowrite,",");
dtostrf(array_sensor[5][0],6, 2, battv_c);
strcat(linetowrite,battv_c);
strcat(linetowrite,",");
itoa(syststatus,syststatus_c,10);// use an additional variable to save syststatus because of bug
strcat(linetowrite,syststatus_c);
myFile.println(linetowrite);
//Serial.print(F("logsd saving: "));Serial.println(linetowrite);
myFile.close();
}
writtingps=false;
WriteMsgSD(msg14,type_status);
}
void onAlarm() {
alarmset = false;
}
void onButton() {
ButtonPressed = true;
}
void sensor_loop (float array_avg[6][2]){
float data;
for (int j=0; j<6; j++){ // initialise array
array_avg[j][0]=0;
array_avg[j][1]=0;
}
for (int i=0; i< BUFF_SIZE; i++) { // take measures
for (int j=0; j<6; j++){ // loop through the temp sensors
switch (j) {
case 0 ...3:
data = readTemp(j);
break;
case 4:
data=readPot(); //took out of function to reduce prog size
break;
case 5:
data= readBatt(); //took out of function to reduce prog size
}
// Serial.print(F("data"));Serial.println(data);
if (data==-127 or data==85){//check sensor problem
array_avg[j][1] = array_avg[j][1]+1;
}
else {
array_avg[j][0] = array_avg[j][0]+data;
}
}
}
for (int j=0; j<6; j++){
if (array_avg[j][1]!=BUFF_SIZE){
array_avg[j][0] = array_avg[j][0]/(BUFF_SIZE-array_avg[j][1]);
}
else {
array_avg[j][0]=-127;
}
}
}
//return false if for one of the sensor there is only wrong values on mais or capt
boolean checkarray(float arraytocheck[6][2]){
boolean nopb = true;
if (arraytocheck[0][1]==BUFF_SIZE or arraytocheck[3][1]==BUFF_SIZE){
nopb = false;
}
return nopb;
}
int freeRam()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
void setup()
{
// Start serial communication for debugging purposes
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
//Serial.print(F("*******STARTING **** RAM at begining of setup:"));
//Serial.println(freeRam());
// Serial.print(F("running the setup at "));Serial.println(rtc.now().unixtime());
// Start lcd
lcd.init();
lcd.backlight();
// Start up the library for DallasTemperature on OneWire
sensors.begin();
// initialize the pins (not need for analog pin)
pinMode(BUTTONPIN, INPUT_PULLUP);
pinMode(FANPIN, OUTPUT);
pinMode(DAMPEROPENPIN, OUTPUT);
pinMode(DAMPERCLOSEPIN, OUTPUT);
pinMode(WAKEUPPIN, INPUT_PULLUP); //for accepting the interrupt signal from RTC DS3231
//initialize RTC
lcd.setCursor(0, 0);
if (!rtc.begin()) {
lcd.print(F("Couldn't find RTC"));
}
else{
lcd.print(F("Found RTC"));
}
//set RTC time at each compile
// Following line sets the RTC to the date & time this sketch was compiled
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Comment out below lines once you set the date & time.
// Following line sets the RTC with an explicit date & time
// for example to set January 27 2022 at 02:20 you would call:
// rtc.adjust(DateTime(2022, 03, 10, 05, 49, 0));
//intialise the SD and RTC and write its state on lcd even if off
lcd.setCursor(0, 1);
SDok = SD.begin(10);
if (!SDok) {
lcd.print(F("SD init failed!"));
// Serial.println(F("CARD not OK"));
}
else {
lcd.print(F("CARD OK"));
//Serial.println(F("CARD OK"));
WriteMsgSD(msg_header,type_linetype);
WriteMsgSD(msg_start,type_status);
}
// print RTC time on LCD for a few seconds
timeprint(rtc.now());
lcd.setCursor(0, 3);
lcd.print(timeprint(rtc.now()));
delay(5000);
lcd.noBacklight();
lcdon=false;
lcd.clear();
//clear any pending alarms !! it doesn't need to be done every time before sleeping
rtc.clearAlarm(1);
rtc.clearAlarm(2);
//Set SQW pin to OFF
rtc.writeSqwPinMode(DS3231_OFF);
// turn off alarm 2 (in case it isn't off already)
rtc.disableAlarm(2);
//set interrupt for button
attachInterrupt(digitalPinToInterrupt(BUTTONPIN), onButton, FALLING);
//!!!!!! changed to low for stability
//set interrupt for RTC alarm
attachInterrupt(digitalPinToInterrupt(WAKEUPPIN), onAlarm, FALLING);
//!!!!!! changed to low for stability
timesetalarm = rtc.now().unixtime()+ALARMSECONDS;
noInterrupts();
alarmset=true;
interrupts();
rtc.setAlarm1(timesetalarm, DS3231_A1_Second); // this mode triggers the alarm when the minutes match. See Doxygen for other options)
timesetalarm=timesetalarm+ ALARMSECONDS;
timeforsaving++;
//timertest=31;
wdt_enable(WDTO_8S); //8s is ok as long as the processing of the main loop doestn't last longer than 8s (for now 2s)
}
//*******************************************************************************
//*******************************************************************************
void loop() {
WriteMsgSD(msg_wakeup,type_status);
//!!!!!!!!!!to check with other arduino
//Serial.write("Y",1);// to wake up other arduino
// delay(500);
//Serial.write("Y",1);// to confirm other arduino
//!!!!!!!!!!to check with other arduino
delay(500);
// Serial.print(F("starting loop at "));Serial.println(rtc.now().unixtime());
sensors.requestTemperatures(); //done here rather than in the function to avoid reapeating it multiple times
// delay(1000); //give time to temp sensors to initialize
//reading the sensors with BUFFER_SIZE value average
//using a global array and not passing it doesn't affect memory usage
float array_sensor[6][2]; //row= 0 to 3 for temp, 4 for temp_diff,5 for battv
sensor_loop(array_sensor);
// Serial.print(F("read temp at "));Serial.println(rtc.now().unixtime());
WriteMsgSD(msg1,type_status);
// log to SD every LOGDELAY times, will be done after psing so may not be exactly spaced in time
// and will be more often when lcd on
if (SDok){
if (timeforsaving==LOGDELAY) {
// Serial.print(F("starting writing to SD at "));Serial.println(rtc.now().unixtime());
logsd(array_sensor, HYSTERESIS,datatype_data);
timeforsaving = 0;
WriteMsgSD(msg2,type_status);
// delay((LOGTIME-(rtc.now().unixtime()-(timesetalarm-ALARMSECONDS)))*1000);
// Serial.print(F("done writing to SD at "));Serial.println(rtc.now().unixtime());
}
}
boolean sensorpb = not(checkarray(array_sensor));
//Serial.print(F("the value of sensorpb "));Serial.println(sensorpb);
if (sensorpb) {
WriteMsgSD(msg_sensorerror,type_status);
nbersensorpb++;
}
else {
nbersensorpb=0;
}
WriteMsgSD(msg3,type_status);
//array_sensor[0][0] = 500; //capteur
//array_sensor[3][0] = 10; //mais
/*
for (int i=0; i< 6; i++) {
Serial.print(F("temp"));Serial.print(i);Serial.print(F(": "));Serial.println(array_sensor[i][0]);
delay(500); //give time to temp sensors to print
}
*/
//no summer mode for testing
boolean issummer = (rtc.now().month()==7 or rtc.now().month()==8);
//array_sensor[0][0]=80;
// Serial.print(F("before loop on motor "));Serial.println(rtc.now().unixtime());
WriteMsgSD(msg4,type_status);
if (!sensorpb){
if (!issummer){
//open or close airvent.Start based on cap temp, stop based on tuy temp. Check hysteresis necessary
if (array_sensor[0][0] - array_sensor[3][0] - array_sensor[4][0] - HYSTERESIS>= 0 && syststatus!=1){ //must run based on temp_cap - temp_mais
digitalWrite(DAMPERCLOSEPIN, LOW);
digitalWrite(DAMPEROPENPIN, HIGH);
ventstarttime=rtc.now().unixtime();
digitalWrite(FANPIN, HIGH);
syststatus=1;
WriteMsgSD(msg_startnormal,type_status);//"Starting normal operations","status");
logsd(array_sensor, HYSTERESIS,datatype_status);
// Serial.println(F("start normal"));
delay(500); //give time to temp sensors to initialize
}
if (array_sensor[0][0] - array_sensor[3][0] - array_sensor[4][0] - HYSTERESIS <= -HYSTERESIS && syststatus!=0){ //must stop based on temp_cap - temp_mais
digitalWrite(DAMPEROPENPIN, LOW);
digitalWrite(DAMPERCLOSEPIN, HIGH);
ventstarttime=rtc.now().unixtime();
digitalWrite(FANPIN, LOW);
syststatus=0;
WriteMsgSD(msg_stopnormal,type_status);//"Stopping normal operations","status");
logsd(array_sensor, HYSTERESIS,datatype_status);
// Serial.println(F("stop normal"));
delay(500); //give time to temp sensors to initialize
}
}
else {
if (array_sensor[0][0]>50 && syststatus!=2) {
digitalWrite(DAMPEROPENPIN, LOW);
digitalWrite(DAMPERCLOSEPIN, HIGH);
ventstarttime=rtc.now().unixtime();
digitalWrite(FANPIN, HIGH);
syststatus=2;
WriteMsgSD(msg_startsummer,type_status);//"Starting summer operations","status");
logsd(array_sensor, HYSTERESIS,datatype_status);
delay(500); //give time to temp sensors to initialize
}
if (array_sensor[0][0]<45 && syststatus!=0) { // use 5 as hysteresis
digitalWrite(DAMPEROPENPIN, LOW);
digitalWrite(DAMPERCLOSEPIN, HIGH);
ventstarttime=rtc.now().unixtime();
digitalWrite(FANPIN, LOW);
syststatus=0;
WriteMsgSD(msg_stopsummer,type_status);//"Stopping summer operations","status");
logsd(array_sensor, HYSTERESIS,datatype_status);
delay(500); //give time to temp sensors to initialize
}
}
}
else {
if (nbersensorpb>10){//in case more than 10 sensor pb in a row, switch off
digitalWrite(DAMPEROPENPIN, LOW);
digitalWrite(DAMPERCLOSEPIN, HIGH);
ventstarttime=rtc.now().unixtime();
digitalWrite(FANPIN, LOW);
syststatus=0;
WriteMsgSD(msg_stoptrouble,type_status);//"Stopping normal operations","status");
logsd(array_sensor, HYSTERESIS,datatype_status);
delay(500); //give time to temp sensors to initialize
}
}
WriteMsgSD(msg5,type_status);
//switch of vent relay after 30s of last activation
if (ventstarttime!=0 && rtc.now().unixtime()-ventstarttime>30){
digitalWrite(DAMPERCLOSEPIN, LOW);
digitalWrite(DAMPEROPENPIN, LOW);
ventstarttime=0;
}
WriteMsgSD(msg6,type_status);
//display values on LCD if needed
//TO DO: change cond to be on ButtonPressed and put the switch off in the function
//this would avoid having to wait for next loop before switching off
noInterrupts();
boolean ButtonPressed_temp=ButtonPressed;
interrupts();
if (!ButtonPressed_temp){
if (lcdon){
lcd.noBacklight();
lcd.clear();
lcdon = false; // could be in the lcdprintini
}
}
else {
lcd.backlight();
lcd.clear();
lcdprintvalue(array_sensor,HYSTERESIS);
}
WriteMsgSD(msg7,type_status);
// manage alarm
noInterrupts();
boolean alarmset_temp = alarmset;
interrupts();
if (!alarmset_temp){
rtc.clearAlarm(1); // this and below cannnot be done in interrupt
rtc.setAlarm1(timesetalarm, DS3231_A1_Second); // this mode triggers the alarm when the minutes match. See Doxygen for other options)
noInterrupts();
alarmset = true;
interrupts();
timesetalarm=timesetalarm+ ALARMSECONDS;
timeforsaving++;
WriteMsgSD(msg8,type_status);
}
wdt_disable();
WriteMsgSD(msg9,type_status);
if (!lcdon && !writtingps){
WriteMsgSD(msg_sleep,type_status);
Serial.print(F("----------- going to sleep --------------- at "));Serial.println(rtc.now().unixtime());
delay(500);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); //arduino enters sleep mode here
}
WriteMsgSD(msg10,type_status);
Serial.print(F("----------- waking up --------------- at "));Serial.println(rtc.now().unixtime());
delay(500);
}
Any help much appreciated
Thanks in advance