3pi Downloads

One of our members runs robomo.com

Anyway… I got one to experiment with and write a review on. I program mostly in BASCOM BASIC mcselec.com/ so I wanted to get started right away.

Before I actually change the existing code… is there a place I can download the HEX file of the program currently loaded so I can reprogram it should I need to reload the demo? Is this C program available to download and study?

Also… I ran through the demo program… everything was fine until I got to the MOTORS part… I see the screen with:


And I realize that you hit the keys to change the states of the “A” to “a” and the “C” to “c” to select a motor movement… but what do you need to do to actually get the motors to move? Is there something I am missing? :cry:


I just figured it out… you have to HOLD the A or C buttons down… then the motors ramp up. The quick start guide needs to have that little tidbit in there! Okay… so now I’m ready to start programming this thing!

Jerry :sunglasses:


I’m glad to hear that you figured out that part of the demo program! You can get complete instructions and source code for the demo program and some examples from the 3pi User’s Guide. There’s a whole page in there about how to use the demo program. Even if you are going to use BASCOM, I recommend that you get AVR Studio set up for compiling our example code, so that you can more easily learn about how we do things in C. If that’s not enough for you, I’ve put the .hex file up on the 3pi resources page.

When you get BASCOM working with the 3pi, please post some sample code to the forum. We’d be interested to see how it looks! Do you have any contest or task in mind for your 3pi already?

I wanted to start off with a language I am familiar with… then try C and/or assembler. I wrote some simple code to use the LCD display, blink some LEDs, and run the motors forward and reverse.

$regfile = "m168def.dat"       ' Set the chip as a Mega 168
$crystal = 20000000       ' Clock speed 20 MHZ
$baud = 9600       'Set Baud Rate, default TXD pin used [ Port D.1 ]
Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.4 , Db6 = Portb.5 , Db7 = Portd.7 , E = Portd.4 , Rs = Portd.2
Config Lcd = 16 * 2       ' Actually 8x2 but that is not recognized by BASCOM.
Config Portb = Output
Config Portc = Output
Config Portd = Output
' Pin Configurations
' Portb.0 - LCD Function R/W
' Portb.1 - LCD Data DB4                    ( Switch A )
' Portb.2 - Buzzer
' Portb.3 - Motor 2 Control Line
' Portb.4 - LCD Data DB5                    ( Switch B )
' Portb.5 - LCD Data DB6                    ( Switch C )
' Portb.6 -
' Portb.7 -
' Portc.0 - IR Sensor #1 ( Left )
' Portc.1 - IR Sensor #2
' Portc.2 - IR Sensor #3 ( Center )
' Portc.3 - IR Sensor #4
' Portc.4 - IR Sensor #5 ( Right )
' Portc.5 - ADC5
' Portc.6 - Motor Controller Not Standby
' Portc.7 -
' Portd.0 - RXD
' Portd.1 - TXD                                      (RED LED)
' Portd.2 - LCD Function RS
' Portd.3 - Motor 2 Control Line
' Portd.4 - LCD Function E
' Portd.5 - Motor 1 Control Line
' Portd.6 - Motor 1 Control Line
' Portd.7 - LCD Data DB7                      (GRN LED)
' ADC6   -  Battery Power Indicator
' ADC7   -  User Trim Pot on underside
Cursor = Off

Rw Alias Portb.0 : Rw = 0       ' Set to Zero to write to the LCD
Grn_led Alias Portd.7       ' Green User LED
Red_led Alias Portd.1       ' Red User LED

' ======= MOTOR 1 ===========
M1a Alias Portb.3       'Direction
M1b Alias Portd.3       'Go / Stop

' ======= MOTOR 2 ===========
M2a Alias Portd.6       'Direction
M2b Alias Portd.5       'Go / Stop

Lcd "GO"
Grn_led = 1
Red_led = 0

' Run Forward 1 second
M1a = 1
M2a = 1
M1b = 0
M2b = 0
Wait 1

' Stop
M1a = 0
M2a = 0
M1b = 0
M2b = 0
Wait 1

' Run Reverse 1 second
M1a = 0
M2a = 0
M1b = 1
M2b = 1
Wait 1

' Stop
M1a = 0
M2a = 0
M1b = 0
M2b = 0

Lcd "Done."
Grn_led = 0
Red_led = 1

' Waste some time

The odd thing is that the green LED works fine… but I just cannot seem to change the red LED no matter what I do. If I use the PRINT command to send serial data out… the red led flickers… so I don’t know what is going on.

I was able to use AVR Studio to read the original program and save the HEX file and load it back… But I have been looking all over the Pololu site… I can’t seem to find the source code for the 3pi. Do you have a link?? I’d like to view the C code to get an idea of what is going on in there… I have had limited C exposure… but I can write in Basic, Javascript, PHP, ASP… so I should grab the basic concept pretty fast if I can see the code. (If it is commented… even better.)


I still can’t get BASCOM to work with the Pololu programmer over here. On my computer, clicking “Identify chip” doesn’t do anything, and reading the flash memory instantly returns a bunch of 0x00’s, with no error message.

All of the source code that we supply for 3pi, including the demo program, is included with the library download:


Sorry that you couldn’t find that more easily - I’ve placed a link directly on the 3pi page so that it will be easier for others to find in the future.

In your program, I think that the red LED is usually on, and it is only blinking off when you transmit data on the serial port, since the BASCOM serial routine is keeping PD1 high at all other times. Is that what you saw? You’ll have to decide whether to use it as an LED that you can control or as a serial output.


Great… I’ll download that now.

As for the LED… I’m going to try a change that Mark sent me…

