What is the difference between Serial.write and Serial.print? And when are they used?
Both have been used to print on serial monitor, what are their actual differences?


Serial.write is more down to earth , it is simple and fast, it is made to talk binary, one byte at a time. example:

Serial.write(0x45);   // will write 0100 0101 to the cable

Serial.print in the other hand is more versatile , it will do the conversion for you from ASCII to binary it also can convert to BIN/ HEX/OCT/DEC but you need to specify a second argument like so

Serial.print(76, BIN) gives "0100 1100"
Serial.print(76, OCT) gives "114"
Serial.print("L", DEC) gives "76"
Serial.print(76, HEX) gives "4C" 

more examples with visual serial output :


  Serial.write(0x48);   // H
  Serial.write(0x45);   // E
  Serial.write(0x4C);   // L
  Serial.write(0x4C);   // L
  Serial.write(0x4F);   // O

SERIAL OUTPUT : enter image description here



SERIAL OUTPUT : enter image description here

Serial.println() in the other hand will add end of line 2 bytes 0x0D and 0x0A as you can see in the frame




enter image description here


From the Arduino site for Serial.write and Serial.print:


Writes binary data to the serial port. This data is sent as a byte or series of bytes; to send the characters representing the digits of a number use the print() function instead.


Prints data to the serial port as human-readable ASCII text.


Serial.write sends bytes to the serial port while Serial.print sends ASCII characters so people can read easily.

Some devices work using bytes to set configurations, commonly use packets of data and you need to use write function to communicate with them. Eventually they will send bytes through serial interface and then you can interpret by going each byte.


All of the examples above are correct, but maybe more clearly.... All data sent through the serial port is sent as 1's and 0's. (obvious.... I hope)... The difference in the two commands is how whatever is being sent is actually translated/interpreted to/from these 1's and 0's. The clearest example involves transmitting numbers.

Let's say you need to send the number 217. The binary (1's and 0's) representation of this number is 11011001. Using the command Serial.write(217) will literally just send 11011001 across the line. The Hex representation of the same number is 0xD9, and the command Serial.write(0xD9) will send the same thing ... 11011001.

Here is where it gets interesting... If you were to use the command Serial.write("217") you would instead get this: 00110010 00110001 00110111... WHAT?!?!?
When a string is passed as the argument it is broken down into individual characters, converted to ASCII, and then sent as a byte for each character. You would get the exact same output if you were to use the following:


(00110010 00110001 00110111)

Now let's look at Serial.print(). The commands Serial.print(217) or Serial.print("217") will both print the same thing: 00110010 00110001 00110111. This is because the print command first converts any number to a string representation and then uses the command Serial.write() to send each character as individual ASCII bits.

Though this is not a COMPLETE description, I hope it helps to get you thinking in the right direction...


Yet another way to answer this is to state the Serial.write accepts single characters where Serial.print accepts strings. There may be some differences but this is the main one.

  • What about Serial.write(stringData.c_str());? if stringData is defined as String. – jstuardo Jan 24 '20 at 22:30
  • Please show how stringData is defined as String. – linhartr22 Jan 25 '20 at 23:33
