Serial.printf Bug ?

Status
Not open for further replies.

quadrupel

Well-known member
While playing with the Teensy 3.6, its internal RTC, and TimeLib, I came across something funny. In
The code below, the first serial.printf prints the month twice, not the weekday and month
Comment out that line, and uncomment the next two that separates the weekday and month into two separate commands, and all is well. It's as if a string buffer is not clearing?

Bug or something stupid on my part.
i've only been experimenting with this for a few days, so I could be missing something obvious.

Any help would be appreciated,
Bruce

Code:
/*
   Board: Teensy 3.6
   USB Type: Serial
   CPU Speed: 180 MHz
   Optimize: Smallest Code With LTO <-- setting does not matter
   Port: (Teensy3.6) Serial
*/
#include "TimeLib.h"


int main()
{
  while (!Serial);  // Wait for Arduino Serial Monitor to open
  delay(100);

  tmElements_t rtc;
  for (;;)
  {
    time_t rtc_raw =  rtc_get();
    breakTime( rtc_raw, rtc );

    Serial.printf( F("%s, %s "), dayStr(rtc.Wday), monthStr(rtc.Month) ); // fails -- prints November twice
    //Serial.printf( F("%s, "), dayStr(rtc.Wday) );    // works
    //Serial.printf( F("%s "), monthStr(rtc.Month) );  // works
    Serial.printf( F("%02d, %04d"), rtc.Day, (rtc.Year + 1970) );
    Serial.printf( F(" @ %02d:%02d:%02d\r\n"), rtc.Hour, rtc.Minute, rtc.Second );

    delay(5000);
  }

  return 0;
}
//eob: main()
 
The time library is probably using a single static array to return a result. When the printf is executed, dayStr is evaluated and the result stored in the static string. Then monthStr is evaluated and (over)writes its result into the same static string. Then the printf is actually performed and prints the results.
As you've discovered, separating the two calls fixes the problem.

Pete
P.S. I've just checked the code. dayStr, monthStr and other time library functions do use one static string to return a result.
 
try this instead:
Code:
#include "TimeLib.h"

const char days[8][10]={"Err", "Sunday", "Monday", "Tusday", "Wednesday", "Thursday", "Friday", "Saturday"};
const char months[12][10]={"January", "February", "March", "April", "May", "June", "July","August", "September", "October", "November", "December"};

int main()
{
  while (!Serial);  // Wait for Arduino Serial Monitor to open
  delay(100);

  tmElements_t rtc;
  for (;;)
  {
    time_t rtc_raw =  rtc_get();
    breakTime( rtc_raw, rtc );

    Serial.printf( "%s, %s ", days[rtc.Wday], months[rtc.Month] ); // correct
    Serial.printf( "%02d, %04d", rtc.Day, (rtc.Year + 1970) );
    Serial.printf( " @ %02d:%02d:%02d\r\n", rtc.Hour, rtc.Minute, rtc.Second );

    delay(5000);
  }

  return 0;
}
//eob: main()

note: i removed the "F" macro - Teensy 3.x does not need it.


edit: ok, el_supremo is right.
maybe to save some bytes ram...AVR sucks. But why the stringcopy? What's the reason?
 
Thanks el_supremo & Frank B.
I was pretty sure it was a charcter string overwrite issue; thanks for confirming my suspicions. Using const char arrays is definitely a better solution than that presented in the Time library.

Frank, thanks for the hint on F(). My niavety on Teensy is certainly showing :) My learing curve may be a little longer than I anticipated. Or, do I mean my AVR unlearnig curve will be longer than I anticipated.

Again, el_supremo and Frank, thanks for the help.
Bruce
 
Status
Not open for further replies.
Back
Top