page created : April 3rd, 2010     updated : May 5th, 2011  

1. Motivation:

We started a new robot project. A small boat should autonomously sail over the Luxembourg reservoir lake from Lultzhausen to Liefrange. The idea has been in our mind for a long time, at least since we met Riccardo Rocca's great site in 1999, which already had inspired us to work with the Pewatron 6100 (Dinsmore1655) compass sensor years ago !! By contrast to Riccardo's project, we want to realize a LEGO NXT controlled version using as much as possible LEGO parts and a homebrew NXT compatible GPS module. The boat and the NXT programs will be made by a group of students and the GPS-NXT interface prototype by CB. The realization of the PCboard, the soldering and testing will be executed by students. The whole team will do the debugging. We got some inspiration from

2. GPS module

We acquired a SkyTraq Venus 6 GPS Module ST22 from This is a quite impressive and also cheap part. Key features:

  • SkyTraq chipset with 65 channels "All-in-View" tracking
  • Cold/Hot start time: 29/1 sec. (average)
  • Update rate: 1 - 10 Hz
  • High sensitivity: -160 dBm
  • Large voltage supply range: 3-5.5V
  • Low power consumption: 25mA tracking, 50mA acquisition, 75mA enhanced acquisition
  • Size: 22x22x8mm (with patch antenna)
  • TTL UART communication
  • Optional internal backup supply
  • Accuracy: position 2.5m CEP / 5m 2D RMS; velocity 0.1m/sec; time 300ns
  • Weight: 9grams
  • Configurable with many options

The factory settings output has four messages, starting with the $GPGGA message. We want to have positional, but also directional, timing and speed data, so the first thing to program is to reconfigure the module to send out the $GPRMC message. Then we want to have a possibility to switch down the power consumption. Everything should be done over a single NXT sensor port.

Through the serial output it sends the following string of ASCII data, according to the NMEA format, once every second, at a rate of 9600 bps:
(some data may have variable character number)
0         1         2         3         4         5         6         7
The individual elements of this string are:
$GPRMC		NMEA sentence type
145055 		GPS time of position fix (seconds)
V		data quality: A = valid position, V = receiver warning
4453.6083		latitude "ddMM.mmnn"
N		latitude N or S hemisphere
00944.9533	longitude "DddMM.mmnn"
E 		longitude E or W hemisphere
000.0		speed over ground (knots)
000.0		course over ground (0-359.9 degrees)
070399		date of position fix "ddmmyy"
-		not used
-		not used
N		N = Data not valid; A = Autonomous mode etc.
*		delimiter
7F		checksum byte (= byte1 eor byte2 eor byte3 eor … byte62)
The string is terminated by the ASCII codes "13" (carriage return) and "10" (line feed).
3. GPS to NXT interface

The NXT has excellent working I2C busses for each sensor port. The recent NXT firmware (>=1.28) has no major problem anymore. Most of the initial issues had already been solved by version >=1.05. We will be using a PIC16F88 and program it with our Ultimate ROBOLAB for PICs environment. (Unfortunately this pilot project software is no longer available online.) The reason why we use this software mostly is that it is easy for students to follow firmware development, and moreover to do their own programming without the need of long study of C, which perhaps would be more indicated. The learning curve of our software is better, and the students can concentrate on the robot project, without getting lost in details.

The test circuitry on the breadboard has the GPS module, the PIC, the 18.432MHz crystal plus two 22pF capacitors, two LEDs and a handful resistors, finally a few decoupling capacitors. For survey of the serial traffic with the PC, we added a MAX232 and its usual capacitors, and eventually a hacked NXT cable.

Note: we chose a 18.432MHz crystal, because this frequency divides: usual baud rates 38400, 19200, 9600, 4800, 2400 and the PIC baud-generator has 0% error.

4. The interface firmware

The first thing to do is to reconfigure the NMEA message sending with a message of the type:

<0xA0,0xA1><payload length><payload#ID (=08)><payload body><checksum (XOR)><0x0D,0x0A>

Normally we should wait for an acknowledgment from the GPS. This is not implemented in the first firmware version. Instead we are waiting for a serial timeout interrupt. A timer generates an interrupt, if during 100ms there has been no signal on the serial line. Because at start the module sends messages during no more than 500ms, this timeout is perfect to detect the GPS serial silence. The PIC serial buffer is reset and the configuration message is sent to the GPS module. There should be no problem with cold start, since nothing else happens then. Warm start has not been tested yet.

