Go Down

Topic: Pololu Orangutan Robot Controllers (Read 2967 times) previous topic - next topic

Hello!

I would like to introduce a series of boards that might prove useful to those of you in the Arduino community.  Pololu's line of ATmega168-based Orangutan robot controllers have a great deal of overlap with Arduinos and can be programmed via ICSP using the current Arduino-0011 IDE.  I've just put up an app note and a set of Arduino libraries that allow you to easily interface with all of the onboard hardware.  The app note contains the documentation for these libraries and explains in detail how to make the Orangutan robot controllers compatible with the Arduino environment:

http://www.pololu.com/docs/0J17

Here's a brief overview of the two Orangutans:

[size=16]Orangutan LV-168[/size]


The Orangutan LV-168 ties an ATmega168 microcontroller running off of a 20 MHz resonator to a removable 8x2 LCD with contrast control, a buzzer, three user push buttons, two user LEDs, a user trimmer potentiometer optionally jumpered to analog input 7, a temperature sensor optionally jumpered to analog input 6, and two discrete, low-voltage H-bridges capable of independently driving two brushed DC motors (2 A continuous per channel).  The unit contains a step-up voltage regulator that allows it to run at full speed off of 2 to 5 V, meaning you can power the device with three NiMH cells or a single lithium-based cell.  Digital pins 0 and 1, and analog inputs 0 - 5 are brought out to 0.1" female headers to allow for easy connecting of sensors and external hardware.  Removing the LCD provides access to seven more digital I/O pins.
Price: $59.95 USD

[size=16]Baby Orangutan B-168[/size]


The Baby Orangutan B-168 is code compatible with the LV-168 because the common hardware has the same AVR pin connections.  By removing the LCD, buzzer, and push buttons, the Baby Orangutan fits an ATmega168 microcontroller, dual H-bridge, user trimmer potentiometer, user LED, power LED, 20 MHz resonator, and reverse battery protection into a tiny 24-pin DIP package, and a low-dropout voltage regulator allows it to operate from 5 - 13.5 V.  The Baby Orangutan B can serve as the brains of a small robot, or as an auxiliary controller on a larger robot.  It is the same size as the Arduino Mini, but it offers many more features than the Mini and operates over a much larger voltage range.
Price: $29.95 USD ($24.95 USD for the version with the ATmega48 microcontroller)


- Ben

mellis

Very comprehensive documentation!  Good to see more uses for the Arduino environment.

The buzzer library looks very cool, we've wanted good sound generation for a while, so I may try to incorporate it into the standard distribution.  Also there's going to be an LCD library in Arduino 0012: http://svn.berlios.de/wsvn/arduino/trunk/hardware/libraries/LiquidCrystal/, not sure if it would make sense for you to switch over to that when it comes out.  Would you need any changes to it?

I think the buzzer library is the most complicated of the libraries from an implementation standpoint, but it's also the one I'm most proud of.  We just had a local robot competition today, and a few of us at Pololu made entries out of a new robot kit we are developing that is essentially a higher-voltage version of the Orangutan LV-168 layed out as a PCB chassis.  A few of us made ours using the Arduino IDE and the Orangutan Arduino libraries (it worked great and I was very happy with the experience), and a few of us used AVR Studio with C version of the same libraries.  The allure of the new buzzer library was so strong that one person had his robot playing Bach's Fugue as it did its line-following and maze-solving, and another had his line-follower speed synchronized to a Hungarian Rhapsody.

The buzzer library is currently hard-coded for 20 MHz operation, but it wouldn't be too hard to generalize it.  Also, in its current implementation it is driven by the timer1 overflow interrupt (this interrupt is used to time note durations, and to start the next note when the buzzer is operating in automatic play mode), which happens at the frequency of the note being played will can lead to a lot of interrupts if you are playing high-frequency notes.  This approach was chosen so that buzzer operation would rely solely on timer1, but if you are serious about making this a standard library, it might make more sense to drive buzzer operation with the timer0 overflow interupt used for millis().

