Ensuring Reliable RS-485 Communication
On the CPi-A, CPi-B, and CPi-S panel PCs, the RS-485 port utilizes the Broadcom SoC's mini-UART. The mini-UART has a number of limitations that need to be considered to ensure reliable communication. Please see the Raspberry Pi documentation for detailed information on the mini-UART.
To avoid the limitations of the mini-UART altogether, consider the CPi-C panel PCs, as their RS-485 port does not utilize the mini-UART, and is not subject to its limitations.
The mini-UART's clock is dependent on the SoC's core clock. This means that, to ensure reliable communication, the SoC's core clock frequency must be stable1). To ensure the SoC's core frequency is stable, please implement all of the following:
- Ensure
core_freq=250(Bullseye) orcore_freq_fixed=1(Bookworm) is added to the /boot/config.txt file to ensure the core frequency is configured to a predictable setting. - Install cpufrequtils with
sudo apt install cpufrequtils, and change the contents of /etc/default/cpufrequtils to <html>GOVERNOR="performance"
</html>. The default is
ondemand, which should actually be fine for most use cases, butperformancewill provide extra insurance. Reboot and confirm withcat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor. - Ensure the core frequency does not throttle due to high temperatures. The SoC should not begin throttling unless the core temperature reaches 80℃ 2), so to ensure reliable communication, the SoC's core temperature must remain lower than 80℃.
To check the current core temperature run vcgencmd measure_temp and ensure it remains below 80℃.
To check the current core frequency run vcgencmd measure_clock core and ensure it remains stable.
To check if the system has been throttled run vcgencmd get_throttled. See the Raspberry Pi documentation for information on how to interpret the output. Or inspect the “Throttled” output from the following script:
#!/bin/bash #Flag Bits UNDERVOLTED=0x1 CAPPED=0x2 THROTTLED=0x4 SOFT_TEMPLIMIT=0x8 HAS_UNDERVOLTED=0x10000 HAS_CAPPED=0x20000 HAS_THROTTLED=0x40000 HAS_SOFT_TEMPLIMIT=0x80000 #Text Colors GREEN=`tput setaf 2` RED=`tput setaf 1` NC=`tput sgr0` #Output Strings NO="${GREEN}NO${NC}" YES="${RED}YES${NC}" #Get Status, extract hex STATUS=$(vcgencmd get_throttled) STATUS=${STATUS#*=} echo -n "Status: " (($STATUS!=0)) && echo "${RED}${STATUS}${NC}" || echo "${GREEN}${STATUS}${NC}" echo "Undervolted:" echo -n " Now: " ((($STATUS&UNDERVOLTED)!=0)) && echo "${YES}" || echo "${NO}" echo -n " Run: " ((($STATUS&HAS_UNDERVOLTED)!=0)) && echo "${YES}" || echo "${NO}" echo "Throttled:" echo -n " Now: " ((($STATUS&THROTTLED)!=0)) && echo "${YES}" || echo "${NO}" echo -n " Run: " ((($STATUS&HAS_THROTTLED)!=0)) && echo "${YES}" || echo "${NO}" echo "Frequency Capped:" echo -n " Now: " ((($STATUS&CAPPED)!=0)) && echo "${YES}" || echo "${NO}" echo -n " Run: " ((($STATUS&HAS_CAPPED)!=0)) && echo "${YES}" || echo "${NO}" echo "Softlimit:" echo -n " Now: " ((($STATUS&SOFT_TEMPLIMIT)!=0)) && echo "${YES}" || echo "${NO}" echo -n " Run: " ((($STATUS&HAS_SOFT_TEMPLIMIT)!=0)) && echo "${YES}" || echo "${NO}"
