Arduino loop timings

The advent of easy-to-use development ecosystems like Arduino have made a lot of embedded design tasks, such as obtaining GPS positions or controlling LCD displays or servo motors, significantly easier. Tasks which would take many hours to implement in assembly (a square root function for distance calculations, for example) are easily implemented in a single line of C or C++ code.

Often, though, there is a performance penalty associated with blindly using C or C++ code and making calls to library functions. If these functions are not used as intended, a significant amount of processor time can be wasted in unnecessary housekeeping.

While investigating the possibility of migrating our EET401 Microcontrollers course to the Arduino platform, one of the professors with whom I work ran some quick tests on an Arduino Uno, to test its clock-cycle efficiency. The results he got were startling, and warranted further investigation. Here is a recreation of these experiments, along with an brief explanation of what is going on.

The Arduino development environment comes with the basic example code to blink a LED:

void setup() {
pinMode(13, OUTPUT);
}

void loop() {
digitalWrite(13, HIGH);   // set the LED on
delay(1000);                     // wait for a second
digitalWrite(13, LOW);    // set the LED off
delay(1000);                     // wait for a second
}

This results in the LED (connected to Pin 13 on the Arduino Uno) blinking on and off at a rate of right about half a Hertz (one second on, one second off). The code is straightforward and easy to understand — and for an application like this, performance isn’t an issue.

Here’s the same sketch, with the delays removed. Intuitively, this should turn the pins on and off as fast as possible, since the loop appears to be doing nothing else.

void setup() {
pinMode(13, OUTPUT);
}

void loop() {
digitalWrite(13, HIGH);   // set the LED on
digitalWrite(13, LOW);    // set the LED off
}

Intuition can sometimes be deceiving, though. This code results in a square wave of only about 121kHz. Since the AVR microcontroller on the Arduino runs at a speed of 16MHz, this represents about 133 system clocks per cycle, just to turn one bit on and off. What’s going on?

Only 121kHz, running on a 16MHz system clock? (Click for larger.)

As it turns out, the calls to digitalwrite() are responsible for much of the delay. This routine is actually fairly efficient at what it is intended to do, but is far too general to be good at high-speed operations like this. It accepts a variable input, chooses which pin to change, then looks up the correct memory address and makes the change. All of this is accomplished in about twenty or so clock cycles, which isn’t bad when you think about it.

Such fancy options aren’t necessary when going for pure speed, though, so in this case there are better options. Re-writing the program to replace the calls to digitalWrite() with Boolean functions that write directly to the output port improves the frequency to 1.14 MHz. This is nearly a 10x improvement — but the short 14% duty cycle implies that there is still quite a bit of optimization that could be done in the loop itself.

After replacing DigitalWrite() with direct writes: 1.139MHz. (Click for larger)

Using a while(1) loop to surround the port-on and port-off statements eliminates most of the remaining delay, improving the frequency to 2.66MHz, with a final duty cycle of ~33.5%. 2.66MHz represents 1/6 of the input clock frequency, so apparently each operation (bit-on, bit-off, and loop) takes two clock cycles. This is probably optimal, and is better than would be possible in PIC assembly at 16MHz (four clock cycles would be needed for each bit operation, and eight for the jump.)

Adding an explicit loop gets us 1/3 duty cycle @ 2.66MHz. (Click for larger.)

Here is the final code used to get the 2.66MHz signal shown above:

void setup() {
pinMode(13, OUTPUT);
}

void loop() {
while(1){
PORTB |= 0x20;   // set the LED on
PORTB &= ~0x20;    // set the LED off
}
}

In conclusion, compiled C code can indeed be as efficient as handwritten assembly code — but it’s important to know the overhead associated with calls to library functions. The Arduino environment was built for ease of use, not lightning speed. Considering everything that functions like digitalWrite() do, though — addressing pins based on a variable, setting PWM states correctly etc — the efficiency of these functions is actually pretty good. It’s a question of using the right tool for the job.

 

Posted in Arduino, C, Coding, Digital | Tagged , , , , , , | Leave a comment

Symantec “LU1803” fix

Since the computers in the PLC lab at work support a rather old set of Allen-Bradley PLCs via an old 1747-PIC interface, they are limited to running Windows XP Service Pack 2. This solution works well enough, but is definitely showing its age. Supporting legacy installations like this sometimes require a bit of research when mysterious error messages show up.

Recently, while updating the Symantec anti-virus software, I encountered a “LU1803: LiveUpdate failed while getting your updates” error. Since a 2006 virus database is of very little use in late 2011 (and being limited to running XP/SP2 rules out running MS Security Essentials as I usually recommend), something had to be done.

