Learn

Arduino Serial.print() and println(), line by line

Start building free

Or see every lesson.

  • 455parts on the bench
  • 43boards running now
  • 1.00xreal time, on every board
Arduino Uno: printing to the serial monitorlive0.000 s 0.00x
Click to open it in the editor
A greeting, pi to five places, the uptime once a second, and an echo of what you type.

Serial.print(x) sends x to the serial monitor and stays on the same line. Serial.println(x) does the same and then ends the line, so the next thing printed starts on a new one. Call Serial.begin(9600) once in setup() first, and set the serial monitor to the same speed.

The circuit above is an Uno on its own, talking to the serial monitor. Press Run. It prints "Mokxi Arduino Uno: serial example", then "pi to five places is 3.14159", then "up 1000 ms", "up 2000 ms" and so on, once a second. Type a letter into the box under the monitor and press Enter: an A comes back as "you typed: A (0x41)", and the Enter as "you typed: <newline>".

Below is how print and println differ byte by byte, how to choose decimal places and number bases, the wrong way to print text and a number together, and what printing costs in time, each run on an Uno with what it printed.

Want the step-by-step version? The lesson "Making the board talk" walks through this with checkpoints.

Open the lesson

The sketch

Here is setup() from the sketch running above. Serial.begin(115200) opens the port at 115200 baud. print() writes "pi to five places is " and leaves the line open, and println(3.14159265, 5) adds the number with five decimal places and ends the line.

Print before Serial.begin() and nothing comes out. We printed "before begin" first and "after begin" second, and only "after begin" arrived.

firmware/uno/examples/serial (the setup() running above)
void setup() {
  Serial.begin(115200);
  Serial.println("Mokxi Arduino Uno: serial example");
  Serial.print("pi to five places is ");
  Serial.println(3.14159265, 5);
}

print against println

Three prints and a println, print("a"), print("b"), println("c"), printed "abc" on one line, and the next println started a new one. The line ending println adds is two bytes, a carriage return and a newline, \r\n. The serial monitor hides them; a program reading the port, or another board, sees both.

Serial.println() with nothing in the brackets just ends the line, which is handy after a row of prints.

One line from four calls
void setup() {
  Serial.begin(9600);
  Serial.print("a");
  Serial.print("b");
  Serial.println("c");
  Serial.println("next line");
}

void loop() {
}

Decimal places, HEX and BIN

A float prints with two decimal places unless you say otherwise. Serial.println(3.14159) printed 3.14. Give the number of places second: println(3.14159, 4) printed 3.1416, rounded, and println(2.0 / 3, 3) printed 0.667. With 0 places it rounds to a whole number, halves up: 1.5 printed 2 and 2.5 printed 3.

For a whole number, the second value is the base. println(255, HEX) printed FF and println(5, BIN) printed 101, with no leading zeros, so pad it yourself if you want all eight bits. A negative number in HEX shows all four bytes of a long: -1 printed FFFFFFFF.

Places and bases
void setup() {
  Serial.begin(9600);
  Serial.println(3.14159);
  Serial.println(3.14159, 4);
  Serial.println(2.0 / 3, 3);
  Serial.println(1.5, 0);
  Serial.println(2.5, 0);
  Serial.println(255, HEX);
  Serial.println(5, BIN);
  Serial.println(-1, HEX);
}

void loop() {
}

Numbers, letters and write()

print() decides how to show something by its type. println(65) printed 65, println('A') printed A, and a bool printed 1. Serial.write(65) is different: it sends the byte itself, and the monitor shows the character with that code, an A. Use print() for people and write() for sending raw bytes to another device.

print() also returns how many characters it sent. int n = Serial.print("hello"); gave 5.

Text and a number on one line

The quick way that does not work: Serial.println("Temp: " + t); with t at 21 printed a few stray symbols. Adding a number to quoted text moves along the text instead of joining, and 21 letters along is past the end of "Temp: ". Clang warned: adding 'int' to a string does not append to the string. The plain way is two calls, Serial.print("Temp: "); then Serial.println(t);, and "Temp: " + String(t) works too; both printed "Temp: 21".

People who know C reach for sprintf(). It works for whole numbers: "%02d:%02d" with 7 and 5 printed 07:05. On an Uno it does not do floats: %f printed "t=?", because the Uno’s small printf leaves floats out. Use dtostrf(t, 6, 2, buf), which printed " 21.50", or print the float on its own. And %d is an int: given a long of 100000 it printed -31072, with a warning; use %ld for a long.

sprintf on an Uno
void setup() {
  Serial.begin(9600);
  char buf[40];
  float t = 21.5;
  sprintf(buf, "t=%f", t);
  Serial.println(buf);
  dtostrf(t, 6, 2, buf);
  Serial.println(buf);
  sprintf(buf, "%02d:%02d", 7, 5);
  Serial.println(buf);
  long big = 100000;
  sprintf(buf, "%d", big);
  Serial.println(buf);
  sprintf(buf, "%ld", big);
  Serial.println(buf);
}

void loop() {
}

What printing costs, and F()

Printing takes time, set by the baud rate. At 9600 baud a character takes about a millisecond to send. The Uno keeps a 64-byte queue, so a short line goes into the queue and the sketch carries on, but a long one waits for room. A line of 100 characters took 38504 microseconds to print at 9600 baud, and 3168 at 115200. A sketch that prints a lot at 9600 spends most of its time printing; use 115200 unless something else sets the speed.

On an Uno, every piece of quoted text in a sketch is also copied into its 2048 bytes of RAM when it starts. Wrap fixed text in F(), as in Serial.println(F("from flash"));, and it is read from flash instead, where there is far more room. It printed "from flash" exactly as before. For a sketch with a lot of messages it is the easiest RAM to get back.

If the monitor shows nonsense instead of words, its speed does not match Serial.begin(). The serial monitor garbage page has that and the other causes.

Questions

What is the difference between Serial.print and Serial.println?

print() sends the text and stays on the same line. println() sends it and then a carriage return and a newline, so whatever comes next starts on a new line.

How do I print a float with more decimal places?

Give the number of places after the value: Serial.println(3.14159, 4) prints 3.1416. Without it a float prints with two places.

How do I print text and a variable on the same line?

Use two calls: Serial.print("Temp: "); then Serial.println(t);. Or join them as Strings, "Temp: " + String(t). Writing "Temp: " + t without String() prints part of the text or garbage.

Why does sprintf print a question mark for a float on Arduino?

The Uno’s printf is built without float support, so %f prints ?. Convert the float with dtostrf() first, or print it with Serial.print(t, 2).

Why does my serial monitor show nothing?

Check that Serial.begin() runs before the first print and that the monitor is set to the same baud rate. Anything printed before Serial.begin() is lost.

How do I print a number in HEX with a leading zero?

`Serial.println(10, HEX)` printed "A" and `Serial.println(255, HEX)` printed "FF": print() leaves leading zeros out. For a byte, print the zero yourself when it is below 0x10. `if (b < 0x10) Serial.print("0");` before `Serial.println(b, HEX);` printed "0A".

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.