Now the GPS module sends nothing but $GPRMC messages, which are very short (70*10/9600=73ms). Each second we have 927ms time for perfect I2C interrupt replies to the NXT. In order to tell the NXT that we are in this pause, a LED is switched on, as soon as the RX interrupt detects the CR LF termination of the $GPRMC packet. This LED pin of the PIC is connected to the white wire (analog input) of the NXT cable. The second LED is used to indicate that there is activity on the serial channel between the GPS and the NXT. The logic of the Ultimate ROBOLAB programs are intuitively comprehensive:

5. The NXT program

We are working with LabVIEW Education Edition. The first test program should read the data from the GPS interface once a second. Therefore the sensor port is first configured as CUSTOM/RAW. The program waits until it detects an analog value >400 indicating that the serial LED is powered, which happens at the PIC detection of the CR LF. Then the NXT reconfigures the sensor port to I2C and reads 6 x 15 bytes, always with an offset. (We read more bytes, in order to test, if really everything works fine.) The next picture shows the reception of a $GPGGA message (the photo was taken before the $GPRMC configuration was programmed on the PIC.) Everything works fine, with a little flaw. If the GPS module has a lot to calculate, if we are abruptly changing the direction for example, then it seems that it is not able to maintain a constant baud-rate, and some messages are badly received. The blinking LED (actually a third LED, but we just reconnected the second!!) sometimes remains on. This shows that we are lost in some interrupt handler. We have not localized this issue yet.


6. The schematics

Here the rough-and-ready schematics of the interface. After a discussion with Philippe Hurbain we added the BS250 to the device, in order to have the possibility to completely switch off the main power supply. The The back-up power supply of the GPS-module and the PIC are directly connected to NXT 4.3V. Hence, it will be possible that the NXT programically wakes up the GPS module.


7. The layout

Stéphan realized this nice layout of the PCboard. Etching will be done tomorrow, because the device didn't work.


8. The boat project

In fact this year we had been interested in participating in the ESA CanSat contest. However, because of timing issues, this was not possible. So, we had to seek a new project, and here it is: the LEGO boat project. Two years ago, a team had worked on a submarine, but finally abandoned, because of the many difficulties.

