Monthly Archives: March 2016

In my last post, I described my efforts to integrate a CK Devices Mongoose 9DOF IMU module into my Wall-E2 wall-following robot. In that post, I had collected a set of azimuth (heading) data from the Mongoose showing that the Mongoose was operating properly and that significant error compensation was possible using a simple sine function. This led me to believe that it would be feasible to install the Mongoose on the robot and create a similar compensation function. Unfortunately, that turned out not to be the case. When I collected a similar set of heading data in the installed case, the data showed non-linear behavior for which function-based compensation would be difficult, if not impossible to achieve.

The image below shows results from the ‘bare’ (desktop) uninstalled configuration, where it is clear that the Mongoose raw heading values closely follow the actual magnetic heading, and that a simple sine function is sufficient to reduce heading error to approximately +/- 2 deg.

Mongoose Mag Heading & Error on desk before installation on robot

The next set of images shows the Mongoose installed on the robot between the upper and lower decks. The idea was to place the Mongoose in a location reasonably well protected physically, but away from high-current elements. I also wanted to avoid placing it on the upper deck to avoid the additional inter-deck wiring and attendant maintenance/troubleshooting complexity.

Mongoose installed on robot, side view

Mongoose installed on robot, top view

After installation, the same set of measurements were taken, with the results shown in the following plots. As can be seen, the Mongoose heading readings in this case are hugely different than the desktop run. Instead of being able to compensate the heading error to within +/- 2 deg, the compensated error is greater than the uncompensated one! Looking at the Installed Raw Heading plot, it appears that the readings are relatively linear (but heavily suppressed) out to about 315 deg, where something bad happens and the reported heading falls rapidly to near zero. I made another run in the installed configuration with the magnetometer gain turned down as far as possible, but this did not materially improve the situation. Clearly something on the robot was drastically affecting the Mongoose magnetometer, to the extent that compensation was impossible. Moreover, due to the retrograde readings between 315 and 360 degrees, even a lookup table solution seems problematic.

As I often do when faced with what appears to be an insurmountable obstacle, I tabled the problem and did something else for a while and let my subconscious work on the problem for a while. After a couple of days of this, I decided to go back to the uninstalled (desktop) case, re-establish my measurement baseline, and then see if I could determine what on the robot was causing such huge magnetic heading variations. After playing around for a while, I was able to determine that the cause of the problem was the permanent magnets in the DC wheel motors – well DUH!! After smacking myself on the forehead a couple of times for not thinking of this days ago, I realized that I had carefully determined that Wall-E’s chassis was constructed of aluminum that shouldn’t (I thought) cause problems with the magnetometer, forgetting entirely the fact that in addition to not affecting the magnetometer, it also wouldn’t shield the magnetometer from the strong magnetic fields generated by the motor magnets – oops!

So, what to do? As much as I would like to avoid it, it appears now that the only viable solution (other than abandoning the magnetometer idea entirely) is to put the Mongoose on the top deck, as far away from the motors as possible. I am at least a little optimistic that this will work, for two reasons; with the gain turned down, the Mongoose almost worked where it was, and because mag fields decrease with R3, a few cm could make a significant difference.

In my last post from about a week ago, I described my ongoing efforts to integrate the CK Devices Mongoose 9DOF IMU into my ‘Wall-E2’ wall-following robot. Since that time, I have gotten the Mongoose successfully integrated into the robot, and am able to see magnetometer & accelerometer readings being passed through the host Arduino Mega to the PC via the Mega’s serial port.

After getting all the hardware and software issues worked out, I have now started on the issue of getting the magnetometer calibrated for it’s new home in the robot. All magnetometers need to be calibrated after installation to compensate for errors caused by nearby metal (ferrous and non-ferrous) objects; otherwise the reported magnetic heading can be substantially off. I have considered just using a 360-element lookup table containing offset values, but that’s a bit tacky even for one with my low standards, so I have been researching available magnetometer calibration techniques and tools. I found a nice discussion at DIY Drones here, but I have been having trouble getting the tools to work. The discussion (and tools) center around the widely available GY-273 HMC5883L breakout board, and this ain’t quite the same animal as the Mongoose.

