Segway with brickpi NOT

I did’t find anyone on the internet who uses the brickpi for a segway type robot. So I decided to build one. More fun to do something that hasn’t been done already… :slight_smile:

First I tried to get an idea of the dIMU together with the brickpi - see my post in the dIMU Forum. In short, brickpi with dIMU is unusable in C and I assume it is unusable in python, too. The timing deviations are not acceptable for any PID system. And everything is far too slow!

Then I tried the dIMU with a NXT and RobotC. It was a weekend long journey, the Dexter Industries git repository stuff does not compile with a RobotC 4.x compiler, no common.h found in git… at the end I found a nice working system at the website of Soldaat.

The dIMU on NXT works steady as a rock, no jitter at all, and it takes 9ms to poll all 6 axis! This is faster then anything I was able to get with brickpi, C and/or phython. My fastest time in C was around 12ms…

So my impression is that brickpi is not able to do steady, fast and reliable polling. No idea if this is due to hardware design glitches or a badly programmed API. And I have no idea how brickpi and the I2C interface work together. But I would assume that a compiled C program must be able to read all axis in under 10ms.

Are there any plans on Dexter side to invest some time in a nice c API? Or may be even a linux hardware driver for Rasbian?




A few thoughts back on this. First, it would help to know what version of the BrickPi you’re using. If you’re using the latest, indeed the lag time will be too great. The microcontroller on the BrickPi is going to poll, then the Pi is going to poll the BrickPi, it’ll take at least 1/2 a second to get to you. However, if you’re using the older brickPi, there might be hope: it uses Port 5, which is directly accessed by the Pi.

So maybe we start there: what version of BrickPi are you using?


Hi John,

thanks for your fast answer!

I was an early adopter, my raspberry is the old one with a big SD card and the brickpi is from the first series. Firmware version is 876. No EV3 support but I don’t need that, I only use NXT stuff.

Hey Michael,

The version you have still has the Port 5; the direct connection to I2C on the Pi. This WON"T work for the BrickPi+ though.

Have you had a look at this code:

It might be a start at least, I’m not sure how fast this can poll the sensor.

Hi John,

that was a great tip! With port 5 I get the poll time down to 5-7ms. In python! The weather forecast for the weekend looks rainy so may be I find the time to try this in c.

It didn’t work out of the box, had to change from smbus(0) to smbus(1). No big deal. :slight_smile:

Thanks for your help, now I can investigate further.



Hey Michael, excellent news! Please let us know how it goes.

We took that port 5 off because virtually no one was really using it. However, maybe we can come up with a simple board that lets you connect I2C sensors directly to the Pi like this. So we’re all waiting on your results! We would also LOVE it if you shared your code with us!

Best, John

Hi John,

just to give you a short update:

Port 5 nails it! It is SO much faster and I get much better results and reach the timing I get on the original NXT platform. But the variation in timing is not gone. My results for reading 10.000 gyro/acc triples with the actual RfR system is:

pi@dex ~/Desktop/sources $ ./i2cgyro
reading 10000 gyro and acc triples needed 95911.870 msec
loop time between 2.796 and 31.946 msec
< 5ms: 12
<10ms: 9456
<15ms: 507
<20ms: 23
<25ms: 0
<30ms: 1
>30ms: 1

If you look at the spectrum you see that although most of the readings are around 10ms there are some readings that take over 30ms. Not very nice for a PID because I need a steady time base.

So my next try was to use my raspberry jessy lite system that I had adapted for brickpi usage. And with that I get far better results:

pi@brickpi:~/sources ./i2cgyro reading 10000 gyro and acc triples needed 95881.762 msec loop time between 2.791 and 12.003 msec &lt; 5ms: 1 &lt;10ms: 9777 &lt;15ms: 222 &lt;20ms: 0 &lt;25ms: 0 &lt;30ms: 0 &gt;30ms: 0 pi@brickpi:~/sources ./i2cgyro
reading 10000 gyro and acc triples needed 95881.576 msec
loop time between 6.546 and 12.474 msec
< 5ms: 0
<10ms: 9785
<15ms: 215
<20ms: 0
<25ms: 0
<30ms: 0
>30ms: 0

Always better then 15ms! I think that I can start to work with that. (And my basic idea, that RfR is too overloaded to be of realtime use seems to be right.)

Where to go from here?

The idea to start a bare metal brickpi system is compelling but far to tedious. But there might be another option: Have you folks at DEXTER ever tried to compile and use a RT linux kernel with RT Preemt defined? That shoud give much better real time capabilities - at least in theory. :slight_smile: I’m tempted to try it myself unless you have some experience and say it is useless.



That’s great to hear that you were able to get the response time down so far, excellent!

To answer your questions, nope, we haven’t tried to compile and use any other kernel than the one we use on Raspbian. If you go this route, we’d love to hear how it goes!

Hi John, time for the next update!

I have built a RT kernel for my two brickpi-SD cards. I don’t get much better results on my minimal system. I assume that there is not much running that might interfere with my running program so the benefit is small. But it really shines on the big Raspbian for Robots system:

pi@dex ~/Desktop/sources $ ./i2cgyro 
reading 10000 gyro and acc triples needed 96432.833 msec
loop time between 2.858 and 32.822 msec
&lt; 5ms:   40
&lt;10ms: 9304
&lt;15ms:  545
&lt;20ms:   59
&lt;25ms:   28
&lt;30ms:   18
&gt;30ms:    6
pi@dex ~/Desktop/sources $ ./i2cgyro 49
going realtime, prio = 49
reading 10000 gyro and acc triples needed 95876.807 msec
loop time between 3.161 and 11.092 msec
&lt; 5ms:    1
&lt;10ms: 9258
&lt;15ms:  741
&lt;20ms:    0
&lt;25ms:    0
&lt;30ms:    0
&gt;30ms:    0
pi@dex ~/Desktop/sources $ uname -a
Linux dex 4.1.16-rt17+ #1 PREEMPT RT Sat Feb 6 19:13:38 CET 2016 armv6l GNU/Linux

I pimped my i2c gyro test program and now it looks for a command line parameter. If there is none or the parameter is 0 the program will run in normal, non-RT mode. Otherwise it takes the number as the RT-priority of the process and switches to RT mode.

The first run is without RT. On the second run, I sat RT priority to 49 and all the jitter is gone. MaxTime went down from over 30 to 10! So I can use all the benefits of the RfR system, for example the VNC interface and the nice graphic UI, but with the RT kernel I don’t have to make compromises when it comes to the answer times of robot tasks. Great!

May be worth a discussion at Dexter HQ: Next RfR with RT kernel…?

Regards, Michael