Displaying my ignorance again

Hi again.
I'm hoping that this will be solved with a similarly well-put "WTF are you doing?" comment as last time.

I've started to get the hang of laying my information out on the screen, using the sprintf command.
However, I'm getting weird results.
If I put in the following:

  sprintf(revs,"%.5d",rpm);
  sprintf(date,"%.2d/%.2d/%d",now.day(),now.month(),now.year());
  sprintf(time,"%.2d:%.2d",now.hour(),now.minute());
  glcd.drawstring(92,0,(revs));
  glcd.drawstring(67,6,(date)); 
  glcd.drawstring(97,7,(time));

It's perfectly happy for a second or so after uploading to the board, as evidenced here:

However, after a short pause, it then becomes this:

I don't know why, but I'm hoping that someone will point out something really obvious (read: worthy of a facepalm) and it'll fix it.

I've also just noticed that there's a problem in the first picture, too - the bit at the bottom where it currently reads 16:5965535 is supposed to say Odo: 65535.

This didn't start happening until I specified the length of the numbers that would be displayed by these sprintf commands, so I'm guessing it's something to do with that. However, it completely messes up the layout if I don't specify that the day/month/hour/minute output should be 2 digits each, or that the tachometer has five digits. Just not in the same way that this does.

Thoughts, anyone?

We'd need to see more of your code. Specifically, how are revs, date and time defined? A first guess is that they are too small (not including space for the trailing NULL).

PaulS:
We'd need to see more of your code. Specifically, how are revs, date and time defined? A first guess is that they are too small (not including space for the trailing NULL).

Fair enough.

void datetime()
{
  DateTime now = RTC.now();
  sprintf(date,"%.2d/%.2d/%d",now.day(),now.month(),now.year());
  sprintf(time,"%.2d:%.2d",now.hour(),now.minute());
  glcd.drawstring(67,6,(date)); 
    glcd.drawstring(97,7,(time)); 
    glcd.display();
  delay(1000);
}

The revs code I shamelessly lifted from the arduino forums, and I imagine it's nowhere near workable yet. Here are the relevant bits, though:

  pinMode(rpmPin, INPUT); //tachometer pin 
  attachInterrupt(rpmInterrupt, &rpmIsr, RISING);
  sprintf(revs,"%.5d",rpm); //output results

That bit's in void setup()

void rpmIsr() 
{ 
  unsigned long now = micros(); 
  unsigned long interval = now - lastPulseTime; 
  if (interval > 2000) 
  { 
    rpm = 60000000UL/(interval * pulsesPerRev); 
    lastPulseTime = now; 
  } 
}

What do you mean about "the trailing NULL"? Idiot question, I dare say, but I seem to be specialising in them today.

So I guess you are just ignoring the part that asked: "Specifically, how are revs, date and time defined?"?

What do you mean about "the trailing NULL"? Idiot question, I dare say, but I seem to be specialising in them today.

Character strings need to be terminated with a NULL character, "\0". It is how a function like "print" knows it has reached the end of the array.

No, I just misread the question. My apologies.
They are defined as:
char revs[5]
char date [10]
char time[5]

Ah. Is it an automatic thing, or do I need to append \0 to my character strings?

char revs[5]

  sprintf(revs,"%.5d",rpm);

sprintf automatically adds the trailing NULL. So, the 5 digits in the rpm value plus the trailing NULL will take 6 spaces in the 5 element array. Oops.

  sprintf(date,"%.2d/%.2d/%d",now.day(),now.month(),now.year());

2 + 1 + 2 + 1 + 4 + 1 = 11 spaces in the 10 element date array. Oops.

  sprintf(time,"%.2d:%.2d",now.hour(),now.minute());

2 + 1 + 2 + 1 = 6 spaces in the 5 element array. Oops.

For the minute value, you probably want %02d. This will make 12 --> 12 and 3 --> 03.

Thanks. I honestly had no idea about needing to make the character array one element larger, so I'll try to remember it for next time.
It works just fine now. Cheers :smiley: