Reading DS1307 RTC after sleeping

I want to interrupt sleep, log something once per second, get a timestamp onto it and sleep again.
After going to a sleep mode like "LowPower.powerDown" and waking up again the I2C communication is dead.
I tryed a few things to get it working but nothing helps so far, only if there is no sleepmode at all it keeps working.
Google does give this but that didnt work for me or I didnt implement it correctly.

How could I get the I2C up and running again? Preferably as quickly as possible, good would be below 50ms and perfect below 1ms.
For the SD-card (SPI) I had to use a different library and had no more problems when switching it off and on via MOSFET just once every 10 sec.

This is the example out of the library im using, so there is no sleep. But if I would simply make it sleep and interrupt via the 1Hz output of the RTC it would be almost identical to my situation.

#include <Wire.h>
#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
  Serial.println("DS1307RTC Read Test");
  Serial.println("-------------------");
}

void loop() {
  tmElements_t tm;

  if (RTC.read(tm)) {
    Serial.print("Ok, Time = ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
    String datestring = "";                             // make a string for assembling the data to log
    datestring = String(tmYearToCalendar(tm.Year)) + "." + String(tm.Month) + "." + String(tm.Day) + " " + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second);
    Serial.println(datestring);
  } else {
    if (RTC.chipPresent()) {
      Serial.println("The DS1307 is stopped.  Please run the SetTime");
      Serial.println("example to initialize the time and begin running.");
      Serial.println();
    } else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
    }
    delay(9000);
  }
  delay(1000);
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

This is not the code you're using for the sleep. Post that code because your error is probably in the wakeup code.

Also post a wiring diagram.

The wake up is simply a interrupt. So there is no wakeup code.
It all works except for the RTC.
Its hooked up via I2C, no pullups, and workes like that in this sketch when the sleep is commented out.

#include <Wire.h>
#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

#include <SdFat.h>
#include <SPI.h>
#include <LowPower.h>
const int chipSelect = 10;
SdFat SD;
int val = 0;

const int dPin = 2; // interrupt 0


String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
bool fertig = 1;
int warten = 0;
bool linefeed = 0;
bool an = 1;
int num;

char inChar;
boolean newData = false;
String datestring = "";

void setup()  {
  pinMode(5, OUTPUT);
  Serial.begin(9600);                                   // open serial port, set the baud rate as 9600 bps

  inputString.reserve(512);         // reserve 512 bytes for the inputString:
  delay(250);

  pinMode(dPin, INPUT);
  pinMode(8, OUTPUT);         //power for RTC, was on Vcc befor too, its I2C is supposed to recover when its powercycled and digital Pin has enough current to power it
  digitalWrite(8, HIGH);
  Serial.println("an");
  Serial.flush();
}

void loop() {
  recvoneChar();


  if (an) {         //on first start up sleep and wait for signal
    attachInterrupt(0, recvoneChar, CHANGE);
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    detachInterrupt(0);
    an = 0;
  }


  if ((millis() - warten) > 50) {    //dont sleep while the data comes in
    val++;
    if (val == 10) {    //count 10x data for lower SD-card access -> lower power consumption
      stringComplete = true;
      val = 0;
    }
    if (stringComplete) {   //print the 10 records to the SD-card
      digitalWrite(5, HIGH);
      if (!SD.begin(chipSelect)) {                            // see if the card is present and can be initialized:
        Serial.println("Card failed or not present");
        delay(50);
        return;
      }
      File dataFile = SD.open("log.txt", FILE_WRITE);
      dataFile.print(inputString);
      dataFile.close();
      Serial.print(inputString);
      Serial.flush();
      inputString = "";                  // clear the string:
      stringComplete = false;
      digitalWrite(5, LOW);
    }


    attachInterrupt(0, recvoneChar, LOW);  //sleep after printing it and/or the buffer of 10 is not full yet
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    detachInterrupt(0);
    warten = millis();
    linefeed = 0;
    num = 0;

  }


}


void recvoneChar() {


  if (Serial.available() > 0) {
    inChar = Serial.read();
    num++;

    tmElements_t tm;

    if (RTC.read(tm)) {
      datestring = String(tmYearToCalendar(tm.Year)) + "." + String(tm.Month) + "." + String(tm.Day) + " " + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second);
      //      Serial.print(datestring);
    }    else {
      if (RTC.chipPresent()) {  //this never shows up, so the I2C itself failed
        Serial.println("The DS1307 is stopped.  Please run the SetTime");
        Serial.println("example to initialize the time and begin running.");
        Serial.println();
      } else {
        Serial.println("DS1307 read error!  Please check the circuitry.");
        Serial.println();
      }
      delay(2000);
    }
String(tm.Day) + " " + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second);
    Serial.println(datestring);
    if (num > 2) {
      if (!linefeed) {
        linefeed = 1;
        inputString += '\r';
        inputString += '\n';
        inputString += datestring;                   // add timestamp
        inputString += ",";
      }
      inputString += inChar;                   // add it to the inputString:
    }
  }
  digitalWrite(5, LOW);
}

I guess the problem is your interrupt handler. Set an empty routine as the interrupt handler but NEVER send anything to the serial interface in an interrupt service routine (the serial interface uses interrupts to work and inside ISRs interrupts are disabled).

Holy moly!
That did it!
I simply have a empty loop now:

attachInterrupt(0, interrupt, LOW);
.
.
.
void interrupt() {
}

Great. Finally the powerconsumption is low and not far too high.
Its about 4,5mA idle, mostly from the arduino and I might optimize that in hardware. If I get down low enough I could leave the 9V battery in there all the time instead of switching it off or taking it out.

7,5mA average while logging (including the thermometer itself with about 1mA). About half of the value I had befor (arduino in idle-mode with UART on). Could be halfed again in hardware.

After working for about 7min (~300 measurements, ~3000 loops) it totally fucks up.
I found somthing about the heap getting messed up with strings, got every bit of RAM static and also measured the free memory. Its rock solid untill it suddenly crashes, so thats not it.

What could be the cause of these crashes?
I cant c&p that, you have to check the screenshot.

#include <MemoryFree.h>

#include <Wire.h>
#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

#include <SdFat.h>
#include <SPI.h>
#include <LowPower.h>
const int chipSelect = 10;
SdFat SD;
int val = 0;

const int dPin = 2; // interrupt 0


String inputString = "";         // a string to hold incoming data
String datestring = "";          // strong for date assembly
boolean stringComplete = false;  // whether the string is complete
bool fertig = 1;
int warten = 0;
bool linefeed = 0;
bool an = 1;
int num;

char inChar;
boolean newData = false;


void setup()  {
  Serial.begin(9600);     

  inputString.reserve(312);         // reserve 312 bytes for the inputString
  datestring.reserve(32);
  delay(250);

  pinMode(5, OUTPUT);         //power to SD
  digitalWrite(5, LOW);
  pinMode(dPin, INPUT);       //interruptpin
  pinMode(8, OUTPUT);         //power for RTC
  digitalWrite(8, LOW);
  Serial.println("an");
  Serial.flush();
}

void loop() {
  recvoneChar();


  if (an) {         //on first start up sleep and wait for signal
    attachInterrupt(0, interrupt, CHANGE);
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    detachInterrupt(0);
    an = 0;
  }
  digitalWrite(8, HIGH);

  if ((millis() - warten) > 70) {    //dont sleep while the data comes in
    val++;
    if (val == 10) {    //count 10x data for lower SD-card access -> lower power consumption
      stringComplete = true;
      val = 0;
    }
    if (stringComplete) {   //print the 10 records to the SD-card
      digitalWrite(5, HIGH);
      if (!SD.begin(chipSelect)) {                            // see if the card is present and can be initialized:
        Serial.println("Card failed or not present");
        delay(50);
        return;
      }
      File dataFile = SD.open("log.txt", FILE_WRITE);
      dataFile.print(inputString);
      dataFile.close();
      //      Serial.println();
      Serial.print(inputString);
      //      Serial.println();
      Serial.flush();
      inputString = "";                  // clear the string:
      stringComplete = false;
      digitalWrite(5, LOW);
    }


    //    Serial.println(",  sl");  //debug to see what happens when
    //    Serial.flush();
    attachInterrupt(0, interrupt, LOW);  //sleep after printing it and/or the buffer of 10 is not full yet
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    detachInterrupt(0);

    warten = millis();
    //    Serial.print("wk  ,");
    linefeed = 0;
    num = 0;

  }


}


