flipZH
Posts: 4
Joined: Thu Sep 20, 2018 4:36 pm

CAN Speed Pi 3B+ vs. Pi Zero W

Mon Oct 22, 2018 4:03 pm

Hi all,

I could not find a solution to this issue, so here goes:

I have an RPi 3B+ and an RPi Zero W and I am comparing CAN Bus performance in Python 3 by sending 100 8-Byte CAN frames (with all zeros to get a worst-case timing in terms of additional bit-stuffing). The code I am running is stated below.

I get quite a big difference in timing: On the 3B+, I get between 25 and 30ms, while the Zero W only manages about 95ms, so a factor of 3-4 slower. These timings were confirmed with a CAN-USB adapter on a PC.

The 3B+ is running Stretch Desktop and the Zero is running Stretch Lite, both recent installs.

For both, I configure the CAN Bus with the following lines in /boot/config.txt and to run at 1MBps:

Code: Select all

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
# config can over spi
dtoverlay=mcp2515-can0:oscillator=16000000,interrupt=25
#dtoverlay=spi-bcm2835-overlay
This results in using the default spimaxfrequency of 10MHz. Of course, a max value means that the actual SPI clock may not be 10MHz, so I thought that maybe the Zero is running a slower SPI frequency, but it turns out that the Zero is running a 10MHz clock, while the 3B+ runs at a slower 6.25MHz. I measured this with a scope on Pin 23, SCLK.

My questions are:
  • Why is the Zero this much slower? Is this just caused by the slower processor in combination with Python? I assume that if I wrote a baremetal test, the two would produce the same identical timing, as the processor and the SPI interface are a lot faster than the CAN Bus. Or might this be an issue with the CAN driver on the Zero?
  • How can I get the 3B+ to also use a 10MHz SPI Clock? I assume that this is an issue with the clock divider as mentioned in [1]? I tried setting core_clock=250 in /boot/config.txt, but the SPI clock stayed at 6.25MHz.
Thank you very much for any inputs!
Philipp

[1]: viewtopic.php?f=44&t=43442&p=347073

Code: Select all

import can
import time


if __name__ == '__main__':

    bus = can.interface.Bus(channel='can0', bustype='socketcan')

    msg = can.Message(arbitration_id=0x000,
                      data=[0, 0, 0, 0, 0, 0, 0, 0],
                      extended_id=False)

    N_SEND = 100
    init = time.time()
    try:
        for i in range(N_SEND):
            bus.send(msg, timeout=None)
        send_time = (time.time() - init) * 1000.0
        print('Time for {} msgs was {:.2f}ms.'.format(N_SEND, send_time))
    finally:
        bus.shutdown()
Last edited by flipZH on Tue Oct 23, 2018 3:11 pm, edited 1 time in total.

danjperron
Posts: 3076
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: CAN Speed Pi 3B+ vs. Pi Zero W

Mon Oct 22, 2018 6:41 pm

How can I get the 3B+ to also use a 10MHz SPI Clock? I assume that this is an issue with the clock divider as mentioned in [1]? I tried setting core_clock=250 in /boot/config.txt, but the SPI clock stayed at 6.25MHz.
I thought it was core_freq and not core_clock
https://starfishmedical.com/2018/07/18/ ... conundrum/
Why is the Zero this much slower? Is this just caused by the slower processor in combination with Python? I assume that if I wrote a baremetal test, the two would produce the same identical timing, as the processor and the SPI interface are a lot faster than the CAN Bus. Or might this be an issue with the CAN driver on the Zero?
Good chance that a quad core cpu helps! Did you try to set the clock speed at 6.25Mhz on the pizero?

flipZH
Posts: 4
Joined: Thu Sep 20, 2018 4:36 pm

Re: CAN Speed Pi 3B+ vs. Pi Zero W

Tue Oct 23, 2018 9:23 am

I thought it was core_freq and not core_clock
Yes it is, thank you! Now the 3B+ has the 10MHz SPI clock. However, this did not affect the timing much, the 100 messages are still in the 25-35ms range. This suggests that the SPI clock itself is not really the bottleneck - which kind of makes sense given that the SPI runs much faster than the CAN bus even at 6MHz. I won't check the 6.25MHz on the zero, therefore, but thank you for the great suggestion!

Also, the 25-35ms are actually pretty great considering that in theory, the CAN Bus could send these messages at best in about 12.6ms (assuming 126 bits to send per 8-byte frame at 1MBps).

flipZH
Posts: 4
Joined: Thu Sep 20, 2018 4:36 pm

Re: CAN Speed Pi 3B+ vs. Pi Zero W

Tue Oct 23, 2018 1:14 pm

Small update: My work colleague had the great input of also running the speed test using canplayer on the PiZero (i.e. a C++ implementation) using the -t parameter causing messages to be sent as quickly as possible: The time improved to 40ms for 100 messages, indicating that indeed the processing power required to run the Python overhead is likely causing the slower performance of the zero.

flipZH
Posts: 4
Joined: Thu Sep 20, 2018 4:36 pm

Re: CAN Speed Pi 3B+ vs. Pi Zero W

Tue Oct 30, 2018 4:55 pm

One more update:

Turns out that for the 3B+, I was using a power supply that was too weak - as processing power was requested to run the Python code, the power supply limit was reached and probably the CPU throttled. Great newbie mistake.

With a proper power supply, the Python code reports a time of 7.8ms to 13ms for sending the 100 frames. This is under the theoretically possible limit of 12.6ms (100% busload), which means that Python runs faster than the underlying Socketcan driver.

Indeed, checking with a CAN receiver, I find that the messages are arriving in about 20ms, and very consistently so. This is actually quite good as it indicates a busload of about 63-64%.

Return to “Interfacing (DSI, CSI, I2C, etc.)”