As far as the LCD library for Arduino 0012, it seems like a good foundation.  Have you considered using the busy flag to control LCD timing rather than using fixed delays?  It's not that complicated (you can see the Orangutan LCD library for an example), and it allows the LCD to potentially operate much faster than the HD44780 spec.  It would also make your LCD code independent of clock speed (right now it might not work on a 20 MHz mega168, for example, because I believe delayMicroseconds() doesn't correctly account for clock speed?).

Additionally, have you considered making stdio.h's printf function work for LCD control?  This could take care of things like automatically wrapping text and automatically scrolling the display lines to allow for new text, and it would make it easy for people to print out integers and floats.

Lastly, I notice you only implement delays for LCD functions like clear() and home().  The HD7780 spec requires 37 us delays for most of the other LCD control instructions.  Are you relying on the (relatively) slow execution of digitalWrite() to ensure you more than exceed this delay?  It might be nice to have a slightly faster version of send() just so that lcd.print() functions aren't as potentially disruptive to the timing of programs, but this isn't at all crucial.

For the 0012 distribution, maybe I would create an Orangutan version of the LCD library that inherits from/wraps around yours, automatically sets the pin assignments for what they are on the Orangutan LV-168, and provides some useful print() methods (like the ones it does currently).


- Ben

mellis

Having the buzzer library on timer 1 seems fine, at least as a first pass.  We can just tell people that it will interfere with two of the PWM outputs.  The Servo library will do the same thing.  If you're bored and wanted to generalize it to any CPU speed (or at least 16 MHz and possibly 8 MHz), that would be awesome.  Otherwise, I'll give it a shot.  We need more people playing Bach with Arduino!

Using the busy flag for the LCD is an interesting idea.  I think the implementors of the original library avoided it because you can save a pin (I think) by tying the read / write flag to ground (or 5v?) rather than controlling it explicitly.  I'd definitely like the library (and the rest of the core) to work at 20 MHz.  Actually, if you find things in the Arduino core that don't work at 20 MHz, please let me know, as I'd like to support for that CPU speed.  Patches are even better of course.  For the moment, though, I'm not so concerned about the speed of the library, since we can only read text so fast anyway.  But if it's a problem for people, we can certainly look into supporting the busy flag.

When I tried the code w/ my LCD, it worked without those delays (probably because, as you suggest, digitalWrite(), etc. are so slow), but it's probably still best to add them.  

We've been avoiding printf() and co. because the syntax is relatively complicated compared to the rest of the Arduino API.  Also, they can take up significant program space (1.5 KB or so, if I remember right, which was a lot when we were using the ATmega8).  

mem

Quote
Using the busy flag for the LCD is an interesting idea.  I think the implementors of the original library avoided it because you can save a pin (I think) by tying the read / write flag to ground (or 5v?) rather than controlling it explicitly.  I'd definitely like the library (and the rest of the core) to work at 20 MHz.  Actually, if you find things in the Arduino core that don't work at 20 MHz, please let me know, as I'd like to support for that CPU speed.  Patches are even better of course.  For the moment, though, I'm not so concerned about the speed of the library, since we can only read text so fast anyway.  But if it's a problem for people, we can certainly look into supporting the busy flag.


LCD library performance can be an issue if the delays interfere with other code that is time critical. One of my first sketches was a servo tester that needed to do some calculations and update an lCD display within a 20ms servo frame. Using the LCD4bit code consumed way more time than was available, changing to a library that used the busy flag rather than a fixed delay and direct port I/O rather than digitalRead was 300% faster, plenty fast  enough for my app.
Perhaps it not an issue for the typical Arduino app, but for me the performance gain through monitoring the busy flag more than justified the loss of the pin.


mem

Quote
 This approach was chosen so that buzzer operation would rely solely on timer1, but if you are serious about making this a standard library, it might make more sense to drive buzzer operation with the timer0 overflow interupt used for millis().
- Ben


Ben, I vote for sound using one of the 8 bit timers if you can. Many of my Arduino applications seem to need the unique capabilities of timer1, particularly input capture.

I completely agree with your LCD comments.