Following the general line of the discussion at DIY Drones, I downloaded the ‘MagMaster’ ZIP files, and attempted to get the MagViewer visualizer program linked up with my Mega/Mongoose combination, without much success. After flailing around for a while with the robot/Mongoose setup, I decided to simplify things by isolating the Mega/Mongoose combination from everything else going on with the robot. I had a spare Mega, so I simply connected the Mongoose to Tx1/Rx1 on the spare (same as on the robot) and loaded a modified version of the robot controller onto the Mega.

The modifications basically stripped away everything to do with the robot, leaving only the code that interfaces with the Mongoose. According to the DIY Drones discussion, this should have allowed the MagViewer program to see the same magnetometer data as for the GY-273, but apparently not. The viewer program never shows any activity – bummer!

Posted March 16, 2016

Well, I’m still not sure why the MagViewer program didn’t recognize the Mongoose mag data (I posted to the DIY Drones forum, but no replies yet), so I decided I would try a variant on my original idea of a lookup table.

First, I needed a way to accurately orient my Mongoose module to different headings. I Googled around a bit, and found a protractor printing site that offered 360-degree heading graphics like the one shown below

4-inch heading circle, calibrated in degrees

Then I taped a narrow strip of paper to the bottom centerline of the Mongoose module to make an accurate pointer, and proceeded to record the actual Mongoose heading reading for each 5-degree increment around the circle. I started this process by orienting the paper heading circle so that the 0/360 point corresponded to a Mongoose heading reading of 0 degrees, i.e. aligned with magnetic north as measured by the Mongoose. The data were recorded in an Excel spreadsheet, and the error term (difference between the nominal heading value and the Mongoose reading) was calculated and graphed, as shown below.

Mongoose reading versus actual magnetic heading, with error plot

Well, when the graph first popped up, I just about fell off my chair, as I recognized an almost perfect sine wave graph. This immediately told me two things:

The Mongoose sensor, the test setup and the data was all valid. There is no way I could have managed that smooth of a curve by accident, and also no way it could have been that smooth if there was any significant mag field distortion

At least for this case, with no significant installation errors, almost perfect heading compensation could be accomplished with just a simple sine function with a slight negative DC offset corresponding to the average value of all errors (about -1.35 according to Excel)

To test this theory, I used Excel to calculate the required sin function values, and added the result to the calculated error values for each measured angle. Then I plotted the compensation and comp+error curves on the same plot as before, as shown below.

Angle Error, Comp values, and Comp+Error

From the plot, it is clear that the compensation is effective, although not perfect. The compensated error amplitude looks to be about 2-2.5 degrees, more than adequate for my purposes. I think the remaining error is due to the fact that the sensor data traces out an ellipse rather than a circle.

So, the next step is to install the Mongoose sensor back on the robot, and do a similar test utilizing an 8″ diameter version of the heading graphic. Assuming I get similar compensation results, I’ll probably call it a day and start running field tests. After all, I’m not sure I care if Wall-E thinks a hallway is oriented at 270, 260, or 280 degrees magnetic, as long as the next time it goes down the same hallway it gets more or less the same results!

In my last post on this subject, I described my efforts to renew my acquaintance with CK Devices’ Mongoose 9DOF IMU board, with the intent of integrating it into my wall-following robot project. This post describes the first step toward that integration goal.

The Mongoose board operates on 3.3V and communicates via RS-232 protocol over a 6-pin 0.1″ header block, compatible with the CK Devices ‘FTDI Pro’ programmer module, as shown in the following photo.

Mongoose 9DOF IMU board, with FTDI Pro USB-Serial adapter

Integrating this board into Wall-E requires addressing two distinct but related issues – the voltage difference between the 5V Arduino Mega controller and the 3.3V Mongoose, and the coding changes required to retrieve the desired heading/attitude information from the Mongoose.

The Hardware

