DS1307 timestamp problem

Hi, the following code is from a program that is too big to be posted. I only posted part of it. The setup part is below in case it is required. I left everything even non related to RTC since simple RTC code work but not this. Maybe there is conflicting device in my bigger program.

It is a simple code that run on arduino uno that fetch time from a RTC DS1307 and send it to the serial port. Thing is, when I test it in a simple DS1307 code, it work fine but when I copy it to my bigger program, the two lines "Timestamp_date and Timestamp_Time don't return anything while the other time related lines returns correct time data. This suggest the RTC work fine but don't respond to the now.timestamp command.

I can't figure why it work in a test code and not anymore in the bigger code. Any suggestion?

PROBLEMATIC CODE HERE:

void Send_to_PC() {
  // Send data to monitor
  if (Serialport) {
    // Fetch time data
    DateTime now = rtc.now();    // fetch actual date and time
    // Assembling and copying the data string
    Serial.print(now.timestamp(DateTime::TIMESTAMP_DATE));   /// LINE NOT WORKING
    Serial.print(" "); 
    Serial.print(now.timestamp(DateTime::TIMESTAMP_TIME));   /// LINE NOT WORKING
    Serial.print(" ");
    Serial.print(now.year(), DEC);
    Serial.print("/");
    Serial.print(now.month(), DEC);
    Serial.print("/");
    Serial.print(now.day(), DEC);
    Serial.print(" ");
    Serial.print(now.hour(), DEC);
    Serial.print(":");
    Serial.print(now.minute(), DEC);
    Serial.print(":");
    Serial.print(now.second(), DEC);
    Serial.print(" ");
    Serial.print(Ref_flag);
    Serial.print(" ");
    Serial.print(Cycle_completed);
    Serial.print(" ");
    Serial.print(Atm_temp);
    Serial.print(" ");
    Serial.print(Atm_Humi);
    Serial.print(" ");
    Serial.print(Atm_hPa);
    Serial.print(" ");
    Serial.print(Chamber_hPa);   // hPa
    Serial.print(" ");
    Serial.print(Sensor_offset); // hPa
    Serial.print(" ");
    Serial.print(Bubble_vol);    // mL
    Serial.print(" ");
    Serial.print(CH4_chamber);   // %
    Serial.print(" ");
    Serial.print(DegreC);        // %
    Serial.print(" ");
    Serial.println(z);           // Compteur
  }

SETUP CODE HERE JUST IN CASE:

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

RTC_DS1307 rtc;                         // define the Real Time Clock object

Adafruit_MPRLS MPRLS = Adafruit_MPRLS(); // MPRLS Object

BME280I2C bme;    // Default : forced mode, standby time = 1000 ms
                  // Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,

int z;
int Event;
int Bubble_flag;
char daysOfTheWeek[7][24] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
float MPRLS_hPa;
float Chamber_hPa;
float Chamber_volume;
float Atm_hPa;
float Atm_temp;
float Atm_Humi;
float Bubble_vol;
bool Serialport;
bool Ref_flag;       // 0 = Monitoring mode tag              1 = ref line tag
float Vol_threshold;
float DegreC;
float CH4_chamber;

float Sensor_offset;
int Cycle_completed;
int Relay_SGX = 2;   // Heating the SGX sensor
int Relay_Vent = 3;  // Open solenoid
int Relay_Pump = 4;  // Pump air out
const int chipSelect = 10;
File logfile;

void setup() {
  Serialport = 1;                  // Set to false when not testing
  if (Serialport) {
    Serial.begin(57600);
    Serial.println("Serial connected");
  }
  pinMode(10, OUTPUT);             // Chip select pin for SD card
  pinMode(Relay_SGX, OUTPUT);      // Relay SGX
  pinMode(Relay_Vent, OUTPUT);     // Relay Sol 1
  pinMode(Relay_Pump, OUTPUT);     // Relay Pump
  MPRLS.begin();
  bme.begin();

  // Initializing RTC
  Wire.begin();
  ///////////////////////////////
#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif
 ///////////////////////////////
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);        // Will stop here if RTC have problem
  }
  Serial.println("RTC connected");

  if (! MPRLS.begin()) {
    Serial.println("Couldn't find MPRLS");
    while (1);        // Will stop here if MPRLS have problem
  }
  Serial.println("MPRLS connected");

  if (! bme.begin()){
    Serial.println("Couldn't find bme");
    while (1); // will stop here if BME have problem
  }
  Serial.println("BME280 connected");

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // Cette commande induit un délai d'environ 5 sec vs ordi
     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(2014, 1, 21, 3, 0, 0));
  }

  
  // SD card initialization
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");  // Will stop here if the card have problem
  }
  Serial.println("SD card initialized.");

  // create a new file on SD card
  char filename[] = "BUBBLE00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop
    }
  }

  
  // Monitoring info
  Serial.print("Filename is: ");
  Serial.println(filename);
  Serial.println("File header is:");
  Serial.println("Cycle_completed Atm_temp Humidity Atm_hPa Chamber_hPa Sensors_offset Bubble_volume CH4_chamber SGX_temp z"); // Put the correct Header here
  logfile.println("Cycle_completed Atm_temp Humidity Atm_hPa Chamber_hPa Sensors_offset Bubble_volume CH4_chamber SGX_temp");  // Must be identical as previous line

  Chamber_volume = 200;         // Ajust this volume to match the chamber in mL
  Sensor_offset = 0;            // initial offset
  Ref_flag = 1;                 // The program will start by adjusting the pressure offset between sensors
  Cycle_completed = 0;
  z = 0;
  Bubble_flag = 0
  Event = 0;
}

thank you for your help

Most probably you run out of memory. As the timestamp method uses at least 40 bytes of memory that's not so improbable.

This was among my hypothesis if the code was good. Apparently it's the case. When I compile the program it use 82% of the memory and it say low memory could cause instability. 365 octet left. 1683 octet used.

Does someone have suggestion to make these part of the code less hungry on memory? Note that for this application I need at least 2 decimal and my calibration factor are up to 5 decimals (Ex: Bt). I also have at least one more sensor to add. I tried to post the whole code but it is too big. 9000 characters allowed.

void Get_Chamber_CH4() {
  float A = 0.0035;
  float B = 0.7010;
  float C = 0.6000;
  float At = 0.42400;
  float Bt = 0.00625;
  int out = analogRead(A0);    // Sortie du capteur  Pin 4
  int ref = analogRead(A1);    // Voltage divider ajusté à 0 (1koHm + 50 ohm)
  int temp = analogRead(A2);   // Voltage du capteur de temp. Pin 6
  float Vout = out * (5.00 / 1023.00);   // Conversion en volt Ref de 5 Volts
  float Vref = ref * (5.00 / 1023.00);   // Conversion en volt Ref de 5 Volts
  float Vtemp = temp * (5.00 / 1023.00); // Conversion en volt Ref de 5 Volts
  float Delta = Vout - Vref;             // Differentiel du wheatsone bridge
  CH4_chamber = A * Delta * Delta + B * Delta + C; //  Conversion en % ppm CH4
  DegreC = (Vtemp - At)/Bt;                       //  Conversion en degrée celcius
}
void Get_Pressure() {
  // BME280
  float temp(NAN), hum(NAN), pres(NAN);
  BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
  BME280::PresUnit presUnit(BME280::PresUnit_hPa);
  bme.read(pres, temp, hum, tempUnit, presUnit);
  Atm_hPa = pres;
  Atm_temp = temp;
  Atm_Humi = hum;
  // MPRLS
  MPRLS_hPa = MPRLS.readPressure(); // Pressure in hPa
 // Sensor_offset = pres - MPRLS_hPa; 
  Chamber_hPa = MPRLS_hPa + Sensor_offset; 
  //Bubble volume determination
  Bubble_vol = (Chamber_hPa * Chamber_volume / Atm_hPa) - Chamber_volume; // mL
}

This part is the variable declaration before the setup section. Lots of float!