#6
Jun 03, 2008, 07:47 pm Last Edit: Jun 03, 2008, 07:47 pm by bens Reason: 1
I wish I could put the sound on an 8-bit timer, and maybe there's a way, but unfortunately it becomes difficult to get the kind of PWM resolution you need for quality notes when your timer only has 8-bit resolution.

Right now, to get 10 kHz - 400 Hz on a 20 MHz processor, I use timer1 running at full speed (20 MHz) with it set to overflow from 2000 - 50000.  To get 400 Hz to 40 Hz, I use timer1 running at one-eighth speed (2.5 MHz) with it set to overflow from 6250 - 62500.  Using 16-bit resolution and these two timer speeds (depending on the range the frequency falls into) means I can get fairly close to any frequency I want.  If I tried to duplicate this with an 8-bit timer, I would have to use a much slower timer clock, which would mean much larger gaps between achievable frequencies.

If I were to use timer2, which has the most flexibility when it comes to clock prescalers, I could achieve the following:

prescaler 32, 625 kHz timer, 10 kHz - 2.5 kHz using overflow counts 62 - 250
prescaler 128, 156 kHz timer, 2.5 kHz - 625 Hz using overflow counts 62 - 250
prescaler 1024, 19.5 kHz timer, 625 Hz - 78 Hz using overflow counts 31 - 250

I'm not sure how that would sound, but it might be ok.  I can put it on my to-do list of potential improvements to make.


- Ben

Quote
If you're bored and wanted to generalize it to any CPU speed (or at least 16 MHz and possibly 8 MHz), that would be awesome.  Otherwise, I'll give it a shot.  We need more people playing Bach with Arduino!

I'll look into generalizing the buzzer code so that it works at different CPU frequencies.  At this point I'm not sure how much added complexity it will take to accomodate both 20 MHz and 8 MHz, but hopefully it's not too bad.

I'm also in the middle of making another improvement to the buzzer library that will let you play notes directly from flash rather than from RAM.  One thing we noticed during testing was that with only 1k of RAM, it becomes very easy to take up most of it with a fugue, which can lead to stack issues.  Since the melody is already in flash, it seems like a waste to have it also taking up RAM space, which is much more limited.

Quote
For the moment, though, I'm not so concerned about the speed of the library, since we can only read text so fast anyway.  But if it's a problem for people, we can certainly look into supporting the busy flag.

For me the speed issue doesn't really have to do with how quickly you can display something for reading but rather how intrusive an LCD print call is on the rest of your program, as mem has said.  A lot of the time I find that I want to use the LCD for feedback, but I know that using it will change the behavior of the very thing I'm trying to get feedback on just by the delays it will introduce into the program.  This is especially true if I'm trying to get feedback on some time-critical or time-sensitive application.  Minimizing the time taken by the LCD code just means there is less chance of it negatively impacting such applications, and it increases the number of places where I would feel comfortable inserting LCD routines for feedback or entertainment purposes.

Quote
We've been avoiding printf() and co. because the syntax is relatively complicated compared to the rest of the Arduino API.  Also, they can take up significant program space (1.5 KB or so, if I remember right, which was a lot when we were using the ATmega8).

Yeah, it can be pretty big, but I think it will only take up that kind of space if people actually reference printf in their programs.  The code to make the LCD compatible with printf I think ends up being much smaller.  At any rate, I just thought it might be worth considering if you hadn't already.

Also, thank you very much for taking the time to look through these libraries and give me your feedback!

- Ben

#8
Jun 04, 2008, 08:24 pm Last Edit: Jun 04, 2008, 08:48 pm by bens Reason: 1
Quote
We just had a local robot competition today, and a few of us at Pololu made entries out of a new robot kit we are developing that is essentially a higher-voltage version of the Orangutan LV-168 layed out as a PCB chassis.  A few of us made ours using the Arduino IDE and the Orangutan Arduino libraries (it worked great and I was very happy with the experience), and a few of us used AVR Studio with C version of the same libraries.  The allure of the new buzzer library was so strong that one person had his robot playing Bach's Fugue as it did its line-following and maze-solving, and another had his line-follower speed synchronized to a Hungarian Rhapsody.


