Stop after x laps

Trying to refresh my C knowledge, but stumped. Would like to stop 3pi after a few laps, of Simple Line Follower program, instead of grabbing it and shutting down. Pretty rough on this $99 gem.

What would be best way to count laps? And the code to accomplish this?

Thanks, donde

Hello, donde.

The simplest way to accomplish this would be to use a timing-based approach where you figure out how long you want the 3pi to run and then program it to leave the line-following code loop when this time has passed. The Pololu AVR libraries give you a function called get_ms() that returns the number of milliseconds that have passed since the microcontroller was last reset/powered on, or since you last called time_reset().

Just before your robot begins line following, call time_reset() to reset the millisecond counter. Then in the line-following loop, you can insert code like the following:

if (get_ms() >= 60000)  // if 60 seconds have elapsed
  set_motors(0, 0);  // stop both motors
  while (1);  // loop here forever (i.e. until you reset the 3pi)

It’s up to you to figure out what number you should compare to the result of get_ms(). You can also do something fancier than going into an infinite loop. For example, you could restructure the code so that after enough time elapses, you jump back to the top of the program and are ready to follow the line again.

Another way to approach this problem is to in some way mark the course so the 3pi can track its laps using its line sensors. For example, you could put a piece of black electrical tape perpendicular to the course line. As the robot passes this tape, it will see black on all five of its sensors, which is your cue that it has crossed your marker. You can count the number of times this happens and program the robot to stop once the count reaches the number of laps you want your 3pi to do. You can use the 3pi library code for reading the line sensors to detect when all of the sensors read black.

Does this make sense?

- Ben

Hey Ben,

I was thinking of the 2nd way first. But, both approaches are quite helpful to get me going again. The Holiday shopping is taking my time! The 3pi is a great way learn C or re-learn it. And you guys, not giving away the complete answer, forces us to think. I hope I can stay with it. Thanks for this “brain food” super product. :smiley:

Oh, noticed the right top LED that I added glows very dimly just before the 3pi starts up. After that, it behaves OK. Maybe a leaky LED driver?


The right LED is actually on a line that is also used for LCD control. When writing to the LCD, you’ll notice quick blinking or a dimly lit right LED. This frees up one extra I/O port for use in other things, without causing any problems. So, don’t worry - there’s nothing leaking in your 3pi.

We’re happy you’re enjoying your 3pi! But even if we wanted to give away the answers, there are always more problems to solve. After you learn how to time the laps, for example, you might want to teach your 3pi to “learn the course” on its first lap so that it could get to the right side of the line when a right turn is coming up, etc. Good luck, and let us know how it goes!



Got stop routine going using the get_ms() function. The course is just 3 loops and a straight away, on 1 poster board. I7500 ms worked out OK for 3 laps and then 3pi stop fine. OK on the “dim” LED. It’s funny when my older Fujitsu 10.8" laptop CPU has hard things to do, the screen fades for a few seconds. I’ve tried the PID version of the Line follower, and it’s very smooth, if a bit slower.

I’m a ham operator. Thinking of having the 3pi send CW (code) tones and flash the green and red LED’s topside. Left LED would be for dots, and right would be for dashes. And of course, have the 3pi lapping around the course. Got idea while doing my morning fast walk. 36 degrees at 7 AM in SoCal. Any hints?

Thanks guys, donde

Hmm…For the code, do you happen to have a camera that can take long-exposure pictures? You could dim the lights and have 3pi flash a message in code to you as it zooms by. Also, if you can put together a function for beeping out morse code tones, post it here! It would be interesting to know if you could successfully use that as a kind of debugging output for when you can’t read the LCD.

Yeah, we got 3 inches of snow here in Las Vegas - amazing weather!


I’m thinking the added delays of flashing the LED’s with code or sounding code with the buzzer would not work, for the CPU has enough to do keeping the 3pi on track. I’ve been reading about play_check and play_automatic in Buzzer3. I suppose play_check would be best way. Is the CPU fast enough to accomplish these ideas? Each character could last about 300 ms. I would flash the LED first. L (dit dah dit dit) for left and R (dit dah dit) for right.

Years ago, pilots used radio ranging to help keep them on the glide slope. When too far left, they would hear A (dit dah), too far right, they would hear N (dah dit). When at the center of the glide slope, they would hear a constant tone. Since the characters last about the same time, this might work. Probably not use constant tone, but just light both LED’s

Regards, Don

Hi Don,
Around here, when we program our 3pi robots, we always have them play a tune, and it should not impact the performance of your line follower. If, however, you do notice glitches when playing tones, that should be one of the first things you try turning off. You should definitely be in PLAY_CHECK mode whenever you are reading your line sensors, since a delay of a a fraction of a microsecond would cause a bad reading.

A less processor-intensive approach would be to monitor the system clock with get_ms() and use the simpler playFrequency() command at the appropriate times to generate the beeps you want.

I didn’t know about that radio guidance system before! What did the pilots hear when they were perfectly centered?

Hi Paul,

To answer the last question, they heard a steady tone when centered on the glide path.
Today, the systems are much different, visual, and more accurate. I’m not a pilot, but it’s fun to read about the radio they used.

OK on play_check mode. Looking at the library under Orangutan buzzer, it’s a little unclear what the command structure would look like, especially with Orangutan as examples. I’m using C, so would it look like this?
play_from_program_space(melody); or
playFrequency(6000, 250, 7); or
:play("!L16 V8 cdefgab>cbagfedc");

Since I’m not very musical, is there a way to preview the sounds before compiling. Maybe in AVR Studio? But I would like to stay with Ubuntu.

Getting close to the holidays, so Happy Holidays ! :smiley:


What you want to do is something like:


  // this is your main loop
  play_check(); // call this whenever you can spare the time

The play_check() function basically enters the interrupt handler in a more controlled manner.

Unfortunately, I don’t have a way for you to preview the tunes. But you could make a short program containing just the music commands; it would take only a second or two to load it each time you are testing the melody.

Good luck! I have a feeling that your 3pi will be beeping A’s or N’s depending entirely on whether its turning left or right. How fast is it going right now?