Difference between jupyter notebook and terminal when using shell command


I found an interesting difference when using shell command in PYNQ jupyter notebook and PYNQ terminal.

When I type the following code in terminal

printf “%b” ‘\x66\x6f\x6f’ > /dev/ttyPS0

“66 6F 6F” will be detected in UART TX.

When I type the following code in jupyter notebook

printf “%b” ‘\x66\x6f\x6f’ > /dev/ttyPS0


!printf “%b” ‘\x66\x6f\x6f’ > /dev/ttyPS0

“5C 78 36 36 5C 78 36 66 5C 78 36 66” will be detected in UART TX.

What makes that difference?
(The behavior of “echo” is similar with “printf”.

“66 6F 6F” is what I want, but I also want to send UART data in jupyter notebook directly. Could anyone help me with that?

My board is Ultra96-v2.

Thank you very much.

Chao Zhang

The IPython shell environment isn’t preprocessing strings same way that the shell does. I don’t know why that is but there are a couple of ways around it that I can see.

First you can assign your data to a variable abd then printf that

data = "\x66\x6f\x6f"
!printf "%b" $data > /dev/ttyPS0

Be aware that this might cause problems with characters above 127 due to Python starting to UTF-8 encode the bytes.

Is there a reason not to use a Python function? Something like

def write_serial(data):
    with open(" /dev/ttyPS0", 'rb', buffering=0) as f:


This would let you pass in binary string (with fixed 8-bit characters) avoid any potential Unicode issues.

Thank you very much! The first solution works well for me.