The 5V/3.3V issue requires that 5V serial data levels from the Arduino Mega be stepped down to 3.3V, and 3.3V serial data levels from the Mongoose be stepped up to 5V. Simply ignoring these problems does seem to work (the 5V data from the Mega doesn’t appear to harm the Mongoose, and the 3.3V data from the Mongoose does seem to be recognized by the Mega), but it is inelegant to say the least. Also, a recent addition to Wall-E’s superpowers included Pololu’s ‘Wixel Shield’ module, which fortuitously included some spare circuitry for just this purpose, as shown in the schematic drawing excerpt below. The upper right corner shows the full step-up circuit used to connect the 3.3V Wixel Tx line to the 5V Arduino Rx line, and the top center shows the step-down circuit used to connect the 5V Arduiono Tx line to the 3.3V Wixel Rx line. The lower area shows the spare parts available on the Wixel shield – and the important thing is that there are two general-purpose N-channel MOSFETs. These can be used to construct the same step-up circuit to connect the 3.3V Mongoose Tx line to the 5V Arduino Mega Rx1 line, and one of the 4 available 2/3 voltage dividers can be used to step down the 5V Arduino Mega Tx line to the 3.3V Mongoose Rx line.

The following image is a small section of my overall Scheme-it (Digikey’s free online schematic capture app) schematic for Wall-E, showing the addition of the Mongoose IMU.

The Software:

After getting the hardware wired up and tested, I naturally thought All I had to do was plug in the Mongoose with the full set of reporting software, and I’d be ready to go – NOT! So, after the obligatory yelling and cursing and the appropriate number of random code changes hoping something would work, I was forced to fall back on my somewhat rusty (but not completely worthless) trouble-shooting skills. I started by creating a new, blank Arduino project. Into this project I placed code to simply echo whatever I typed on the serial command line to the serial view window. To this I added a few lines to make the laser pointer blink on/off, just to provide a visual “I’m alive!” indication, and then tested it. After all errors were made/corrected, etc, the final code was as shown below.

The next step was to extend the echo loop to include Serial1, with a simple jumper between Tx1 and Rx1 on the Mega board. In the software all this required was Serial1.begin(9600) in Setup() and the addition of the code to route command line bytes out Tx1 and to route received bytes on Rx1 to Tx0 so that it would get displayed on the serial monitor. The code to do this is shown below:

The next step was to extend the loop beyond Serial1 and into the Mongoose, by replacing the jumper from Tx1 to Rx1 with the Mongoose board’s Rx & Tx lines respectively, and replacing the normal Mongoose code with the turn-around (echo) code. No change should be required to the Arduino code, as it will still be echoing whatever shows up at Rx1 to Tx0.

The Mongoose code is:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

voidsetup()

{

Serial.begin(9600);

}

voidloop()

{

/* add main program code here */

while(Serial.available()&gt;0)

{

charreadbyte=Serial.read();

Serial.write(readbyte);

}

}

When this code was loaded into the Mongoose and run stand-alone, I got the following output by typing ‘this is a test’ on the serial port command line.

After the Mongoose was disconnected and placed into the robot circuit, I got the following output from the Robot project on a different comm port.

So, it is clear from the above that the Mongoose board connected (through the step-up/down circuitry on the Wixel shield) to Rx1/Tx1 is successfully receiving and echoing whatever shows up on its serial port.

Now it was time to reload my modified version of CK Devices ‘Mongoose_base’ firmware back onto the Mongoose and get it running with Wall-E’s firmware. After the usual number of hiccups and such, I got it running and nicely reporting ‘Tilt’ (X-axis accelerometer) and ‘Heading’ (derived from 3-axis magnetometer values) along with the normal robot telemetry values, as shown in the printout below.

Although the Mongoose module has been successfully integrated into the robot system from a technical standpoint, there is still plenty of work to be done to complete the project. At the moment (see the photo below), it is just kind of ‘hanging around’ (literally), so some additional work will be required to mount it properly. Stay tuned! ;-).