As it turns out, there’s a fix — follow this link (which requires Internet Explorer; sorry) and run the auto-fix tools provided by Symantec.  Kod feci. Arne Saknussemm.

Share and enjoy!

Posted in System Administration | Tagged , , , , , | Leave a comment

Cabbage Chunkin’, Skyrim style!

One of the best parts of TES V: Skyrim is how “open” the world is. There are the usual quests and adventures that you would expect, but there are many other ways to simply wander around and explore the world that Bethesda has created. In-game physics continues to improve, as well, allowing all kinds of interesting experiments and in-world “hobbies” for your characters to pursue.

As it is autumn in the northern hemisphere, I decided to see if a Skyrim version of the annual “Punkin’ Chunkin‘” contest would be feasible. I was disappointed to find that apparently pumpkins aren’t present in Skyrim, even though they were in TES IV: Oblivion. (Anyone else remember making “pumpermelon” health potions?)

However, cabbages do exist in Skyrim, and such common foods are quite plentiful (especially if you channel your inner Sheogorath and make it rain cabbages. Or cheese.) Since cabbages, like nearly everything else in the game, are physics-enabled, they react to environmental forces, including gravity, momentum, collisions — and the occasional otherworldly FUS RO DAH.

So without further ado, here is my Altmer mage diligently laying the foundation for Skyrim’s own Punkin’ Cabbage Chunkin’ contest…

Posted in Games | Tagged , , | Leave a comment

Lawn Mower Overclocking

The most exciting phrase to hear in science, the one that heralds new discoveries, is not “Eureka” but “That’s funny…”
—Isaac Asimov (1920–1992)

Perhaps twenty-five years ago, my parents owned an Ariens riding lawnmower. This was a basic, no-frills model, but it ran reliably and got the job done. Being the teenage son, reasonably mechanically-inclined, underpaid, and somewhat expendable, I got lawn-mowing duty. (Actually, my Dad volunteered to do the trim work with the push mower, so even back then, I recognized I got the better end of that deal.)

The Ariens did a good job nearly all of the time — but at 5HP, it was quite a bit underpowered for what it was asked to do. When cutting through thick grass or climbing the steep hill in back of the house, it would sometimes stall out. The canonical workaround for the thick-grass problem was to raise the cutting deck, and drive over the grass very slowly at full power; the workaround for the climbing-the-hill problem was to dismount and walk alongside the mower up the hill while reaching over to steer it. This was fun, but you always ran the risk of the mower either getting away or running over your toes. (At least I had the sense to shut off the blades.)

One day, while backing up to turn around near some pine trees, the mower’s engine revved up dramatically. Not knowing what was happening, I quickly shut it off and rolled it back away from the trees. When I started it up again, everything was fine. I took a look around the engine, and noticed a spring-loaded lever on the right side, near the back of the mower. Pressing gently on this lever caused the engine to speed up a bit.

Playing around with the lever mechanism a bit more, I figured out what it was — a governor for the engine, tied to a set of vanes that pulled the lever forwards when the engine speed increased. By applying some pressure to the lever, the engine could be made to speed up. Since car engines often speed up when more power is needed, I decided to see if this could be used to give the mower a bit more power.

I found some twine, tied it through a hole in the lever, and tied it to one of the seat supports. By pulling gently on the line, I could apply pressure to the lever, and cause the engine to rev up a bit past its normal set point. Instant “turbo mode!”

The mower worked great after that. Whenever I saw a steep hill or tall grass ahead, I would simply pull on the “extra power” cord, and power through the grass or up the hill with no problem at all. Rumors that I would occasionally put the mower into fourth gear and use this effect for extra speed while racing back to the garage are merely conjecture based on stereotypical generalizations of teenage guys. (That’s my story, and I’m sticking to it.)

A year or two later, while doing spring cleaning in the garage, my Dad noticed the line and asked me about it. I told him what it was for and why; to his credit, he just rolled his eyes and mumbled something about pretending not to have seen it. (I guess he did a quick calculation of the risk of a blown engine vs. the unsafe practice of me walking alongside the mower when going up the hill, and decided it was worth it.)

We eventually got a larger mower, and sold the Ariens (still running like the day we bought it, but minus the hack) at a yard sale. The newer mower had a 10HP two-cylinder Briggs and Stratton, electric start, and headlights. It climbed the hill easily and went through the worst summer grass like it was nothing. It was also fast enough in top gear that even as a reckless teenager, I usually didn’t run it flat out because of the risk of hitting a tree. (It cornered like a dump truck.) Still, sometimes I missed the Ariens. There’s just something about a good, fun hack.

 

Posted in Hacks, Nostalgia | 1 Comment