Brainstorming the LEGO boat:

  • We got inspiration from Brian Davis' Serenity 1.0:
  • => The Catamaran idea seems the very best: take two LEGO sets 7906, and see what we can do.
  • Perhaps add a canvas and add a sensor for capturing the wind direction
  • Where is the best propeller position: in the center, like Brian's design, or on the sides?
  • Will we need an additional compass, or can we extract valid directional data from the GPS (if the boat doesn't move, we have no direction!)
  • We must check the pedestrian mode of the GPS module, in order to get more precision
  • We need to test the current consumption and the amount of batteries
  • Weight? Balast? Keel?

Brian Davis wrote the following lines: (thanks Brian)

I took a look at today, and had some thoughts I thought might help, so take them for what they’re worth, and I look forward to seeing what you guys come up with!

- a catamaran is very stable, and can be made more stable by spreading the floats further apart, a very nice feature. The boat hulls from #7906 work well, but if you can get them the blue hulls from set #7994 will displace more water, and allow you to carry more payload. In either case, swamping the hulls would result in them taking on water and the boat sinking. To counteract this, I used a hot-wire cutter to cut Styrofoam sheets into shapes that fitted firmly inside the hulls. With the deck on, it looks the same, but can’t flood nearly as easily. Properly designed, they will stay attached to the deck even in a worst-case scenario of the lower hull sinking away.

- Note that you want the center of mass of the ship to be very near the center of the structure so the boat as a whole floats level. That’s rather tough to do, especially as you add or subtract structure as you refine the design. The port-starboard balance was fairly easy to obtain on Serenity, but the bow-stern balance is continuously adjustable by mounting the NXT (with the batteries) on two very long (32 stud) axles. This way it could be slid forward and back to any degree required. This worked very well to balance the center of mass over the center of buoyancy.

- Serenity used the sealed LEGO motors that come with some boat sets. For an all-LEGO solution, it’s hard to beat these, as they are small, sealed, and high-efficiency… but you can’t turn them off or throttle them. So if there was a thrust imbalance (sayt one battery a little lower than the other, or far more likely and a real problem a bit of plant material causing more drag on one motor than the other), Serenity would be forced into a turn. Instead I mounted the motors midline to avoid this, and could turn the ship by turning the entire motor mounts. This allowed not just port and starboard turns, but the ability to reverse in place, spin in place, stop (by pointing the motors in opposite directions), and even “drift sideways”. The result was a very maneuverable platform. If the propellers are controllable (perhaps running props via a submerged drive shaft leading to a motor above the waterline) this isn’t needed, but still a nice thing to think about. I don’t think Serenity’s propeller arrangement is the best possible… but once I decided to stick with a pure-LEGO solution and use the LEGO propeller “pods”, it’s the best I’ve been able to come up with. There will be much faster more powerful LEGO boats than Serenity… but it’s hard to imagine a practical one that’s more maneuverable.

- If you have a catamaran that’s driven by propellers, there’s no absolute reason for a keel or ballast: stability is derived from the catamaran configuration. But if you want a sail of any type, you have to deal with the possibility of a strong gust overturning the entire craft. For a sail, you’d certainly need a keel, and perhaps transferable ballast (at least left to right). I’d say a sail would be very cool… and a lot riskier. A keel would also reduce the maneuverability of the boat (turns become sweeping, not tight). It would help with fighting wind issues, but at least so far in my experience on *small* bodies of water, a low profile is enough to get around this.

- If you are going for an all-LEGO solution, a strong, light-weight, and always, everywhere, cross-braced structure is a priority. In all of Serenity, there is only one place where the structure is held together only by a “studded” connection – where several very large plates are very firmly pressed onto the LEGO decking of the hulls using just about every studded connection possible. Even these LEGO “anchor” plates are locked into the rest of the structure by trapping them in standard beam-plate-plate-beam type structures locked together with studless elements. The entire weight of the structure is held, essentially, on long beams supported at the ends on moving, twisting platforms – a recipe for stud-to-stud failure if you’re not careful. In practice, Serenity can be pickled up by one hull and swung around over my head; after a couple of revolutions there is no trace of separation of any junctions (in fact, getting the sucker apart to work on it takes some doing, and a specific series of steps to disassemble; 3L friction pins with bushings end up being very useful in this).

- A compass (as opposed to just getting the heading from a GPS system) would be a very good thing. As you note, if the boat stops, it has no heading information… and if it’s moving slowly, it will have very poor heading information. More importantly, if there is any current or wind, the “heading” the GPS reports will be due to the overall motion of the boat, which may be very different from the heading of the boat itself. Picture a boat trying to motor “north”, but not overcoming the wind (being blown backwards, to the “south”). The GPS will report a “southerly” heading, but the boat heading would actually be unknown (is it pointed north and being blown backward, or pointed south and motoring southward)? I’d say a compass is a good idea.

I’ve got more thoughts on such boats, but figured you might find some of this useful… and if not, please feel free to ignore it, I will not be offended in the least! I just had so many thoughts on reading your page I wanted to write them up; thank you for your patience with an over-seas back-seat boater. I'd post these in the MCP forums, except I might want to throw them out "into the wild" as well (perhaps on NXTasy), and so didn't want to commit to only that channel... but these are certainly open for discussion there as well.

Brian Davis

  • In his honour, we will baptize the new boat: "Serendipity"
  • The PCBoard has not ben realized so far, because the problems with the etching machine persisted. After the board finally was realized, Stéphan saw that the electrolytic capacitors didn't match the pin layout. The board has to be remade. This throws us back by a week or two.
  • Two 7906 sets have been ordered
  • We also ordered, and already have received the HiTechnic compass sensor.

Yesterday evening we succeeded in making the PCboard, soldering the parts, and testing the device: plugged in... and it worked. Wow, excellent job, guys!!! The transistor was not placed yet, because the current PIC firmware doesn't support its control. A new PIC firmware will include the feature of switching on and off the GPS module. Here a few shots of what happened:

1. Philippe studying Brian's email, taking notes. Everything was discussed so far, but no decision has been taken. We will wait until the LEGO sets arrive.

2. Stéphan realized a new layout. Here he is preparing the PCboard for the exposure device:

3. Developing the exposed board in an NaOH solution (7g/l):

4. Etching the board with FeCl3; copper is dissolved:

(Amateur radio method !!!)

5. Drilling the holes:

6. Soldering the parts:

7. Testing the GPS interface in the rain, just waiting for a valid fix (just 4 satellites):

True position:

49.606988googlemap = 4936.41928deg*100+min=49° 36' 25.16''

6.122184googlemap=607.33104deg*100+min=6° 7' 19.86''

GPS estimated position (+-30m deviation):



8. Indoor test:



10. Test of the GPS module

New layout:

First free-land test. The robot was moved over the sports field for about 2 minutes, after having intercepted at least 4 satellites and the data was written in a log-file. Then the longitude and latitude have been extracted. The GPS  needed to be protected against rain. Because of the rain, we aborted the experiments. No speed data and orientation data have been read yet.


Extracting the robot positions:


Steve Hussenplug wrote this email (thanks Steve):

I'm not sure if you've done this, but you may want to look into kml files ( )

It really adds a whole new cool world of tracking. It allows you to pull data into google earth & google maps.

I stored data for my Green Monster, and wrote a program to convert the csv data into a kml file. You can see some files I've posted on the GM web site:

If you need any help to get going, I'd be glad to help.



Kml-files not yet studied!!

A longer test with the module. The GPS was placed behind the windscreen of a car. The following LVEE VI was run on the NXT, logging the $GPRMC string every 5 seconds. No failure!!!

  • The LEGO arrived. Stéphan ordered 4 more motors.
  • Philippe has some good ideas, if ever we are going to use sails.
  • Eric M. joins the crew. Excellent. He has good dieas too.
  • The team worked on the catamaran idea.
  • Stéphan is in charge to write a LabVIEW VI (NXT module) that allows extracting the data from the $GPRMC packets. Good luck!
  • We went through the GPS PIC program. Needs work:
    • The PIC firmware switches on the "valid" LED, as soon as the <CR><LF> are received from a packet. Works! If the <CR> is received, a flag is set. If the <LF> is received AND the flag is set, then the packet is complete. Bug: Imagine the PIC receives <CR>_some_characters_<LF>; then the flag is not cleared. It should be cleared, if the byte after the <CR> is not <LF>!!!
    • The I2C may hang up in one state --> needs a detection of this situation and an I2C reset then. Although this did not happen yet, we estimate the probability to 1:1000000; so thanks to Murphy: it will happen, and the GPS is lost for the NXT. So, this must be fixed!!!
    • It should be possible to switch to pedestrian mode. Suggestion: if the NXT tries to read a certain specific address, then the mode is changed.
    • We also should be able to switch off the GPS, and
    • switch to low-power mode.
    • ==> a lot work in the GPS interface!!!

The LEGO boats:

Another test with the GPS: a bicycle tour:


The GPS module was placed on a fixed position, in order to estimate the precision and accuracy. (Precision expressed in standard deviation [m] from mean; accuracy expressed in deviation of the mean from true position)

  • 107 samples
  • standard deviation latitude: 2.2m                     (at 1855.333 [m / minute])
  • standard deviation longitude: 1.37m                 (at 1855.333*cos(latitude) [m / minute])
  • deviation from true position (latitude): (5002.6211 - 5002.6225) * 1855.333)= -1.67m
  • deviation from true position (longitude): (556.1684 - 556.1675) * 1855.333*cos(latitude) = 1.67m