void recvoneChar() {


  if (Serial.available() > 0) {
    inChar = Serial.read();
    num++;

    tmElements_t tm;
    if (RTC.read(tm)) {
      datestring = String(tmYearToCalendar(tm.Year)) + "." + String(tm.Month) + "." + String(tm.Day) + " " + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second);
      //      Serial.print(datestring);
    }    else {
      if (RTC.chipPresent()) {  //this never shows up, so the I2C itself failed
        Serial.println("The DS1307 is stopped.  Please run the SetTime");
        Serial.println("example to initialize the time and begin running.");
        Serial.println();
      } else {
        Serial.println("DS1307 read error!  Please check the circuitry.");
        Serial.println();
      }
      delay(2000);
    }

    if (num > 2) {
      if (!linefeed) {
        linefeed = 1;
        inputString += '\r';
        inputString += '\n';
        inputString += datestring;                   // add timestamp
        inputString += ",";
        Serial.print("freeMemory()=");
        Serial.println(freeMemory());
      }
      inputString += inChar;                   // add it to the inputString:
    }
    Serial.println(inChar);
  }
  digitalWrite(5, LOW);
}

void interrupt() {
}

got every bit of RAM static

That is IMPOSSIBLE since you still use the String class. If you do not believe that, LOOK at WString.cpp, and see what the += operator is defined to do.

The two strings have a fix size of 312 and 32 bytes.
The free memory is not moving one byte.

I dont know if my statement is really correct like that, but I dont see RAM issues here. Reducing the size of the large string (down from 512 bytes) didnt change a thing.

The two strings have a fix size of 312 and 32 bytes.

So, you don't need Strings. You are just being lazy using them. I see.

Could u give me some constructive feedback?
Its not like I have experience or anything, I program since November 2016 and its just a hobby to realise things I couldnt do befor. I dont know other ways to get accumulated data on the SD-card.

Edit: Is the/a string really the problem? I used the 512 Byte one for days worth of data (not just 7min), same size, without the RTC timestamp but millis().

Edit2: Added pictures of the glitch happening on the scope. Ch1 is the signal, Ch2 is pin9 going low whenever the arduino is wake and high right befor it sleeps. In normal operation its interrupted, wake for the set 50ms and back to sleep. In faulty operation it doesnt wake up, incoming data however is perfectly fine.

Could u give me some constructive feedback?

What Paul means: the String class is a piece of shit for microcontroller without a memory management unit and only 2kB of RAM. It fragments your memory in no time, you really shouldn't use it for a sketch that is expected to run more than a few seconds. Instead of building your output string you could simply call Serial.print() several times and finish the line with a Serial.println().
For the input string you could use a character array and I hope you don't need 512 bytes for it, that a quarter of the whole RAM this little processor has.

To save more memory, replace all calls to a print() or println() method with constant strings as

Serial.print("This is a constant string");

by one with the F() macro:

Serial.print(F("This is a constant string"));

If you use the F() macro the string is submitted to the serial interface directly out of the flash memory. If you don't use it, the constant string is copied to RAM at sketch start and that memory is never released.

Edit: Is the/a string really the problem? I used the 512 Byte one for days worth of data (not just 7min), same size, without the RTC timestamp but millis().

There's a high probability that it is.

Edit2: Added pictures of the glitch happening on the scope. Ch1 is the signal, Ch2 is pin9 going low whenever the arduino is wake and high right befor it sleeps. In normal operation its interrupted, wake for the set 50ms and back to sleep. In faulty operation it doesnt wake up, incoming data however is perfectly fine.

Please describe in more detail what these pictures show. Ch1 is what signal? Ch2 is going low but where is low in that picture? I don't know your scope's output.

In the currently working version its the exact same string. All that is different is the device is not in the powerdown but idle mode to get the UART data -> no more external interrupt as that is interrupt driven.
Just finished testing that for 31h or 71000 datapoints with no problems.

I will still try and find a way to make a char array somehow. Could I do it like this to add each char to the array and print it later?

char charBuf[350];  //creat array "charBuf"
char.toCharArray(charBuf, 350)      //add "char" to my array via toCharArray()
dataFile.print(charBuf); //print after eg. 10 samples are collected, hence 350 for ~300 chars

