Channels ▼

Al Williams

Dr. Dobb's Bloggers

Humans Are Still Analog

May 12, 2014

The last few weeks I've been working on an ARM-based development system that doesn't break the bank. If you read last time, you may have noticed that I mentioned the LPC-Link debugger. However, if you are using the Mbed online compiler, you may have wondered how you would actually debug using the online IDE.

The answer is, you can't. You need some local IDE. I used LPCXpresso, which is a free download for Linux, Mac, and Windows. The problem is the Mbed libraries expect to compile on the Mbed compiler. The code is open source and it is full of #if statements to account for other supported compilers, but at least for the LPC1114, I didn't get a clean compile right out of the box.

In theory — and this may work one day — you should be able to tell the Mbed IDE to export your project to a different IDE. That is supposed to give you a project with all the right options and dependencies. However, the LPC1114 didn't support LPCXpresso export at the time I tried it.

I wound up exporting the project as a ZIP file which worked, but it didn't set up a project with all the defines, libraries, start up files, linker files, and the other ancillary things needed to get a successful compile. Of course, you can always abandon the Mbed libraries, but they are very handy compared to using the CMSIS setup the LPCXpresso examples use.

Lucky for you, I did all the work of dragging through compile and linker errors and fixing up the Mbed library to work with LPCXpresso. You can find the result along with a small example program in the online listings. You can use the LPCXpresso Import Projects command (from the Quickstart Panel) to load both projects. You could skip the example, but you need the Mbed project if you want to write your own programs or run the example.

Speaking of the QuickStart Panel, I have been frustrated before with LPCXpresso because it does rely on the panel heavily (see the figure below). Many of the panel functions have similar Eclipse menus (for example, the import project) but they don't work the same! You really want to use the functions off the QuickStart Panel instead of the native Eclipse equivalents.

If you don't care about debugging, then you can just get the example and plug it into Mbed (or clone my copy). The code is almost exactly the same either way (I did have to add a reference to mbed_main for the LPCXpresso copy).

The example drives a common radio control servo on pin 1 of the IC. The one I had needed 5V, so I connected the positive and ground wires to a 5V supply and then made sure the 5V supply had a ground in common with the LPC1114 board (which is a 3.3V system). The control input to the servo connected to pin 1 of the CPU chip.

My goal was to make a meter that could show activity on the PC (after all, reading numbers of a screen is a digital concept and humans are still analog). I'll take a rainy day project in the future to put a needle on the servo and make a cardboard backing that shows 0% to 100%. A small piece of software sends the percentage to the "meter" so the percentage could be anything, really.

If you haven't used an analog servo before, the idea is simple. You periodically send it a pulse. It generates a matching pulse internally that depends on the position of the motor shaft. If your pulse is longer than the internal pulse, the motor will move in one direction. If your pulse is shorter, the motor moves in the other direction. The amount of motion depends on the difference between the pulses, and eventually the shaft will stop at the commanded position.

Most servos have mechanical stops so they don't go all the way around. That's perfect for a meter. I measured and found that my servo would go all the way to the ends with a 1 millisecond pulse and a 2.6 millisecond pulse. Anything between would move the shaft to some point between the extremes.

The software could do some timing loop, or manage a timer interrupt. But with the Mbed libraries it is much simpler. The library provides a PWM (pulse width modulation) object. Normally, you use it to send pulses of a certain duty cycle and period. For example, a 20 millisecond period pulse with a 10% duty cycle would be high for 2 milliseconds and low for 18 milliseconds.

The object will compute that for you, if you want. It also provides methods that let you set the timing of the pulse automatically. That's what I wanted. The serial port is also nicely encapsulated. The code could hardly be simpler:

#ifdef __USE_CMSIS    // only needed for LPCXpresso
#include "LPC11xx.h"
#include "mbed.h"

PwmOut out0(P0_8);
Serial host(USBTX, USBRX);
// I didn't include the flash access adjust 
// for the online version since it isn't necessary
extern "C" void flash_access_time(uint32_t frequency);
// Needed for LPCXpresso
extern "C" void mbed_main(void);

int main(void)

    	unsigned int n=200;
    	host.scanf("%d",&n);  // read from PC
    	if (n>100) continue;  // make sure in range 0-100
    	n=((unsigned int) (1600.0*n/100.0));  // get a number from 0 to 1600
    	n=1600-n;  // reverse motion direction  so now it is 1600 to 0
// add 1000 so that total number is 1000 to 2600 (or 1mS to 2.6mS)
    	out0.pulsewidth_us(n+1000);      }

Using scanf is wasteful, but it sure makes the program simple! Naturally, the position of the servo was backwards, so 2.6 milliseconds was 0% and 1 millisecond was 100%. That's an easy fix in software, of course.

The first calculation of n essentially computes a percentage of 1600. Notice the ARM can easily handle floating-point math, which is convenient. The second calculation flips the result so that 100% becomes 0. Finally, the program adds 1000 to n before calling pulsewidth_us. This results in 1000 to 2600 microseconds (which is 1 to 2.6 milliseconds).

If you are using LPCXpresso with a debugging probe you can single step, break point, and examine the program executing as you'd expect with any modern debugger. If you aren't, you can still use LPCXpresso and just program using the bootloader like you would if you were using the online IDE. The two objects are just a few of the devices supported by Mbed. If you browse the web site, you'll see objects ranging from networking, cameras, range finders, and plenty more.

I didn't spend much time on the script to send the serial data indicating CPU load, so it probably has room for improvement. I used mpstat (you may have to install it from your repository) to get the one second average and let Awk parse the line, do the math, and send the percentage over the serial port. Here's the code:

#!/usr/bin/awk -f

BEGIN      {
            if ( SPORT=="")  SPORT="/dev/ttyUSB0";
            PGM="mpstat -u 1 1";
            system("stty -F" SPORT " 57600 clocal -crtscts cs8 -cstopb -parenb -ixon")
            while (1) {
                do {
                    PGM | getline
                } while ($3!="all");
                print v >SPORT
                print "Debug: " $0
                print "Debug: " v
                system("trap 'exit 1' 2; sleep 1");

For debugging, you might just as well use a serial terminal and enter 0 to 100 at 57600 baud and no handshaking. The serial port setup is the purpose of the call to sty, by the way.

I'll probably come back to the LPC1114 and Mbed at a future date. Hopefully by then the project export will work (I never did get the MBed RTOS to compile under LPCXpresso). Meanwhile, you should be able to work through Mbed and do quite a few powerful 32-bit projects for a very small investment.

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.