int z;
int Event;
int Bubble_flag;
char daysOfTheWeek[7][24] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
float MPRLS_hPa;
float Chamber_hPa;
float Chamber_volume;
float Atm_hPa;
float Atm_temp;
float Atm_Humi;
float Bubble_vol;
bool Serialport;
bool Ref_flag;       // 0 = Monitoring mode tag              1 = ref line tag
float Vol_threshold;
float DegreC;
float CH4_chamber;

float Sensor_offset;
int Cycle_completed;
int Relay_SGX = 2;   // Heating the SGX sensor
int Relay_Vent = 3;  // Open solenoid
int Relay_Pump = 4;  // Pump air out
const int chipSelect = 10;
File logfile;

Some other question:
Is the comment text use Arduino memory?

Numerous Void function take more memory than a bunch of code in one loop?

Declaring variable at the very beginning is better on memory than inside a void? (Sometime it don't work and I was force to put the variables in the specific void).

thank you

When I compile the program it use 82% of the memory and it say low memory could cause instability. 365 octet left. 1683 octet used.

Using the SD library you run out of memory from the beginning (it reserves a memory region of block size: 512 bytes).

Does someone have suggestion to make these part of the code less hungry on memory?

Post complete code! Attach it to the post if it's to big to be included using code tags.

Is the comment text use Arduino memory?

No. But literal strings does!

Numerous Void function take more memory than a bunch of code in one loop?

A void function is just a subroutine with no return value.

Declaring variable at the very beginning is better on memory than inside a void? (Sometime it don't work and I was force to put the variables in the specific void).

That depends. A global variable uses it's memory for the complete time the sketch runs while a local variable exists only (and so uses memory) during the time the subroutine runs.

Thank you for all this informations. I will cut on litteral string length for sure and make local variable as most as I can.

For the SD library, I need to keep it. It will be a datalogging device.

As per your suggestion, the full code is attached to this post.

Thank you again

Bubble_0818.ino (10.2 KB)

Try putting many of your literal strings into PROGMEM and using the F function.

You also use the same substring in many places such as:

Serial.println("Couldn't find RTC");
Serial.println("Couldn't find MPRLS");
Serial.println("Couldn't find bme");

Which you could replace with a string from Flash (PROGMEM) and a short literal and consider shortening the description e.g
Serial.println("BME not found");
then
const char not_found[] PROGMEM = {" not found"};

Serial.print("BME");
Serial.println(F(not_found));

Serial.println(F(not_found));

The F() macro only works with string literals, if you want to print a string stored in flash memory then cast it to __FlashStringHelper*

Serial.println((__FlashStringHelper*)not_found);

Whoops, my mistake, David is entirely correct. Teach me to pay more attention when I change my mind half way through making a comment.

You can of course define a macro especialy if you are going to use it often, such as:

#define FV(s) ((__FlashStringHelper*)(s))

const char not_found[] PROGMEM = {" not found"};
const char bme_s[] PROGMEM = {"BME"};
.
.
Serial.print(FV(bme_s));
Serial.println(FV(not_found));

A bit of explanation of why you would want to place commonly used strings into PROGMEM manually instead of using multiple identical F("") in the print statements.

When you are using identical string literals that are stored in RAM

Serial.println("text literal");

//more code here

Serial.println("text literal");

//even more code here

Serial.print("text literal");

the compiler will recognize that all the text is identical, and will only store a single copy of the text in RAM, referencing it in each of the statements where it is used.

If instead you use the F() macro to store the text in PROGMEM

Serial.println(F("text literal"));

//more code here

Serial.println(F("text literal"));

//even more code here

Serial.print(F("text literal"));

the compiler will not take into account that the text is identical, and will instead store a separate copy of the text for each use.

Also be careful you do not incorrectly declare the text as a char * instead of as a char array

const char * const someText PROGMEM = "text literal";
//someText is a char* that points to the memory address where "text literal" is stored
//someText is stored in PROGMEM
//the text itself is stored in RAM

const char someText[] PROGMEM = "text literal";
//the text itself is stored in PROGMEM