That would make sense… I put the $baud command in because I was eventually going to communicate with a PC… but I don’t need it at this time. That will likely fix the issue.

UPDATE: I removed the $baud command and it worked flawlessly.

I’m glad you got the LED working! Let me know if you have more problems, and I’ll try to help you out.

Actually… save me a bit of work… on the motor controllers I figured out what pins need to be set to make the motors go forward/reverse… for the PWM which pin is the PWM?

' ======= MOTOR 1 ===========
M1a Alias Portb.3       'Direction
M1b Alias Portd.3       'Go / Stop

' ======= MOTOR 2 ===========
M2a Alias Portd.6       'Direction
M2b Alias Portd.5       'Go / Stop

My guess is Portd.3 and portd.5 but honestly, I haven’t looked through the C code in enough detail yet. I’d like to tinker with the PWM later this week if time allows.

By the way, thanks for the assistance.

Some people have asked why I use BASCOM instead of C… after setting up AVR Studio I remember why. In C I needed to download the following…

  • AVR Studio
  • 3pi Files

Then I had to compile, set everything in the right directories… verify it worked with the demo program, then start learning the language.

For a total newbe… like some of the kids getting into robotics… there were too many places to fail. With BASCOM you download the program, load a sample file, and hit F7 to compile. Even with needing to use AVR Studio as a programmer… it had a much simpler setup.

I hear the Arduino setup is a single click install… I’ll need to evaluate that as well… but for now I think C is more of an advanced programming environment.


Your explanation of the motor pins was not quite right. Actually, the two AVR pins for each motor correspond directly to the two motor outputs, so that values of high/low will turn the motor one way, and values of low/high will turn the motor the other way. The “PWMA” and “PWMB” inputs on the motor driver chip are not connected to AVR pins; instead of using them, we leave one pin high and PWM the other to adjust the speed.

Take a look at the schematic in the quick-start sheet. We also have a detailed application note that explains how to use the motor drivers on the 3pi, LV-168, and Baby Orangutan B boards, including truth tables and sample code.

As for the difficulty of getting started with C on 3pi, I agree with you that it requires some advanced computer skills. However, downloading and installing three packages (not actually five as you implied) is pretty easy - the hard part is actually programming in C. We’d like it to be easier, and we’d be really happy if you posted some BASCOM example programs here! Does BASCOM provide a way for you to store library functions in separate files, or maybe even link to compiled code that could come from C? Having the basic functions (like PWM) taken care of is really important for beginners.

Arduino is easy to install, but users still have to install the Pololu libraries for the simplest possible experience, and it’s not much easier to write code within the Arduino environment, compared to just writing normal C. There are a lot of people who have Arduino experience, however, so we think that providing this option will make it easier for them to use the 3pi.

I am aware that you use the input pins for the chip and not the PWMA and PWMB pins… BASCOM does have some PWM functions… been awhile since I have used them… two of the AVR pins were programmed to do that function… I just couldn’t remember the actual hardware. (I’ll look in my archives… I programmed a tank with PWM once… I know I have my notes around here somewhere.)

Anyway, you can write a program in BASCOM then use an #include type of function to pull it in like a library. I write a section with pin definitions, then one for routines like “FORWARD”, “REVERSE”, etc.

The BASCOM equivalent is $include

$include "123.bas"

As for the PWM… here is the example from the manual…

'And the TIMER can be used in PWM mode
'You have the choice between 8,9 or 10 bit PWM mode
'Also you can specify if the counter must count UP or down after a match
'to the compare registers
'Note that there are two compare registers A and B

Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down , Prescale = 1

 'to set the PWM registers, just assign a value to the compare A and B registers

Compare1a = 100
Compare1b = 200

 'Or for better reading :

Pwm1a = 100
Pwm1b = 200


I just can’t remember which pin it was for the Mega168… I’ll dig out my Mega8 sample and compare the datasheets. I thought the output was OC1B and OC1A, but as I recall… I thought the software wasn’t working… then I put the O-Scope on each pin… and found that the PWM was coming out, just off a different pin than I thought.

The manual says…

So we have 4 registers in the 168… I guess I’ll just have to experiment and post the code when I figure it out.
Jerry :open_mouth:

You say that you are trying to “remember the actual hardware”, but I really don’t understand what other information you are trying to remember. Can you ask a direct question about it? You know which pins connect to the motor driver, and you know how these correspond to the four PWMs (PD5=OC0B, PD6=OC0A, PD3=OC2B, and PB3=OC2A). The application note says very clearly how to use Timer0 and Timer2 to PWM these four pins, including explicit settings for all of the registers involved, so I don’t know what more I could tell you.

Your example code is setting up the PWM on Timer1, which won’t work with the motor pins - is that what you’re confused about? Timer1’s PWM will definitely just go to OC1A and OC1B, so if your code isn’t doing that, there’s something wrong. Which pins did it seem to go to?


Just a follow-up on this… I was able to get the motors to operate properly with PWM.

These are the routines I came up with.
Define “Speed” as a word variable…

Dim Speed As Word 

Then call the Pwm_setup once. After that… just call the routines as you need them.

'Motor Routines
Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Config Timer2 = Pwm , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down

Pwm0a = Speed : Pwm0b = 0 : Pwm2a = Speed : Pwm2b = 0

Pwm0a = 0 : Pwm0b = 0 : Pwm2a = 0 : Pwm2b = 0

Pwm0a = 0 : Pwm0b = Speed : Pwm2a = 0 : Pwm2b = Speed

Pwm0a = 0 : Pwm0b = Speed : Pwm2a = Speed : Pwm2b = 0

Pwm0a = Speed : Pwm0b = 0 : Pwm2a = 0 : Pwm2b = Speed