To save more memory, replace all calls to a print() or println() method with constant strings as

There are no constant strings.
Edit: There are! From the RTC debugging, they never get called. Ill fix that.

Ch.1 is the dataline, aka Rx on the arduino, getting TTL data at 9600 baud form the device, about once every 1,6s.
Ch.2 is arduinos pin9 going low right after the interrupt and high befor sleeping.
On pic 150 that works, its up for the set 50ms and back to sleep.
Pic 146a (stitched from 3 pics) shows how it fails to wake up. Its up for a a few µs somehow, even with that small programm I have it couldnt be that fast to get threw the loop - not to mention the fact that it isnt allowed to go back to sleep untill 50ms pas...

I will still try and find a way to make a char array somehow. Could I do it like this to add each char to the array and print it later?

Your code will not work. A character array is not really a C++ object but the way strings are handled in C. It's just a bunch of bytes in consecutive order in memory with a pointer to it.

Examples of how to handle it:

char buffer[200];
buffer[0] = 0; // terminating null byte

// add a single byte
int l = strlen(buffer);
buffer[l++] = c;
buffer[l] = 0; // terminating null byte

// add a C string
strncat(buffer, "This is the string to add", 200); // 200 is the size of the buffer array

Ch.2 is arduinos pin9 going low right after the interrupt and high befor sleeping.

I cannot find the code for the handling of pin 9 in your sketch. Please post a complete sketch.

This is what you are looking for, it was added for debugging:

digitalWrite(9, HIGH);
attachInterrupt(0, interrupt, LOW);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
detachInterrupt(0);
digitalWrite(9, LOW);

Can you explain this example a little? Is my understanding correct:

    //both these lines go to the top of the programm
    char buffer[200];      //creat a buffer(?) for 200 chars (incl. terminating null byte) with the name "buffer"
    buffer[0] = 0;         //terminating null byte like a initialisation?


    // add a single byte
    int 1 = strlen(buffer);   //defines the lenght of the string(?!) to be one, eg. add one char
    buffer[1++] = c;          //Counts up 1 position in "buffer" and puts "c" into this position, I would put my "inChar" here
    buffer[1] = 0;             // terminating null byte, but why fixed at position 1?


    // add a C string  -- what is a "C string"?
    strncat(buffer, "This is the string to add", 200); //Why is "buffer" suddenly a string? 
    //Output would be "buffer" combined with "This is the string to add"
    //Why did u use 200 when "This is the string to add" is only 25 chars?
    //I would put my datestamp in there instead of the 2nd argument
    //My understanding: strncat(string1, string2, Maximum number of characters to be appended) --> string1 now contains string2 or, if too long, only the max. numbers of chars

What I dont see is how I could get the buffer printed to SD-card and possibly to serial for easy debugging too. Can i simply use eg. "Serial.print(buffer)"?

What I dont see is how I could get the buffer printed to SD-card and possibly to serial for easy debugging too. Can i simply use eg. "Serial.print(buffer)"?

Yes, you can do that.

//defines the lenght of the string(?!) to be one, eg. add one char

That's not a one but a lowercase L and it stands for length. On my system a 1 and lowercase l has different font outlines to make them distinguishable, you should choose a font in your editor that makes them distinguishable too.

The strlen() function counts the number of bytes in the string up till the null byte at the end.

Pic 146a (stitched from 3 pics) shows how it fails to wake up. Its up for a a few µs somehow, even with that small programm I have it couldnt be that fast to get threw the loop - not to mention the fact that it isnt allowed to go back to sleep untill 50ms pas...

How many micros is it up? Can you analyze the that? Do you have the Pin9 code in both locations where you call the sleep?

I updated the code, replaced the big string with the buffer and im also using the 2nd char, byte 177 (tho its false but thats what arduino reads right after wakeup with clock initialization), to start mark the new linke eg. add the datestring.
But I run into problems while compiling:

read-rs232-log-13:29: error: 'buffer' does not name a type

 buffer[0] = 0; // terminating null byte

 ^

C:\Users\Leo\Documents\Arduino\read-rs232-log-13\read-rs232-log-13.ino: In function 'void recvoneChar()':

