Very low refresh rate with 16-Channel PWM Controller

For Adafruit customers who seek help with microcontrollers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
paultiplady
 
Posts: 3
Joined: Wed Apr 08, 2015 1:26 am

Very low refresh rate with 16-Channel PWM Controller

Post by paultiplady »

I'm trying to use the Adafruit PCA9685 16-channel PWM microcontroller to control ~160 servos from a Raspberry Pi.

I've got 10 16-channel microcontrollers on a single I2C bus, and I'm using the Adafruit Python library (with smbus-cffi) to send data to the servos.

I'm trying to send updates to all 160 channels at a refresh rate of 20Hz. I'd expect this to be well within the I2C protocol's 100KB/s bandwidth, but I'm finding that after adding more than one controller to the bus the controllers lag and only process updates at about 2Hz. I've profiled my code and pared it back to a very simple implementation, and my testing suggests that there's a bottleneck writing to the bus (I haven't determined whether the bottleneck is in the Python libraries or in the kernel device drivers).

Have these microcontrollers been stress-tested at high update frequency with multiple controllers on the same bus? Should I be able to send updates to 10 controllers on the same bus at 20Hz?

Any suggestions for issues to investigate would be much appreciated.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Very low refresh rate with 16-Channel PWM Controller

Post by adafruit_support_mike »

You're probably seeing the limits of the RasPi's time-slicing nature.

The process that sends messages to the Servo Controllers doesn't sit on the CPU 100% of the time. It only runs for about 10ms at a shot, then the OS suspends it and gives the other processes a turn.

The best way to test that would be to put the SCL line on an oscilloscope or logic analyzer with the timebase set to about 100ms and see how the pulses cluster. The behavior described above would produce 10ms blocks of activity separated by 50ms-100ms blocks of dead time.

User avatar
paultiplady
 
Posts: 3
Joined: Wed Apr 08, 2015 1:26 am

Re: Very low refresh rate with 16-Channel PWM Controller

Post by paultiplady »

If that is indeed the issue, is it possible to get around this by increasing the priority of the process? I'll try ionice and nice and report back, anything else that might fix it along those lines?

And, if that's just a limitation of the Pi, are there other I2C controllers that you can recommend that might be suitable for this task? I'm not tied to the Pi for this use-case, I can connect directly from a powerful PC through e.g. a USB-I2C adapter if that would give me better throughput.

Thanks

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Very low refresh rate with 16-Channel PWM Controller

Post by adafruit_support_mike »

Boosting the priority of the process should improve things (and if things do improve it's a sign that time slicing is probably a factor), but there will still be kernel processes with higher priority.

Any other computer will probably give you similar performance. The limits don't have anything to do with hardware power. The limiting factors are OS design and the limits on I2C data rate. For a 400kHz I2C connection, you get an upper limit of 4000 clock cycles per 10ms time slice. I2C clocks one byte every 9 cycles (8+ACK), so you're looking at an upper limit of 444 bytes per slice of runtime. From there, you have to find the frequency at which the process gets slices from the OS, but every major OS uses the same general strategy for preemptive multitasking.

An Arduino (or a similar microcontroller like the Pro Trinket or Teensy) has much less processing power (16MHz clock, 2k of RAM) but doesn't have the overhead from multitasking. It only runs one process (with minor adjustments for interrupt handlers), so it can give you a full 400 kbits per second (assuming your code can generate data fast enough to stay ahead of the I2C bus).

User avatar
adafruit_support_bill
 
Posts: 88088
Joined: Sat Feb 07, 2009 10:11 am

Re: Very low refresh rate with 16-Channel PWM Controller

Post by adafruit_support_bill »

I haven't tested specifically with servo control, but I did some performance tests on the V2 motor shield which uses the same PWM chip. With the motor shield, I was able to achieve over 1100 steps/second. Considering that each step requires setting at least 4 PWM channels, using an Arduino and the 16 channel servo shield, you should be able to issue several thousand channel updates per second.

User avatar
paulstoffregen
 
Posts: 444
Joined: Sun Oct 11, 2009 11:23 am

Re: Very low refresh rate with 16-Channel PWM Controller

Post by paulstoffregen »

I just took a quick look at the library code. Looks like setting a channel involves an address plus 5 bytes on the I2C bus.

https://github.com/adafruit/Adafruit-PW ... er.cpp#L75

With 9 bits per byte, plus start and stop, at 100 kHz that ought to take approx 0.6 ms per channel. For 100 channels, an update rate of approx 10 Hz should be possible, assuming the chip doesn't stretch any of the I2C clock cycles, and you've got strong pullup resistors to avoid rise time delays.

This would be a perfect job for Raspberry Pi & Teensy 3.1 combo, using USB between the two. Then the Pi could generate data and send it over USB, which is pretty efficient and fully buffered and interrupt driven on both the Pi and Teensy3 side. Normal AVR Arduino boards, even native USB ones like Teensy 2.0 and Arduino Leonardo are NOT interrupt driven on their USB stacks, so the Wire library being busy with the I2C bus can cause stalls on the incoming USB data. If you use a Teensy 3.1, it should be able to keep receiving the USB packets while busy on the I2C bus, to enable continuous streaming.

A regular serial-based Arduino board would almost certainly not work. While it could probably do the I2C communication, it wouldn't be able to simultaneously receive incoming serial data from the Pi at a high enough baud rate. This job really calls for a native USB interface with interrupts and substantial buffering, to allow the Wire library to keep manipulating the I2C bus as more packets arrive.

For 20 Hz, you'll need to increase the I2C clock rate. Faster I2C rates to such a large number of boards may be an issue, so a scope should be used to check the signal quality.

User avatar
paultiplady
 
Posts: 3
Joined: Wed Apr 08, 2015 1:26 am

Re: Very low refresh rate with 16-Channel PWM Controller

Post by paultiplady »

Thanks for the detailed responses guys -- very much appreciate your time. I'll go back to the drawing board and try these out.

For the record, running my process with nice --20 didn't have an appreciable effect.

I don't have the hardware to actually measure the I2C bus, so I'm just going to try dropping in a Teensy or Digispark and see how that does.

Locked
Please be positive and constructive with your questions and comments.

Return to “Microcontrollers”