Extreme line following: six robots enter, one robot leaves, kind of.  This is an unedited video of an unofficial event at the local robotics competition we held this past weekend, so it's rather long, but it has some interesting points.  The six participants are using the same Pololu 3pi robot, but all of the robots were programmed independently by different people.  Most of us used the Orangutan libraries linked at the top of this thread, and several of us did the programming using the Arduino IDE.  The robots are following the line at just under a meter per second.  The eventual "winner" is playing a Hungarian rhapsody while the third place finisher is playing one of Bach's fugues (mine was the one that finished second and took out "Johann").

I think next time I'm going to add a sharp sensor to the back of my robot so that it can slam on full reverse and take out the people behind me.


- Ben

Osamu_Iwasaki

Hello ben,

That's great news for me and japanese users.
I am MecahRoboShop owner and operating manager in japan.
I go straight to introduce this nice hack on my blog page.
Thank you!

best,

#10
Jun 06, 2008, 07:36 am Last Edit: Jun 06, 2008, 07:36 am by bens Reason: 1
We have now gone through and thoroughly tested all of the library methods.  As a result, we ended up fixing several minor bugs and making a number of small improvements.  We also made two more substantial improvements worth mentioning:

1) To the OrangutanLCD library we added support for creating custom characters using the OrangutanLCD::loadCustomCharacter() method.  The syntax for using it would be:

#include <avr/pgmspace.h>
const char happyFace[] PROGMEM =
{
 0b00000,  // the 5 bits that make up the top row of the 5x8 character  
 0b01010,  
 0b01010,  
 0b01010,  
 0b00000,  
 0b10001,  
 0b01110,  
 0b00000
};

void setup()
{
 OrangutanLCD::loadCustomCharacter(happyFace, 3);
 OrangutanLCD::clear();
 OrangutanLCD::print((char)3);  // print our custom char to the display
}

The following picture shows my line-following robot's LCD, which uses custom bar-graph characters to indicate in real time the signal strength of its five line (reflectance) sensors and uses a custom smiley-face character to keep my spirits high.




2) To the OrangutanBuzzer library we have added the ability to play a melody directly out of program memory.  Since the melody is already in flash to begin with, it's a huge waste of RAM space to have to first copy it to RAM before you can play it.  The new method is OrangutanBuzzer::playFromProgramSpace(), and it takes as an argument a pointer to a character array in program memory.  The following picture shows a piezo buzzer playing a melody from program memory.




Lastly, the guide to using these libraries now shows their associated example sketches so you can get a feel for how to use these libraries without first having to download and install them.


- Ben

Oracle

#11
Jun 06, 2008, 09:57 pm Last Edit: Jun 06, 2008, 10:00 pm by Oracle Reason: 1
Quote
The following picture shows a piezo buzzer playing a melody from program memory.


I'm impressed how vibrant those notes look ;)

You've done a fantastic job with this.  When I made my first thread here I never dreamed the company would take so much interest you'd make up all these libraries.

When I first came across the Orangutan, I thought it was cute but, as a pic user, it didn't seem worth getting into AVRs over.  Now it seems like an absolutely amazing platform for general embedded programing and robotics.

I really want one of these.  Any news on when your new robot platform will be out?  

Thanks for the kind words!  Our 3pi robots don't have a specific target release date yet, but we expect they will probably be out in July.  There should be a page up with more information about them soon.

The robot will be programmable via the Arduino IDE using the same procedure as our Orangutans, and all of the Orangutan Arduino libraries will work on it (we'll also be creating an Arduino library specifically for the 3pi).

- Ben

I had a request to add a stepper motor library for the Orangutans, but first I decided to test them with the Arduino Stepper library and was able to control a bipoloar (and therefore most unipolar) stepper motor using its four motor outputs.  This makes the Orangutans useful if you have a project requiring either variable speed control of two bidirectional DC motors or a single stepper motor.

- Ben

creatrope

hi Ben,

Is there reason to believe that these arduino libraries will work for the original Orangutan? If not, are you planning to support it?
It is not specifically mentioned.

Thanks, Harry

Go Up