Code Along - Chapter 15

Text & Time Formatting

Build fixed-width text with snprintf: times, dates and a live clock on the LCD, and floats with dtostrf because the Uno cannot print %f.

Estimated time 60-80 minExercises passed 0 / 5

Formatted text with snprintf

snprintf(buffer, sizeof(buffer), format, values...) writes text into a char array, following a format like "%02d:%02d". For example, snprintf(buffer, sizeof(buffer), "%02d:%02d", 5, 9); puts 05:09 into buffer. %d is an int, %02d pads it to two digits with a leading zero, %04d pads it to four, and %s is text. The snprintf section of the Theory Reference lists them all, and Lesson 26 uses the same call later for real clock times.

The functions in this chapter return a String, Arduino's text type, so setup() can print the result. The starters already end with return String(buffer);, which turns the finished char array into a String.

On the Uno %f does not work - it prints ?. Use dtostrf() to turn a float into text first.

Exercise 15.1

formatDate()

Not started

An RTC gives the day, month and year as separate numbers. Write formatDate so it returns them as DD/MM/YYYY - day 5, month 9, year 2026 becomes 05/09/2026. One snprintf line does it: %02d for the day and month, %04d for the year.

Sample output
05/09/2026
String formatDate(int day, int month, int year) {
  char buffer[11];   // "DD/MM/YYYY" plus the end marker
  // snprintf the day, month and year into buffer

  return String(buffer);
}

void setup() {
  Serial.begin(9600);
  Serial.println(formatDate(5, 9, 2026));
}

void loop() {
}

Turn on JavaScript to edit, run and test this code in the browser.

Exercise 15.2

formatMinutes()

Not started

Write formatMinutes so it returns a time in seconds as MM:SS text - 125 seconds becomes 02:05. The starter already works out the whole minutes with /. Work out the leftover seconds with %, then snprintf both into the buffer with %02d, as in formatDate().

Sample output
02:05
String formatMinutes(unsigned long totalSeconds) {
  char buffer[6];   // "MM:SS" plus the end marker
  int minutes = totalSeconds / 60;   // whole minutes
  // Work out the leftover seconds, then snprintf minutes and seconds into buffer

  return String(buffer);
}

void setup() {
  Serial.begin(9600);
  Serial.println(formatMinutes(125));
}

void loop() {
}

Turn on JavaScript to edit, run and test this code in the browser.

Exercise 15.3

formatTime()

Not started

Now the full clock: write formatTime so it returns the time as HH:MM:SS - 3725 seconds becomes 01:02:05. Same idea as the last exercise, with hours added.

Sample output
01:02:05
String formatTime(unsigned long totalSeconds) {
  char buffer[9];   // "HH:MM:SS" plus the end marker
  // Work out hours, minutes and seconds, then snprintf into buffer

  return String(buffer);
}

void setup() {
  Serial.begin(9600);
  Serial.println(formatTime(3725));
}

void loop() {
}

Turn on JavaScript to edit, run and test this code in the browser.

Fixed-width text on the display

An LCD row is 16 characters and nothing clears itself. Build the whole field in a buffer first, with %02d padding so 9 becomes 09. Every update then writes the same number of characters in the same place, so no digits are left behind and the text never jumps sideways.

Exercise 15.4

A clock on the display

Not started

Show the time since the board started as MM:SS on the top line, updating as it runs. Build the text with snprintf into a char buffer, as in the exercises above, then print the buffer.

millis() / 1000 is the number of whole seconds.

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);
char buffer[6];

void setup() {
  lcd.init();
  lcd.backlight();
}

void loop() {
  int totalSeconds = millis() / 1000;
  // Work out minutes and seconds, build MM:SS and show it at the top left

  delay(200);
}

Turn on JavaScript to edit, run and test this code in the browser.

Exercise 15.5

Why does it print a question mark?

DeeperNot started

formatVolts should return text like 4.73 V, but on an Uno it returns ? V, because the Uno's snprintf cannot handle %f. Fix it so the voltage appears with two decimals. dtostrf(value, 1, 2, text) writes a float into a char array; print that with %s.

Sample output
4.73 V
String formatVolts(float volts) {
  char buffer[12];
  snprintf(buffer, sizeof(buffer), "%.2f V", volts);
  return String(buffer);
}

void setup() {
  Serial.begin(9600);
  Serial.println(formatVolts(4.7321));
}

void loop() {
}

Turn on JavaScript to edit, run and test this code in the browser.

Try it on a real Uno

Upload A clock on the display with the I2C LCD wired to A4 and A5. Then add the DS1307 RTC from Lesson 26 to the same two bus pins, and replace millis() / 1000 with the RTC's hour, minute and second - the snprintf line carries straight over.