How to increase 3pi speed


I ordered 3pi couple of months ago and played with it, programmed with PID algorithm for line following and was able to tune it so that it can drive track very stable with max speed to 255. I like it alot! This weekend I took it to our local robo competition and while it was it was in top part of pack, there where about 3 faster, custom built robots. So, I’m wondering if there is anything I could do to improove speed while reusing your nice and easy to work with platform/robot, or I need to build custom one?

I had ideas along those lines:

  • I tried to measure actual speed of stock 3pi going max speed (255) and it came down to aprx. 1m/s. That coresponds to aprx 600rpm with original 30mm wheels.
  • I would like to get it more or less twice as fast (2m/s), so would need 1200rpm at weels
  1. one option would be to try to go with 1:10 ratio instead of original 1:30, but keep the same motor ( But would it have enough torque? Have you tried similar experiments? 3pi is so small that I’m thinking it might actually work.

  2. somwhat related to this 2 years old discussion
    Extreme line following

would it be possible to run more stronger motors like this one Maybe any news since discussion above? As I see from previous discussion one of concerns where that current requirement for this more powerfull motor will be too high for either motor driver or voltage regulator. If so, would there be some more or less easy way to fix this by replacing on-board comonent with some other?

  1. if both of above are impossible/impractical, can you suggest anything else? (what new “platform”, motors? etc)

Thanks in advance,


I think that 10:1 gear ratios would result in something very uncontrollable. Your acceleration would be pretty low, which would make fast cornering very difficult. We’ve put in an HP motor in a 3pi with a lowered boost voltage, and it wasn’t controllable at full speed on our courses with 6" radius turns, so I think a 2x improvement will be too much for this chassis. Were the robots doing 2m/s with 6" radius turns, and did they have a similar size to the 3pi?

You should be able to get a 2x speed improvement by making your own chassis using the same wheels and the 30:1 HP gearmotors. In general, it will help to make the sensors farther ahead of the motors so that you can get as much notice as possible about upcoming turns.

- Jan

Thanks for quick replay!

Here is video from winer robot:
This is from 2008 but still the same one where fastest this year and also the same track was used. Corners are with somewhat bigger radius than 6". Something between 8"to 12". Also as you see robot is bigger. I guess his speed was not really 2 m/s, but close - like 1.7m/s (my laptime 8sec, his 5sec)

I was thinking maybe small size/weight of 3pi would be as advantage if we could fit more powerful motor in there and be able to drive it to full speed. But probably you are right - HP motor with new chases would be a way to go.

On this topic - HP motors are 1.6A (yes?) but most of motor drivers you have listed are for 1A. How would you recommend to drive them to be able to use full power? As I understand also it won’t be possible to use your 2.5-9.5V boost regulators because of current req. or will it?


You could use one TB6612FNG per motor, with the outputs paralleled to get about 2A output capability. For the power supply, you could just start with a higher voltage; if you really like our boost approach, you could use one per motor, or make your own higher-power boost converter.

- Jan


You should also note that the HP motors have a stall current of 1.6 A at 6 V and the TB6612 can deliver a maximum of 3 A per channel. The free-run current of the HP motors is below the 1 A continuous current rating of the driver, so a single TB6612 will work if you keep the voltage low (around 6V) and you keep the motors from stalling for prolonged periods of time or from suddenly changing from full-speed forward to full-speed reverse (this isn’t something that should happen when following a line).

As Jan said, we have used 3pis with HP motors on them, but we had to lower the boost voltage and take greater care when writing code to limit abrupt accelerations (PID usually does a good job of this when things are well tuned and a terrible job of this when they’re not).

Our latest Orangutan robot controller, the Orangutan SVP has two TB6612s in parallel, so it can deliver a continuous 2 A per channel (6 A max).

- Ben

Thanks Ben,

So, maybe I will order HP motors and try them first in 3PI as a first step, and then go from there.

BTW, how it is possible to change boost voltage? I don’t think there is potentiometer for this on 3pi. Would I have to resolder some resistor?

Thank you both,

Yes, you would have to swap out a resistor.

- Jan

Hi Jan and Ben,

Just wanted to asked a quick question. Can I used the 3pi library with the SVP1284?



I don’t really understand your question. We offer the Pololu AVR library, which works with our Orangutan robot controllers and the 3pi robot. There are some 3pi-specific functions in this library, but you wouldn’t use these on the Orangutan SVP-1284.

- Ben


Sorry for my previous post - what I mean was, there are some neat functions in 3pi - like this line sensing and etc. What I mean was - if I used the 3pi.h file in the SVP and used almost exactly the same code - can that run in SVP 1284? Or do I need to change some parts of it so it will work in SVP. Let’s take an example for the line sensor, in 3pi, we need to connect to the line sensor to PC0 and so on, where do I need to connect it in SVP and used the same code?

Hope I made it clear - if not, well, I am online now - I will try again,


I don’t think there’s anything to be gained by trying to make the 3pi-specific code work on the SVP. Rather, I would just use the more general library functions. For example, the PololuQTRSensors section of the library provides code for interfacing with QTR sensors. The 3pi line sensor code just initializes a PololuQTRSensors object for the specific sensors on the 3pi. I think you should make your own initialization function for the number and type of sensors you have on the I/O lines you want to use. Does this make sense?

- Ben


Thanks a lot.

Hi Ben,

I got your SVP-1284. I am just wondering where should i connect the QTR8RC. The sample code
unsigned char qtr_rc_pins[] = {14, 15, 16};

what pins is 14, 15 and 16? Is there a way for me to increase the number of pins?

Thanks again,

The QTR sensors section of the library command reference explains how to use the QTR functions (the documentation for the initialization function qtr_rc_init() is near the bottom of the page and answers the two questions you asked).

Note that we have added digital I/O support to the library since that example was written, so we now have some convenient constants you can use instead of pin numbers. The constants have the form IO_LN, where L is the port letter and N is the port number, so you would use the constant IO_C4 for pin C4 (see section 4 for more information). This makes it easier to write your pins array. Once you know what pins you want to use, you can make your array something like:

unsigned char qtr_rc_pins[] = {IO_D3, IO_D2, IO_D1, IO_D0, IO_C1, IO_C0, IO_B4, IO_B3};

- Ben

Hi jan,

Thanks a lot. Kind of weird thing on my SVP - I used this:

unsigned char qtr_rc_pins[] = {IO_D3, IO_D2, IO_D1, IO_D0, IO_C1, IO_C0, IO_B4, IO_B3};

but IO_C0 and IO_C1 will not work - it does not return any values. But when I changed the exact number of
IO_C0 and IO_C1 based on the previous 14 and 15 respectively - everything works fine. I guess i might have to change

Anyhow, just one more quick thing - I wanted to used the encoder and line sensing at the same time, but when I tried to
initialize the encoder:
// reset encode counts

just right after the line sensor calibration - PB4 stops working. Is PB4 connected to the encoder?

Thanks again.

It looks like we never updated the QTR sensor library for the Orangutan SVP and Orangutan X2, which is why you’re having problems with the IO_Cx macros from OrangutanDigital (since OrangutanDigital has been updated for the SVP). Unfortunately, you won’t be able to use the IO_Ax pins with the QTR sensor library until we update it.

Your problem with PB4 is that it is the slave-select line of the SPI module, so there are restrictions on its use when you are communicating with the auxiliary MCU (as happens when you try to read the encoders). The SPI module will only work in master mode if PB4 is an input that reads high (the Pololu AVR library configures it as a input with the internal pull-up enabled once the SPI module is initialized) or if it is an output. You should be able to alternate reading the encoders and QTR sensors by manually configuring PB4 as an output when you want to use SPI and as an input with internal pull-up disabled when you want to read the sensors.

- Ben

Hi Ben,

Thanks for the prompt reply. Anyhow, with regards to the line sensing and encoder - I guess I might find some means to compute the speed of the robot. Does this mean that I cannot used the USB capability of SVP if I will used the line sensor?

Pin PB4 will affect all communication between the user MCU (ATmega1284) and the auxiliary MCU, so if you want to use PB4 for the line sensor, you will need to manually configure the state of PB4 as is appropriate for whatever action you are trying to perform (i.e. set it as an output or pulled-up input when using SPI). If you set it as a pulled-up input, you should delay for a few milliseconds to let the voltage rise and stabilize before you try using SPI. You could also just use seven of the eight reflectance sensors and leave pin PB4 free, or you could to add support for port A pins to the QTR library source code (if you don’t want to wait for us to do it).

- Ben

I did some experiments. It turns out that PB4 can not be used as a digital input while the SPI module is enabled (PINB bit 4 is always 0). We already knew that using PB4 as a digital input could cause the SPI module to fail (that’s why the SVP user’s guide says that we recommend making PB4 an output), but we didn’t know that SPI causes digital input to fail. If you really want to use PB4 as an input, you can temporarily disable the SPI module (by clearing the SPE bit in SPCR).

So jlake, if you want to get all 8 of your QTR sensors working right now, I suggest adding code around your QTR-reading code like this:

unsigned char saved_spcr = SPCR;   // Save the state of the SPI module
SPCR &= ~(1<<SPE);                 // Disable SPI module so PB4 can be used as input
qtr_read(values, QTR_EMITTERS_ON); // change this to whatever type of QTR reading you want to do
set_digital_output(IO_B4, LOW);    // Make PB4 an output so it doesn't interfere with SPI.
SPCR = saved_spcr;                 // Restore the state of the SPI module.

This code worked for me, allowing me to read analog channel A from the auxiliary processor via SPI and also read a QTR-RC sensor on PB4 in the same program. This code also works if you drive PB4 high instead of low, but that would cause increased power consumption.

Also, later today we should have a new version of the Pololu AVR Library out that allows you to use pins A0-A7 for your sensors, so you won’t have to deal with the quirks of PB4. When we release it, we’ll make an announcement in the announcements forum.


I didn’t manage to officially release the new AVR library and update the documentation today, but I have made the new version available for you to download at this link: …

That should let you put QTR sensors on port A using the IO_A0…IO_A7 macros, so there is no need to try to get them working on PB4. Enjoy!