Go Down

Topic: Creating a timestamp (RTClib) (Read 3070 times) previous topic - next topic

cyberdrive

Jun 01, 2012, 11:00 am Last Edit: Jun 01, 2012, 11:09 am by cyberdrive Reason: 1
Hiya Community!

Atm i am working on my pool control unit and i do want to integrate a temp (DS1820) logging function (writing to flash in a ring buffer later).

I do have the RTC unit with a DS1307 and i am useing RTClib.
What i want to do is creating something like:

DD/MM hh:mm 26.4         ( where 26.4 is in °C)

what i do have so far is:
Code: [Select]

...
char TempBuf[10] = "         ";
char buffer[17];

dtostrf(PoolTemp, 4, 1, TempBuf);

sprintf(buffer,"%02i/%02i", now.day(), now.month());
Serial.println(buffer);


if i do continue it like:
Code: [Select]

...
char TempBuf[10] = "         ";
char buffer[17];

dtostrf(PoolTemp, 4, 1, TempBuf);

sprintf(buffer,"%02i/%02i %02i:%02i %04c", now.day(), now.month(), now.hour(), now.minute(), TempBuf);
Serial.println(buffer);

it freezes my arduino. Of course it has something to do with the parameters in sprintf but i don´t get it.

Your help is very much appreciated!
Cyber



michael_x

char buffer[7];
seems a bit small ;)

cyberdrive

sorry, of course it meant to be 17...

i do have edited the post above :) THX!

Coding Badly


buffer is too small.  It has to be big enough to accommodate all the characters you write to it in the sprintf call.  Which means we count...

%02i   - two characters
/   - one character
%02i    - three (there is a trailing space there)
%02i   - two
:   - one
%02i    - three (another space)
%04c   - four

...16 (assuming I counted correctly).  One extra for the "null terminator".  Change the definition of buffer to this...

Code: [Select]
char buffer[17];

michael_x

char Tempbuf[] has to be referred to as "%4s" in sprintf, I assume

cyberdrive

Huge THANKS for all the help till now! Just great in here!

Version 1 (only day & month) is working. Even when only adding the statement for "hour" - i get freezed :)

michael_x

you need to provide (at least) as many parameters after the format, as "%" in the format string ...
( or you reverted to  char buffer[7]; )

or some other simple mistake

%i or %d or %u should all be fine and equivalent for an unsigned decimal integer

Hm... try a test sketch with only

Code: [Select]
static char buffer[20];
sprintf(buffer, "%02u/%02u %02u:%02u", 6, 1, 23, 59);
Serial.println(buffer);

cyberdrive

#7
Jun 01, 2012, 09:15 pm Last Edit: Jun 01, 2012, 09:23 pm by cyberdrive Reason: 1
Thanks for the hint, but it freezes with that code too...  :smiley-roll-blue:

i do think it´s the code itself - anywhere else... i do change a bit of code anywhere and it gets freezed. At nearly 1000 lines of code, do you have any tip where to search first?

Cyber

cyberdrive

#8
Jun 01, 2012, 10:13 pm Last Edit: Jun 01, 2012, 10:18 pm by cyberdrive Reason: 1
I do have tracked it down to my logging function. If i do comment that function call out everything is working fine.

myBuffer1 or myBuffer2 is working, but not both at the same time - do you see a mistake?

complete code at: http://pastebin.com/Ju8feXYG

Code: [Select]

void LoggingValues()   // check if values have to be written to history
{
 DateTime now = RTC.now();
 
 int LastTimeSavedVal= 0;    // now.hour() of last time logging
 int PoolTempSavePosVal = 0;    // containing save position of ring logging buffer (value 0 to 8 = 9 values for logging - then reset)
 int iTempVal;
 unsigned int MinAddr = 0;    // calc memory position for writing actual Timestamp
   
 LastTimeSavedVal = EEPROM.read(LastTimeSaved);
 PoolTempSavePosVal = EEPROM.read(PoolTempSavePos);

 MinAddr = EEPROM_MIN_ADDR + PoolTempSavePosVal*BytesPerTempVal;

 for (iTempVal = 0; iTempVal < ValuesToLog; iTempVal++)
 {
   if (now.hour() >= (WakeUpTime + iTempVal*ValueLoggingIntervall) && LastTimeSavedVal < (WakeUpTime + iTempVal*ValueLoggingIntervall))    //calc if value has to be stored
   {
     getMedianTemps();    // reading temps from DS1820
 
     dtostrf(PoolTemp, 4, 1, TempBuf);    // convert float temperature for character operations
     
     PoolTempSavePosVal++;    
     if (PoolTempSavePosVal > 8)   // ring buffer reset
     {
       PoolTempSavePosVal = 0;
       //Serial.println("PoolTempSavePos Reset");
     }      
 
char myBuffer1[11];
sprintf(myBuffer1,"%02i/%02i %4s", now.day(), now.month(), TempBuf);
//Serial.println(myBuffer1);

char myBuffer2[7];
sprintf(myBuffer2," %02i:%02i", now.hour(), now.minute());
//Serial.println(myBuffer2);

    StringTemp = String(myBuffer1) + String(myBuffer2);
    StringTemp.toCharArray(TempChar, 18);    
     Serial.print("DEBUG WERT: ");      
     Serial.println(TempChar);
...

michael_x

Code: [Select]
     StringTemp = String(myBuffer1) + String(myBuffer2);
     StringTemp.toCharArray(TempChar, 18);   


Strings are bad, and + is a very expensive operator on Strings.
And I don't see the definition of TempChar...

What about just throwing that part away?  ;)
If you use it just for the Serial.println, either use the commented println's above instead, or setup your debug message in one sprintf() into a char array of sufficient size directly...

cyberdrive

I am open of throwing it away  :smiley-mr-green:
What i do want to get is a string / char array like:
06/01 12:00 26.4
which i could write to flash. (for example 3 times a day).

That + operation was trying a workaround because of the freezing when putting together all in one char array / a string. I will put it together char by char in one char array as u mentioned.

TempChar is globaly defined:
Code: [Select]
char TempChar[17] = "1234567890abcdef";

Go Up