Store and lock a datetime value

Hello !
I can’t understand why i cannot store and lock my datetime value.
What i am trying to do is, when an event occurs (i == 5 in the sample below), store the datetime when the event occurs.
The problem is that my variable (here storedTime) value changes to be equals to the RTC time…

well, tell me if i am not clear enough…
here is a sample code :

#include <Wire.h>

void setup() {
  Serial.begin(9600);
  analogReference(EXTERNAL);
  Wire.begin(); 
}

char *storedTime;
int i = 0;
void loop()
{
  Serial.print("RTC Value : ");
  Serial.println(getRTC());
  Serial.print("Stored time : ");
  Serial.println(storedTime);
  Serial.println("------------------------------------------");
  delay(1000);
  if(i == 5) {
    Serial.println("Condition raised !");
    storedTime = getRTC();
  }
  i++;
}


char* datetimeBuffer = new char[25];
char *getRTC()
{
  delete [] datetimeBuffer; 
  char *wdBuffer; //week day buffer
  // send request to receive data starting at register 0
  Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
  Wire.write((byte)0); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7); // request seven bytes (ss, mi, hr, wd, dd, mo, yy)

  while(Wire.available())
  { 
    byte ss = Wire.read(); // get seconds
    byte mi = Wire.read(); // get minutes
    byte hh = Wire.read(); // get hours
    byte wd = Wire.read();
    byte dd = Wire.read();
    byte mo = Wire.read();
    byte yr = Wire.read();

    switch (wd) {
    case 1: 
      wdBuffer = "Mon"; 
      break;
    case 2: 
      wdBuffer = "Tue"; 
      break; 
    case 3: 
      wdBuffer = "Wed"; 
      break; 
    case 4: 
      wdBuffer = "Thu";
      break; 
    case 5: 
      wdBuffer = "Fri";
      break; 
    case 6: 
      wdBuffer = "Sat";
      break; 
    case 7: 
      wdBuffer = "Sun";
      break;
    default: 
      wdBuffer = "Bad";
    }
    sprintf(datetimeBuffer,"%02u/%02u/%02u(%3s) %02u:%02u:%02u",bcdToDec(dd),bcdToDec(mo),bcdToDec(yr) + 2000,wdBuffer,bcdToDec(hh),bcdToDec(mi),bcdToDec(ss));
  }
  return(datetimeBuffer);
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

And here is the Serial output (storedTime is always equals to getRTC) :

RTC Value : 29/10/2013(Tue) 20:32:03
Stored time : 
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:04
Stored time : 
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:05
Stored time : 
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:06
Stored time : 
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:07
Stored time : 
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:08
Stored time : 
------------------------------------------
Condition raised !
RTC Value : 29/10/2013(Tue) 20:32:09
Stored time : 29/10/2013(Tue) 20:32:09
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:10
Stored time : 29/10/2013(Tue) 20:32:10
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:11
Stored time : 29/10/2013(Tue) 20:32:11
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:12
Stored time : 29/10/2013(Tue) 20:32:12
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:13
Stored time : 29/10/2013(Tue) 20:32:13
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:14
Stored time : 29/10/2013(Tue) 20:32:14
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:15
Stored time : 29/10/2013(Tue) 20:32:15
------------------------------------------

Look at your code - right after the condition is raised, you call

storedTime = getRTC();

and then mere microseconds later back at the top of loop you call it again,
so barely any time has elapsed.

If you want to see it change, put some delay in here

  if(i == 5) {
    Serial.println("Condition raised !");
    storedTime = getRTC();
  }

I am not sure to understand your answer.

If you want to see it change, put some delay in here

I don’t want to see it change !
What i want is to store the RTC value in the var called “storedTime” when i==5, and keep this value until i decide to explicitely change it, like this :

Condition raised !
RTC Value : 29/10/2013(Tue) 20:32:09
Stored time : 29/10/2013(Tue) 20:32:09 <-- condition is raised so storedTime equals getRTC()
------------------------------------------
RTC Value : 29/10/2013(Tue) 20:32:10 <-- normal : RTC continue to increase
Stored time : 29/10/2013(Tue) 20:32:10 <-- NOT normal : should remains equal to "storedTime" setted when condition was raised (shoud be 29/10/2013(Tue) 20:32:09)

Ah, I see - you are not setting storedTime, yet it appears to be increment the seconds all the time anyway. I can't see how it is doing that.

At the same time, I don't see how i++ is increasing in value either? I would use i=i+1; for that, makes it more obvious to me what is happening:

x++; // increment x by one and returns the old value of x ++x; // increment x by one and returns the new value of x

i is increasing because of “void loop { …delay (1000)… }”
Just the same as you said : i=i+1 (i’ve tried that : same result).

strings (in lower case) are null terminated and null is 0.

the char* storedTime is not initialized so (if memory serves) it default to address 0.

Now look at what you do

char *storedTime;
int i = 0;
void loop()
{
  Serial.print("RTC Value : ");
  Serial.println(getRTC());
  Serial.print("Stored time : ");
  Serial.println(storedTime);
  Serial.println("------------------------------------------");
  delay(1000);
  if(i == 5) {
    Serial.println("Condition raised !");
    storedTime = getRTC();
  }
  i++;
}

char* datetimeBuffer = new char[25];
char *getRTC()
{
  delete [] datetimeBuffer; 
  char *wdBuffer; //week day buffer

 // bits of your code removed

    sprintf(datetimeBuffer,"%02u/%02u/%02u(%3s) %02u:%02u:%02u",bcdToDec(dd),bcdToDec(mo),bcdToDec(yr) + 2000,wdBuffer,bcdToDec(hh),bcdToDec(mi),bcdToDec(ss));
  }
  return(datetimeBuffer);
}

Before i==5 your storedTime is pointing (by luck) to an address which has a 0 in it print sees a string and it prints nothing. When i==5 storedTime is changed to point datetimeBuffer. and print prints it out.

After that i>5 you call getRTC() (inits print statement) that is printed out BUT IT ALSO UPDATES datetimeBuffer, which you printout a cecond time via SerialPrintln(storedTime);

Mark

I've replaced

char *storedTime;

by

char storedTime[25];

and replaced

storedTime = getRTC();

by

strcpy (storedTime,getRTC());

Now seems to work as expected, thank you !