Friday, May 13, 2011

Choosing a Microcontroller

Oooo, lookit all the cool toys!
In case it helps you, I wanted to share my experiences considering several microcontrollers as the brain of my Sparkfun AVC 2011 and 3rd place winning 2012 robot, Data Bus.

Each project is different with a unique set of goals. The key is to think about the goals and how well each option meets those goals. For example...

Goals

My primary goals were to save development time, and to support whatever level of computation required by the robot, and to provide interface flexibility in connecting myriad yet-to-be-chosen sensors. I wanted to keep costs reasonable. Sub $100 or ideally sub $50.

Options

I considered several options for the robot
  • Arduino-compatible: diy pcb, Arduino IDE; super-cheap!
  • An Arduino-flavored AVR XMEGA type thing
  • The Maple, ARM Cortex M3 from Leaf Labs; Arduino-like IDE
  • The mbed LPC1768, ARM Cortex M3 from NXP: online; cloud-based IDE
  • Blueboard LPC1768-H, another Cortex M3; cheap!
  • Parallax Propeller, like my eeZee Propeller, multicore deterministic
  • LPCXpresso, LPC1769, Cortex M3, cheap! (considered in 2012)
Other options I didn't consider (or which weren't available)
Library support

Having a platform with good library support was crucial to saving time. I didn't want to have to develop a lot of libraries.

Best: Arduino is a good choice as it has such a massive following. Most of the common sensors have something written out there somewhere.

Great: Initially the mbed seemed like it would have excellent library support. In fact I ended up writing and publishing most of the drivers myself, but I was easily able to adapt code from Arduino in a couple instances, and use a few existing libraries in other cases. It worked out ok. Device support is better since I originally wrote this.

Good: The Propeller generally has good community support with libraries. I would've had to write many myself and porting code would've been harder if I used Spin. But prop-gcc has become quite popular in the last year or two. Despite the 8 cogs and 80MHz clock speed the reality of hub memory and 4 clock cycles per instruction

Ok: Leaf Labs was an unknown but it was possible that much of the Arduino library code had been or could be easily ported. My latest impression from a year or two ago is that the Arduino library implementation isn't all that optimal or complete and hadn't seen much activity in awhile.

Not sure: The Blueboard. With an LPC1768 it should be binary compatible with most of the mbed SDK (recently open sourced). Otherwise, you'd have to code nearly bare metal, using CMSIS at worst or one of the (few?) RTOS HALs out there.

Not sure: LPCXpresso is supposedly mbed compatible otherwise it's CMSIS or maybe you can find a HAL; it's the same family as LPC1768 so theoretically it should work.

IDE

The IDE has an impact on speed of development.

Good: The Arduino IDE makes for writing small code quickly. Very complex code can be done... it can get a little messy. Ability to do version control is nice and provides a little freedom for moving the development environment from system to system. (I use Subversion with Google Code hosting).

Good: The mbed IDE is more like a real IDE, or a good editor but with version control and the really nice integrated library repository. The big downside with cloud-based of course is when you're at the AVC and they have no internet connectivity then what? Well, offline compile is possible, now, with a variety of tools/IDEs. You may not see the performance of the online compiler.

Good: Propeller Tool is well-suited to SPIN and PASM and generally is set up nicely. I've used it quite a bit, I'm happy with it. It's Windows only. Brad's Spin Tool is an option. I've not played with the Simple IDE yet.

Not sure: Code Red for LPCXpresso now supports C and C++ and it is based on Eclipse which I rather like.

Not sure: Plain old Eclipse with plugins for ARM is one way to go. And maybe open source debugging tools. But that's a mountain of work I've not yet climbed.

Peripheral support

Best: The Cortex M3 has 4 serial ports, USB, CAN, multiple I2C, ethernet, and multiple SPI ports. Clearly the winner since I had I2C, two serial, and two SPI devices. I could've plugged the robot into a wireless AP and controlled it via web over WiFi had I wanted to.

Good: The XMEGA has more peripherals than Arduino so it might've been viable.

Meh: The Arduino Duemillanove, Uno, etc., based on ATmega328P are in a different (much lower) class, with only one of each peripheral. The Arduino Mega, based ATmega2560, would've provided more peripherals.

