Struct and functions when using the Arduino IDE

As anyone reading this blog probably knows, the Arduino IDE simplifies a number of programming for an embedded environment and hides some of the required C / C++ material. This can make life a lot easier, but it can also cause problems, especially when you step out to do more complex things. I got bit by one of those earlier today. Since I eventually found a post to the work around, I thought I’d post it here.

In my robot code, I”ve defined a struct called coord that holds two doubles, which are the x and y coordinates for whatever I need (e.g., the position of the robot, the next waypoint, etc.

Today, I wanted to compute the distance from the ray defined by the previous and next waypoint and the current position of the vehicle, so that the error could be fed into a PID controller. I figured it would be easy to pass the parameters as coord types. BUT, this turns out to be trickier than it should be with the Arduino. Unless the structs are defined in a .h file, there are problems with their scope. A work-around is documented by Alexander Brevig on the Arduino Playground: Struct Resource for Arduino.

An unseasonal post: Automating Halloween Props

This post is more suited to Halloween then the coming Yule, but I finally got around to writing it, and besides, as I write this, there’s only 327 days left to next Halloween!  There are several options for controlling animated props, including prop controllers specifically designed for this purpose.  A recent addition to the market is the MonsterShield, an Arduino-based prop controller with open source code you can modify.  I haven’t tried one out, but thought it was work a mention.  In my props, I just use a handy micro-controllers, such as an Arduino, along with sensors such as a PIR.  The PIR (or pressure mat, or whatever sensor you choose) sends a signal to the microcontroller when it detects someone, and then your microcontroller can trigger a whole sequence of pre-programmed actions.  I had two such props in my Halloween display this year.  The first is a classic “Monster in a Box“.  I use a PIR sensor to detect when someone comes near.  When this happens,a Teensy sends out an output to a Power Switch Tail to turn on the power to a wall wart that delivers 12V power to the windshield wiper motor, as well as to a green light inside the box.  I use a Power Switch Tail so that I don’t have to worry about any safety issues dealing with house current directly.  The motor sequence has several stops and stop in it, of differing lengths, so that the action is more natural.  After it triggers, there’s a dead time, so that it doesn’t keep restarting while trick-or-treaters are standing in front watching it.

Closed Monster in a box, showing the box with the PIR and Arduino that triggers the box.

Inside view of the Monster in a Box, showing the wiper motor and irregular cam.

 

The other prop where I use a PIR and an Arduino is my scarecrow skeletons, who do a little talking and singing routine when triggered.  Here, an Arduino controls two Cowlacious audio boards that in turn drive the servo boards that control the jaw servo and lights in the skulls (also from Cowlacious).  I’ve had the audio boards for some time.  They work fine, and have a wide host of control options (including the ability to be triggered directly from a PIR).  However if I was remaking this prop, I’d probably just wire up some really cheap mp3 players. The video shows the two skeletons doing their routine. Sorry for the quality, my video editor is refusing to save the edited version.

There is Power in a Union: Dealing with multiple byte values via serial

One reads data from the serial port one byte at a time. This is fine for single by data types like char, but what if the data you’re receiving represents one or more multi-byte data types, such as floats or ints? How do you put the pieces back together again? There are several approaches, some for specific cases and other for more general cases. I came across the need to do this when dealing with a compass module. I’m sure there’s more than what I’ve stumbled across, so feel free to add more via comments.

One of the simplest cases is an int in two bytes. For this case, you can read the two bytes into a variable of type byte, then shift the higher value to the left by eight bits and add them into an unsigned int:

higherByte = compass.read();
lowerByte = compass.read();
bearing = ((higherByte<<8)+lowerByte)/10

In this example, bearing has been declared an integer, and the compass module returns a value between 0 and 3600. Since bearing is an int, which is two bytes long, each byte is converted to an int, the higher byte value is shifted left 8 bits, and the values added.

Another way of doing this is to take advantage of the Word data type, which for Arduino’s and other AVR devices (and on many other systems) is 16 bits. One can combine the two bytes into one word and then cast it as the appropriate type, e.g.,

x = (int) word(xHigh, xLow);

I put together some test code for the Devantech CMPS10 module’s bearing and raw data feeds using these two approaches.  If you’re curious or need a quick and simple test program for your compass, checkout https://github.com/ViennaMike/CMPS10SerialTest.

If the value being read uses less than the full 16 bits AND IS SIGNED, such as data from Parallax’s compass module, things get tricky. You need to read the highest bit used (which will be the sign bit) and see if it’s a 1 or a 0. If a 0, the number is positive, and you can just shift the data as above. If it’s negative, there is an additional step after you shift left. You need to have the new sign bit set to 1 and the unused highest order bits ALSO set to 1, since negative numbers are stored using twos complement arithmetic. So you want to bitwise OR the result with a mask, where the highest order bits in the mask, up to the number of unused bits in the original data, are set to 1, and the other bits to 0. See http://www.arduino.cc/playground/Main/HM55B for an example of this.

But what if you have more than two bytes in your structure, or you want to easily handle a long string where, perhaps, you read 6 bytes, with 2 bytes each for x, y, and z parameters? Then, my friends, you will learn that there is power in a “union.” A union is another data type. It allows the same portion of memory to be accessed as different data types. So you can define the particular union to be BOTH a sequence of bytes, read in sequentially over a serial port, perhaps, AND whatever the bytes represent (say a set of 3 ints, or 4 ints and 2 chars). Here’s a simple example:

union Data
{
byte b[2];
int value;
};

int main( )
{
union Data data;

data.b[0] = compass.read();
data.b[1] = compass.read();

bearing =data.value;

There’s more to union’s, and I recommend C-Unions and C++ Other Data Types for an introduction.  There’s also a direct serial port on arduino discussion at Float Value through Serial Port..

p.s.: The title of this post comes from the title of a song by labor activist Joe Hill, written in 1913. For a current version, check out Billy Bragg’s version on You Tube.