I have written an app to communicate with an intelligent UPS. It works fine on a Raspberry Pi 2, but seems to operate at the wrong baud rate on a Raspberry Pi 3 model B running Raspbian bullseye.

This is the code that I use to access the serial port:

uart0_filestream = open("/dev/serial0", O_RDWR | O_NOCTTY | O_NDELAY);  
if (uart0_filestream == -1)
    printf("Error - Unable to open UART\n");
    return false;

struct termios options;
if (tcgetattr(uart0_filestream, &options) != 0)
    printf ("tcgetattr failed");
options.c_cflag = 0;        
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
options.c_cflag |= CS8 | CSTOPB | CLOCAL | CREAD;       
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);

if (tcsetattr(uart0_filestream, TCSANOW, &options) != 0)
    printf ("tcsetattr failed");

Connecting a scope to the serial Tx of the Raspberry Pi 3, this is what I see when I send a character 'a': note that the bit time is 170us, which corresponds to 5885 baud.

Any suggestions for how to make the Pi use the correct baud rate?

Raspberry PI Tx line

  • I see no executable code; no details of what is connected. Try a simple test e.g. a loopback .
    – Milliways
    Commented Nov 24, 2023 at 9:56
  • Look in /boot/overlays/README for an option to fix the core clock frequency. The serial clock ,ay be derived from this clock and will vary as the core clock varies.
    – joan
    Commented Nov 24, 2023 at 20:26
  • Have you made this same measurement on the Raspberry Pi 2 - the one that your app works on? Also - it would make it so much easier to read if you'd set the scope to trigger on a trailing edge that corresponded to t=0. Could you do that?
    – Seamus
    Commented Nov 24, 2023 at 23:18
  • I set it up again to provide more information, and it now works correctly: the bit time is 104us, and Teraterm can send and receive information correctly. No code changes, no hardware changes... it just started working. As a result, I'm closing this question.
    – JavaLatte
    Commented Nov 25, 2023 at 13:47
  • Ah, I don't have enough standing on this site to close this question :-/
    – JavaLatte
    Commented Nov 25, 2023 at 13:50

2 Answers 2


This isn't intended to be a complete answer, but hopefully will give you something to go on:

It's always best to consult the documentation for these things; in this case, Configuring UARTs. Note in the table Primary and Secondary UART, there is a hardware diff between Pi 2 and Pi 3; i.e. UART0 is primary on RPi 2, but secondary on RPi 3. The miniUART UART is primary on RPi 3.

You didn't mention what pins you were measuring on. According to the documentation, the primary UART is on GPIO 14 (pin 8) and GPIO 15 (pin 10). However, for the RPi 3, the UART connected to pins 8 & 10 would be the miniUART. But that doesn't change the fact that the mini UART has a "reduced feature set", described here, with additional details here

And so, I wonder if this might be the cause of your issue?

I'll go out a bit further on this limb, and suggest you may also wish to consult the UARTs & Device Tree section. Perhaps the miniuart-bt overlay in /boot/overlays/README on your RPi (or here on GitHub) will be of some help?

Info:   Switch the onboard Bluetooth function on Pi 3B, 3B+, 3A+, 4B and Zero W
        to use the mini-UART (ttyS0) and restore UART0/ttyAMA0 over GPIOs 14 &
        15. Note that this may reduce the maximum usable baudrate.
        N.B. It is also necessary to edit /lib/systemd/system/hciuart.service
        and replace ttyAMA0 with ttyS0, unless using Raspbian or another
        distribution with udev rules that create /dev/serial0 and /dev/serial1,
        in which case use /dev/serial1 instead because it will always be
        correct. Furthermore, you must also set core_freq and core_freq_min to
        the same value in config.txt or the miniuart will not work.
Load:   dtoverlay=miniuart-bt,<param>=<val>
  • Thank you for the information. I think that the problem was some mis-coordination between the system clock and the miniUART baud rate. It did happen consistently over two or three days, but it's not happening at the moment, I will monitor for any recurrences.
    – JavaLatte
    Commented Nov 26, 2023 at 2:50
  • @JavaLatte: Well that's actually the whole point... if you're using the miniUART, the frequency is dependent upon the variable VPU clock - which is "not a good thing". It's possible that the VPU frequency has changed since your issue arose, and it's now at the proper frequency. Getting the /boot/config.txt setup correctly is the key to solving this issue, but to do that requires that you disclose which version you're using (i.e. bookworm v bullseye v ???). Sorry if that's unclear or confusing, but you're much better off fixing it now instead of waiting for it to recur.
    – Seamus
    Commented Nov 26, 2023 at 3:37
  • PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)". I have not made any changes to /boot/config.txt yet.
    – JavaLatte
    Commented Nov 26, 2023 at 4:51

I still see no code that anyone could execute.

It is unclear why you are using this unusual code, but there is one obvious error you are attempting to set CSTOPB but the mini UART only supports 1 stop bit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.