Good: With Propeller, all the peripherals (except timers/pwm/counters) are done in software. On the one hand, you can have a lot of peripherals and just what you need. On the other hand they will probably perform slower than hardware-- I2C even in PASM has delays due to hub synchornization-- and I'm finding it difficult to track down good peripheral drivers, sometimes. I had to write my own I2C master object because I couldn't find a decent one. Parallax has an online repository but it is lacking compared to mbed.org, particular Doxygen-generated documentation for object APIs.

Processing power

Best: LPCXpresso runs 120MHz and nearly 1 instruction/cycle, lots of RAM and flash. The program size is limited by Code Red (free version) but even then it's quite a bit.

Best: mbed runs 96MHz at 1 instruction/cycle which was plenty and also lots of RAM and flash with no code limits that I know of (but you might double-check). Ran software floating point with ease. Processor was underutilized even doing lots of calculations at 100Hz for my rover.

Ok: Propeller has 32K but it's hub ram and incurs major delays to read/write, but it's the only way for a PASM routine to communicate with Spin objects and Spin is too slow to do device drivers, usually. Each cog has 2K ram which is nice. The 80MHz runs 4 clocks / instruction so that's effectively about 20MIPS times 8 cogs but then you have the 7+ clock cycles for hub synchronization which slows things down.

Worst: Arduino with ATmega328P is only 20MHz (around 20MIPS) with only 32k flash and 2k RAM.  You'll have to be careful with floating point and such, but... you can still do more than you think.

Community support

The ability to find answers and solutions will dramatically speed development efforts versus having to invent the wheel all on your own.

Great: Arduino lots of community, forums, example code.

Best: mbed has quite a big community now too, with forums, cookbooks, and a code repository unlike Arduino

Ok: Propeller has a big community and forums, and while it has a code repository but I find it very difficult to search and the documentation is consistently so bad you invariably have to download and look at the source to have any idea whether the object will work for your needs.

Bad: LPCXpresso has a forum. I'm still struggling to figure out how to do anything interesting. Not impressed so far.

Summary

In short, of all the choices, the Cortex M3-based solutions were easy choices due to the massive number of peripherals and the significant computing power. The cost and completeness of the mbed solution made it my clear winner in the end. I migrated to it around January, about four months before the big competition in 2011. Since then it is one of my top tools alongside Arduino-ish stuff. I found it easy to manage 20k lines of source that drove Data Bus and I to a 3rd place in 2012 so overall, I'm very pleased and things keep getting better. With an open SDK, offline compile, and more MCUs supported every time I look, it seems like a great option.

If you think others might find this helpful, take a second and share? Thanks!

7 comments:

  1. You are right
    But in Avr we have CodeVision that it has wizard for using every Peripherals in it.But in Arm I think we don't have something like this that have wizard to manage our Peripherals and program it easily.
    Mbed makes simple the programing for LPC1768 But if we want to change our ARM Microcontroller to better one I don't think there is an IDE something like Mbed

    ReplyDelete
  2. I used the arduino mega for the competition and didn't have any issue with memory (I used ~30% of its capacity) or lack of pins.

    Additionally, I really dislike the arduino IDE, so I used notepad++ instead. I set the arduino IDE to "use external editor" in the preferences menu. I did all my coding in notepad++, saved, and then compiled and uploaded with the arduino IDE. That method works very well with large code.

    - Team Roadrunner

    ReplyDelete
  3. Great article.

    You make mbed sound great, but I am concerned about cloud computing; my internet connection still goes down too frequently. Is there a way to work offline?

    - Ted (Team Daisy Rover)

    ReplyDelete
  4. Thanks, everyone, for the great comments!

    @Ted: You could do offline compiling with an ARM toolchain and it is possible to download the various mbed libraries so it may be possible to gain all the advantages of mbed while compiling offline.

    @alireza: did not know about CodeVision, that sounds fantastic!

    ReplyDelete
  5. Actually, I have not found a way to use the mbed Compiler without owning an mbed board. I've bought some LPCXpresso boards and wanted to used mbed libraries on it. It seems to be possible, but lacking the access to the mbed compiler is not really the best start I could have. Thanks,

    ReplyDelete
  6. Well... I was able to compile against the mbed library using the Code Sourcery arm-gcc toolchain. Didn't need the mbed compiler. Of course if you can't get the mbed library to start with then yeah that's a problem. Maybe start here? http://code.google.com/p/mbed-lib/

    ReplyDelete
  7. Thanks! Indeed, there is a zip file on the site you provided which is a good start. I was afraid such zip would not be available. Thanks for pointing it out.

    ReplyDelete