very good!


  • Eric worked on the fixations of the motors; quite a difficult task, because the studs are not standard LEGO size (!!), because of the metallic screw and the screw-hole. Needs much work!

  • Stéphan realized the vi splitting the $GPRMC string into its tokens:

  • The PIC I2C interrupt service routine looks like:

  • And the (buggy) TTL-RS232 ISR (see above - bug does not affect the GPS-communication):


  1. The motors are fixed differently. Eric worked intensively on this problem:

  1. The boats will be fixed to each other with. Therfore we need a strong frame:

  1. Stéphan realized the extractor sub.vis that will give us the lattitide and longitude taken from the $GPRMC packet. The packet checksum is computed and compared to the received checksum, in order to verify the packet integrity. DOWNLOAD LABVIEW FILES.



We proceeded to test the power of the boat motors and the burden of the vessel. Therefore the boat was packed with old 1.5V batteries with a total weight 700g. We tried to have the boat cross the little pond of the Luxembourg City-parc.

The ducks don't like it.

Gras embroiled around the propeller.

Eric wants to catch the boat, but the boat capers!

Floating on a wide circle.

  • The speed is 0.3m/sec = 1km/h ==> we will need at least 30 minutes for the 500m distance between Lultzhausen and Liefrange
  • The freely running motor draws 0.37A at 1.5V
  • The motor in water draws 0.6A
  • We estimate that under load the current will grow to 0.8-1A.
  • ==> If we presuppose strong batteries with 2500mAh, we will have enough battery life for the travel.
  • We also measured the LEGO solar panel that produces 5-10mA at 5V, not enough power to rotate the boat motor.
  • The heavy weight produced a load draft that brought the boat to the limit of sinking, at least seriously waterlogging
  • ==> The corpus must be filled with foam.

Next missions:

  • Fill the boat with styrofoam
  • Fix the double motor construction to the boat structure
  • Verify how to calculate the course from the GPS and compass data (think of the clockwise compass angles and reconvert to mathematical angles)
Academic year 2010/2011


The project continues, where we left it for the summer holidays.