read-rs232-log-13:143: error: cannot convert 'String' to 'const char*' for argument '2' to 'char* strncat(char*, const char*, size_t)'

       strncat(buffer, datestring, 25); //Output would be "buffer" combined with "This is the string to add"

                                     ^

exit status 1
'buffer' does not name a type

Isnt "buffer" defined as "char"?
New code:

#include <Wire.h>
#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

#include <SdFat.h>
#include <SPI.h>
#include <LowPower.h>
const int chipSelect = 10;
SdFat SD;
int val = 0;

const int dPin = 2; // interrupt 0


String inputString = "";         // a string to hold incoming data
String datestring = "";          // strong for date assembly
boolean stringComplete = false;  // whether the string is complete
bool fertig = 1;
int warten = 0;
bool linefeed = 0;
bool an = 1;
int num;

char inChar;
boolean newData = false;

char buffer[350];
buffer[0] = 0; // terminating null byte

bool plusminus = 0;



void setup()  {
  Serial.begin(9600);

  //  inputString.reserve(312);         // reserve 312 bytes for the inputString
  datestring.reserve(32);
  delay(250);

  pinMode(5, OUTPUT);         //power to SD
  digitalWrite(5, LOW);
  pinMode(dPin, INPUT);       //interruptpin
  pinMode(8, OUTPUT);         //power for RTC
  digitalWrite(8, HIGH);
  pinMode(9, OUTPUT);
  digitalWrite(9, LOW);
  Serial.println("an");
  Serial.flush();

}

void loop() {
  //  recvoneChar();


  if (an) {         //on first start up sleep and wait for signal
    attachInterrupt(0, interrupt, CHANGE);
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    detachInterrupt(0);
    an = 0;
  }

  if ((millis() - warten) > 50) {    //dont sleep while the data comes in
    val++;
    if (val == 10) {    //count 10x data for lower SD-card access -> lower power consumption
      stringComplete = true;
      val = 0;
    }
    if (stringComplete) {   //print the 10 records to the SD-card
      digitalWrite(5, HIGH);
      if (!SD.begin(chipSelect)) {                            // see if the card is present and can be initialized:
        Serial.println("Card failed or not present");
        delay(50);
        return;
      }
      File dataFile = SD.open("log.txt", FILE_WRITE);
      dataFile.print(buffer);
      dataFile.close();
      //      Serial.println();
      Serial.print(buffer);
      //      Serial.println();
      Serial.flush();
      inputString = "";                  // clear the string:
      stringComplete = false;
      digitalWrite(5, LOW);
    }


    //    Serial.println(",  sl");  //debug to see what happens when
    //    Serial.flush();
    digitalWrite(9, HIGH);
    attachInterrupt(0, interrupt, LOW);
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    detachInterrupt(0);
    digitalWrite(9, LOW);
    warten = millis();
    //    Serial.print("wk  ,");
    linefeed = 0;
    num = 0;
    plusminus = 0;
  }


}


void recvoneChar() {


  while (Serial.available()) {
    inChar = Serial.read();
    num++;

    tmElements_t tm;
    if (RTC.read(tm)) {
      datestring = String(tmYearToCalendar(tm.Year)) + "." + String(tm.Month) + "." + String(tm.Day) + " " + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second);
      //      Serial.print(datestring);
    }    else {
      if (RTC.chipPresent()) {  //this never shows up, so the I2C itself failed
        Serial.println(F("The DS1307 is stopped.  Please run the SetTime"));
        Serial.println(F("example to initialize the time and begin running."));
        Serial.println();
      } else {
        Serial.println(F("DS1307 read error!  Please check the circuitry."));
        Serial.println();
      }
      delay(2000);
    }

    int l = strlen(buffer);   //defines the lenght of the string(?!) to be l, eg. add one char
    buffer[l++] = inChar;          //Counts up l position in "buffer" and puts "c" into this position, I would put my "inChar" here
    //    buffer[l] = 0;             // terminating null byte, but why fixed at position 1?
    if ( (byte) inChar == 177) {
      plusminus = 1;
      buffer[l++] = '\r';
      buffer[l++] = '\n';
      strncat(buffer, datestring, 25); //Output would be "buffer" combined with a max of 25 chars of "datestring"
      buffer[l++] = ',';
    }
    if (plusminus) {
      buffer[l++] = inChar;          //Counts up l position in "buffer" and puts "c" into this position, I would put my "inChar" here
      buffer[l] = 0;             // terminating null byte
    }

    Serial.println(inChar);
  }
}



