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.

Recommended: Udacity’s CS373: Programming a Robotic Vehicle

I haven’t posted recently because I haven’t had time to mess with my robots.  Instead, my free time has been taken up with learning more theory, via Udacity’s free 7-week class.  There will be a new session starting next month, and I highly recommend that you check it out.

The class gives a broad but hands-on introduction to key robotic concepts and algorithms.  It covered localization,  filtering (monte-carlo, Kalman, and particle filters), pathfinding (intro to A*, dynamic programming, etc.), PID (Proportional Integrated Differential) control, and something called graph SLAM (Simultaneous Localization and Mapping). If you’re already well-versed in one or more of these, you probably won’t learn anything new on that subject, but if you’ve only a passing or no familiarity, the course is great.

The format for Udacity’s courses is what really stands out: short 5-10 minute videos with a question or short programming assignment at the end.  It’s a slightly higher tech Khan academy: mostly an electronic whiteboard and pen, but some videos from Google’s autonomous vehicle and the DARPA challenge.  The programming is done in python and submitted directly from the web page (although I recommend an IDE for the weekly homework programming).

Beyond the robotics course, I think this is starting on the path to the future of college education.  I think it’s much like newspapers and the print Encyclopaedia Britannica.   They have valuable features that the online experience can’t duplicate, but the cost differential is just too great to sustain the old model.  When you can offer a college level course to thousands of students at once, on-line, and crowd-source support to partially make up for the lack of direct, 1 on 1 help, it’s hard to imagine that, in 10-30 years, this won’t be the future of a college degree.  Now, it’s not there yet.  This was a beta run, and the numerous glitches and automated grading problems made that abundantly clear.  In addition, there’s a lot to work out, especially for non-tech courses.  But, compared to $10-$50K per year for a college resident degree?  I think I may have seen the future of education.

UPDATE 2/8/2013: I’m more convinced then ever that some sort of blended mix of low-cost online courses and a reduced “residency requirement” will be at least one model for future degrees.  Private tuition costs have been rising faster than healthcare, while college credit is already becoming available for some online courses.  The University of California system has partnered with Udacity to offer a couple of lower division and remedial courses for credit, online, for $150.  And now, The American Council on Education (ACE) has approved five Coursera courses for “credit equivalency.”  Personally, I loved the college experience, but with today’s high cost, it’s becoming unaffordable for too many, and/or imposing a huge debt.

An Introduction and Example of Finite State Machines

Finite State Machines (FSM) are often an excellent design pattern for robot control software. As I was developing my first robotic vehicle, I started with just modifying and expanding upon some sample code I found online.  This worked for a robot moving around at random, avoiding obstacles.  But once I wanted to add positioning and navigation, it became difficult to keep track of where the logic should be at each step and each time the main control loop executed.  I realized that a state machine approach was the solution, and it’s worked out beautifully.

What is a Finite State Machine?  You can find the formal definition here at Wikipedia, but as David Stonier-Gibson puts it in his tutorial:

The formal, mathematical definition of an FSM is such brain numbing, eye popping mumbo jumbo I feel certain that 9 out of 10 electronic engineering and IT students switch off in the first 5 minutes of the FSM lecture series, never to ever benefit from the power of FSMs in their work. This is not difficult stuff, it’s just made to look difficult by the academics!

The basic concept of an FSM is that the system is, at any time, in a specific, pre-defined state.  Multiple states are defined, along with the internal or external events that cause the system to transition from one state to another.  The functions that need to be performed for each transition from one state to another are then determined, and, of course, you have functions to be performed when in a given state.  Not all events trigger a state transition, some are processed and handled with the system staying in the same state.  It’s easiest to explain by example.  A good, short tutorial with examples can be found in the online article Application Design Patterns: State Machines, along with some useful design hints.  Below, I use the state-machine model I developed for my MARV-1 autonomous dead-reckoning vehicle as an example.

State Machines can be represented in several ways.  One approach is a state transition matrix.  Below is the matrix for the code for my MARV-1 autonomous vehicle:

State Transition Matrix

The topmost row shows the seven states that the robot can be in.  The leftmost column shows the internal and external events that can cause a change from one state to another.  For example, “Button 1 pressed” is an external event.  If MARV-1 is currently in the Off state, it transitions to the Orienting state.  If it’s in any other state, it transitions to Off.  “Completed calculating next heading” would be an internal event that causes a transition from the Orienting state to the Turning state.  If, instead, the last waypoint in the list had already been processed, then there would be a transition from the Orienting to the Off state.

In C/C++/Arduino code, states are typically coded using the Switch command.  Each Case ends with a break;, since the system can only be in one state at a time.  There can be code to run each time a state is entered for the first time and code to run when you exit a particular state.  This code can be dependent on the specific transition, e.g., the exit code from Orienting to Off is different than from Orienting to Turning.  I found it easier to use exit code rather than entrance code wherever possible, because then I didn’t have to set a flag and check each time through the main loop to determined if I was entering a state for the first time or not.

In fact, 95 percent of the code in the main Loop for my MARV-1 vehicle is inside a single Switch statement.  The exceptions are checking for the Button 1 press, since that must be done in every state, and updating position and orientation, since, with the exception of the Off state, that must always be done.

You’ll notice that most of the cells in the state transition matrix are empty.  That’s because most events only affect one or two states.  That means that you don’t need to check for those events when in any of the other states.   The state machine design pattern makes coding simpler and much, much easier to follow.  It also  allows you to change out the details within a state (inside a specific case in your code) without affecting the rest of your code.  The exception to this is the transition triggers themselves and the exit processing code.

Another way of designing or documenting your Finite State Machine is with a state machine diagram.  Here’s the same information for MARV-1, presented in pictorial form:

State Machine Diagram

In the case of MARV-1, I started my planning figuring on an Off state and an On state.  Of course, the On state quickly was subdivided into more.  Since MARV-1 uses tank-style turns and always either moves in a straight line or turns in place, it was logical to have a Turning state and a Traveling state.  As I worked on the code, I found it made sense to break out the Orienting from the Turning, even though the Orienting is just some calculations that complete in a single pass through the main Loop.  Similarly, it became easier to code to break the obstacle avoidance maneuvering into 3 states, one for each step in the 3 step obstacle avoidance approach I decided on:  Back up, turn right, go forward a ways, hopefully clearing the original obstacle.  As you can see from the table or picture, if MARV-1 is still pointing towards an obstacle after turning, it goes back to the Avoid:Backing state, as it does if it detects an obstacle while moving forward.

Finite State Machines are a simple and effective concept for robot software, and I encourage you to plan out your next project using this approach.