The first activities are related to the boat design. It is not that simple to connect the studless motor to the boat structure with studs.

Well, not perfect yet, but this will help. Stay tuned.


  • The team has grown: welcome to Tiago and Alexi.
  • Fixing the motors and joining the boat-parts was impressively difficult.
    • Fixing everything with the minimum number of parts and maximum robustness,... wow, this took hours.
    • The main frame has two functions: maintaining both floats together and holding the motors.
    • The HiTechnic compass has been attached far away from metallic or magnetic parts.
    • The NXT is placed more midschips, in order to distribute weight
  • Next tasks:
    • sealing the floats with Silicon (we abandon the idea of using foam inside)
    • We will use the expensive Energizer L91 Lithium batteries for the propeller motors
    • The NXT, compass and NXT-motor will be water-protected by some foil
    • The GPS is still missing onboard.


Test of the compass-sensor. The boat was manually moved up, down and sidewise, and the compass-sensor data was logged. Because of the discontinuities around 0 and 360°, the data was adjusted. The method is very simple. If the derivate is greater than 200°, we may suppose that we had a zero- or 360°-crossing. Depending on the sign, we add or subtract 360, and get a continuous signal, which is passed through an averaging filter. In fact, we applied a scalar Kalman Filter, in order to eliminate the fine ondulations.


The boat corpus is sealed with silicone, in order to make it water-proof.


First test on the park-pond: the boat swims!! But, as Fred Martin said in a paper: "Real robots don't drive straight."

==> The boat didn't float straight. It took about 15 seconds to turn around and it was trapped in the reeds. However, the GPS and the compass do work correctly.


This is the first working control of the rudder.

A few interesting links:
  • Example 1
  • Example 2
  • Example 3
  • 18/11/2010

    The previous program obviously was incomplete, because it only works for one direction. Also, bizarrely, the values "distance" for the NXT motor control icon could exceed 36°!

    A first text program that includes the GPS follows now. It took a long development time, because we messed up compass angles with heading etc.

    Note that the compass points +90°. Therefore the current heading is (180-compass value).


    The following video shows the reaction of the rudder regulation in function of the bearing.


    We have fixed a date for the first real-world test on the Lac de la Haute-Sûre: Thursday, 28th of April 2011, 15h00.

    To do:

    • CB: Authorization from the Direction de la Gestion de l'Eau
    • Stéphan: protect the PCboard of the GPS with special spray; find a waterproof box for the GPS; buy Energizer L91 batteries (12x); install LV2009 on Laptop
    • Eric: styrofoam for the boat; rubber belts for the fixation of the styrofoam; build a replacement motor block, if ever we get into troubles
    • Philippe: Silicone sealing must be improved; little bottle of champagne for the baptizing; letters "SERENDIPITY"
    • Tiago: transparent film to protect NXT, compass and motor from water; program adaptation: add several intermediate target points on the lake (tolerance 5m radius); datalog GPS, compass and regulation data

    Material to organize:

    • Camera
    • Replacement NXT, if ever we get into troubles
    • We got the authorization to do the experimental crossing of the lake. (Because it is Luxembourg's water reservoir, any motor boat activities are prohibited there. Only the safety divers and otherwise authorized people may use fuel or electric boats.
    • With much effort the NXT program now works:
      • It was quite difficult to assure the correct timing for all the functions, in order to avoid missed GPS-messages.
      • In order to calculate the course vector correctly, we needed to transform the coordinates, and compute a Mercator projection. If we want to obtain Cartesian coordinates involving right angles and valid distances, the longitudes must be multiplied with cosine of the latitude.
    • The NXT, GPS, rudder motor and compass need to be sealed into plastic film, in order to protect from the water.
    • On the lake, we will be conducted by safety divers Fred Werer and Jérôme Gloden. (Many thanks to the diver section of the Protection Civile!!!)
    • The boat will be baptized "Serendipity".


    Because at program start, Stéphan noticed that the rudder was not correctly aligned, he stopped the NXT program, then restarted it. However, because the first instance of the program execution had created the GPS data files, and they had been made write protected, the second call didn't write any data. So, the NXT holds only the first 12 seconds in the datalog. Fortunately we had the handheld GPS on-board with us that had its trace function switched on. Since we followed Serendipity, we can retrace the whole trajectory. We could extract the data from the Garmin GPS.

    See the video:



    Sorry! The datalog didn't work for another reason! In fact, it was a program bug. We erroneously had wired the integer division oputput of a modulo function instead of the real modulo value. The program should have logged new GPS data, each time the modulo of a loop index was zero. Because of the bug, only the first 10 seconds were logged. Bummer!!!!