void interrupt() {
}

For the wake-up glitch: I changed the code a little, so there is only one sleep that can only happen after at least 50ms passed since wake-up. The glitch is a little different that way, its wake up after 1,5ms of signals and is up for 1,75ms. Then back to sleep and back up etc.

  if ((millis() - warten) > 50) {    //dont sleep while the data comes in
[blabla other code]
    digitalWrite(9, HIGH);
    attachInterrupt(0, interrupt, LOW);  //sleep after printing it and/or the buffer of 10 is not full yet
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    detachInterrupt(0);
    digitalWrite(9, LOW);
    warten = millis();
}

152: Still working, no bug
153: zoomed in on the working part
155: glitched part
154: zoomed in on the glitched part

Isnt "buffer" defined as "char"?

Yes, buffer is, but datestring is still a String object and the C function don't know how to handle C++ objects.

The last parameter of strcat() is the size of the buffer in the first parameter!

To get that string formatted easily you should take a look at the snprintf(). To print directly to your result string without wasting memory you can use pointer arithmetic:

  uint16_t len = strlen(buffer);
  snprintf(buffer + len, 350 - len, "myformat is %d", decimal_var);

For the wake-up glitch: I changed the code a little, so there is only one sleep that can only happen after at least 50ms passed since wake-up. The glitch is a little different that way, its wake up after 1,5ms of signals and is up for 1,75ms. Then back to sleep and back up etc.

My guess is that you ran out of memory the "an" variable got overwritten (or "warten" if you removed that part) so it didn't react like you would with enough memory.

After writing "buffer" to the file you should reset it to the empty string:

buffer[0] = 0;

And remove all usages of the String class.

In post #5 I did measure the free RAM and printed it. It didnt change and was about 500byte.

To get that string formatted easily you should take a look at the snprintf(). To print directly to your result string without wasting memory you can use pointer arithmetic:

Im simply unable to follow you at this point and am unable to use pointer arithmetic or buffers so far.

uint16_t len = strlen(buffer);
snprintf(buffer + len, 350 - len, "myformat is %d", decimal_var);

"len" gives the current lenght of "buffer".
In ur link a integer is set to be the result of snprinf instead of that beeing on its own?
Where do I even put these 2 lines, how do I use them, for what?
Please try to explain the code in a few words.

And im still stuck at the error:

read-rs232-log-13:29: error: 'buffer' does not name a type

 buffer[0] = 0; // terminating null byte

 ^
[blabla other code]

When you post ALL of your code, then we can help.

Eheran:
And im still stuck at the error:

read-rs232-log-13:29: error: 'buffer' does not name a type

buffer[0] = 0; // terminating null byte

^

Move that line

buffer[0] = 0; // terminating null byte

inside the setup routine. Although your code is correct as you wrote it the Arduino IDE does some magic before handing over to the compiler and that magic is not compatible with what you had.

In ur link a integer is set to be the result of snprinf instead of that beeing on its own?
Where do I even put these 2 lines, how do I use them, for what?
Please try to explain the code in a few words.

Yes the snprintf() function returns an integer but in this case you don't need it so you don't have to assign it to a variable.

These two lines cannot be inserted verbosely in your code, I posted them to show you how to add a (C) string with snprintf() to the end of an existing string without allocating a second buffer just for the snprintf() call.
The first parameter to snprintf() is a character pointer pointing to the start of your character array aka C string. We add the length of the current string to the porinter pointing to the start of the buffer. The result of this calculation points to the end of the current string. So the resulting string from snprintf is appended to the end of your current string using no other temporary buffer.
Please read the linked manual page for snprintf(). You can then replace your String object addition line:

      datestring = String(tmYearToCalendar(tm.Year)) + "." + String(tm.Month) + "." + String(tm.Day) + " " + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second);

which is just a waste of memory.

In post #5 I did measure the free RAM and printed it. It didnt change and was about 500byte.

You did that in one point in your code. But you allocate some variables in routines that are hold locally and other constructs and libraries may also need temporary memory. You can do a lot with 512 bytes but the way you are wasting memory in the rest of your code it won't last long for you.