<< Raspberry Coffee page
Enriching the on-board NMEA Stream with a Raspberry PI and Java
Most - if not all - the software and hardware components mentioned in this document are reachable from the Resources section, at the end of this document.
Several electronic instruments are available on boats (sailing boats, motor boats).
Those instruments read, compute, and eventually provide various data used for navigation.
The idea here is to have an easy access to those data, display them on several kinds of devices (and not only on the expensive displays sold by the nautical electronic providers), and possibly add more data to the ones already managed and manipulated by your existing electronic instruments.
The electronic instruments available on boats are used to measure data like the boat speed and heading, the wind speed and direction, read the boat position (GPS), all this kind of things used for navigation.
Some data are read from transducers (boat speed through water, wind speed, compass heading, etc), and some are computed (true wind speed and direction, true heading, etc).
Those data are usually available in the NMEA format. NMEA stands for National Marine Electronics Association. The definition of the NMEA strings is one of the oldest electronic standards.
The NMEA sentences (or strings) are human readable (i.e. it is a text format, it can be some times a bit cryptic). They can be easily parsed by a computer program, several such parsers can be found for free.
Here is what an NMEA stream can look like:
Hint: What is a parser?
A parser is this piece of software that turns some text into some "object", or actually some "structure".
An "object" is a programmatic structured entity - belonging to a specific program, written in a specific language.
Let us take an example.
Let us take the
NMEA string, present in the stream featured above.
Its meaning is
recommended minimum data for gps
. (I know: where does the C
Here is its structure, as described in the NMEA specification:
1 2 3 4 5 6 7 8 9 10 11
| | | | | | | | | | |
| | | | | | | | | | Variation sign
| | | | | | | | | Variation value
| | | | | | | | Date DDMMYY
| | | | | | | COG
| | | | | | SOG
| | | | | Longitude Sign
| | | | Longitude Value
| | | Latitude Sign
| | Latitude value
| Active or Void
This is a good illustration of what an NMEA string can be.
- It begins with the character
$ and the first comma, are 5 letters
- 2 characters for the device identifier (
GP in this case)
- 3 characters for the sentence identifier (
RMC in this case)
- The 3 last characters are a checksum, used to confirm that the sentence is valid (
*6A in this case)
- Between the first comma and the checksum is the string to parse, as described above
A json (J
otation) parser could turn that string into a json object like this:
The object and the string are semantically 100% equivalent (that also means that the string can be fully re-generated from the object).
In the object above:
cog is the Course Over Ground, in degrees
sog is the Speed Over Ground, in knots
date is an epoch (for computers, it is the number of milliseconds since January 1st 1970 at 00:00:00.000. All computers and languages know how to deal with that).
764426119000 is equivalent to
Wed Mar 23 1994 12:35:19 UTC.
Dates and times management is a very vast topic. See this article.
In short, this is what an NMEA parser would be doing. See the Resources
section for details about the Java parser used here.
Serial Port access
Many navigation stations deliver the NMEA data through a Serial interface, which is compatible with many devices (like laptop computers).
The unfortunate thing about the serial ports is that they are to be accessed exclusively. That means that when one program - running on a laptop for example - is reading the data emitted by the NMEA station, those data are not available for any other program until the serial connection is released by the program using it.
This can be painful when you want to simultaneously
- Read the GPS data from a chart plotter (like OpenCPN)
- Read the NMEA stream to display the data in a graphical interface
- Read the GPS data from Airmail, to use a propagation chart to aim for the most appropriate SSB land-station
Introducing other data, other sensors
In some cases, you could be interested in monitoring data that are not managed by an NMEA station (like the batteries voltage).
You could also be interested in monitoring data managed by NMEA, but not by your NMEA station (like air temperature, atmospheric pressure).
Injecting those data in the NMEA Stream you read from your station would
Note: You might be interested some computed data that are not returned by your NMEA station (like True Wind speed, direction, angle for example). They could be computed from existing data, and injected in the stream just like above.
- Make them available for all the NMEA-aware programs reading the NMEA stream
- Allow you to log them to monitor, display, or replay them
A laptop can sound like an obvious solution for your on-board computing needs, but the power consumption of a laptop is not always negligible. The NMEA stations usually draw a very small amount of current, but a laptop power adaptor can draw between 1 and 3 Amps, which is a lot when you have limited energy available, like on a sail boat for example.
The computer you would use to read the NMEA stream will probably sit close to the chart table, but you might very well be interested in visualizing the data it computes on deck, from existing displays, or from some wireless devices, like tablets or smart-phones.
The Raspberry PI is a credit-card-size computer that can be used to address all the challenges mentioned above.
It is a fully featured Linux computer, that you can get for less than US$40 (2015).
Linux has no incompatibility with Java, hence Java runs just fine on the Raspberry PI.
The choice of a language is a delicate topic; it has some close-to-religious dimension... You cannot convince someone who does not believe you that your language is better than his language. At least, I can't.
I will spend no time trying to convince anyone to use Java rather than any other language.
But I use Java at least because
This being said, all the softwares I wrote to run on the Raspberry PI (in this document) are written in Java. They are all in Open Source.
- I know it (and I like it)
- It is free and Open Source
- There is a huge Java community (9 million people in 2014), no question will remain un-answered
- It is very scalable (runs on very small and very big machines)
- Once it runs, it runs the same on all systems (Windows, Mac, Linux, etc)
- It has gorgeous debugging (local and remote) capabilities
- A jar file (Java ARchive) that runs somewhere will run the same anywhere Java runs, no re-compilation is required
- Many good IDEs (Integrated Development Environment. not Improvised Explosive Device) are available for free
The Navigation Console is a program I've been using on board for several years (I wrote it, partly at sea). It provides - among other features - a graphical user interface to the navigation data.
Graphical, yes. Because even the smartest guy is tired after several days upwind against a snow storm...
And even if you are not the smartest guy, if you are not upwind, not tired, and it is not snowing, there are better ways to use your energy than
scanning raw NMEA sentences.
The Navigation Console, Swing GUI
I have recently enhanced it to run in headless mode (i.e. without graphical user interface), to run on the Raspberry PI. And it works just fine. In those headless conditions, the role of the console is to read and compute the data, possibly log, and re-broadcast them on one or more channels. For such a re-broadcasting to happen, the Raspberry PI creates its own ad-hoc wireless network. Other devices will join this network, and will then have access to the re-broadcasted data.
Notice on the picture above: the slice of Pi on top of the Raspberry PI, hosting the battery monitoring device, and the small breadboard, with a BMP180 PCB plugged in it, and connected to the Slice of Pi. We'll talk more about those two later in this document.
The Raspberry PI at work on board, in the chart table.
Hint: What is a slice of PI?
No pastry..., it is a PCB (Printed Circuit Board), designed to fit on top of the Raspberry PI.
Just google it
We need to plug-in three USB sockets here:
The device featured here is a Raspberry PI Model B, that comes with two USB ports. The more recent one B+ has 4 USB ports; this would cancel the need for the USB hub you can see on the picture, as we would have by default have more than the three USB sockets we need in this context.
- One for the wireless network dongle
- One for a small wireless keyboard
- And most important, one for the NMEA input
Many navigation programs provide the possibility to read the NMEA streams from other channels than the Serial connection. Those other protocols are usually TCP (Transfer Control Protocol) or UDP (User Defined Protocol). Also available for the same purpose: HTTP (Hyper Text Transfer Protocol), RMI (Remote Method Invocation), WebSocket...
The idea here is to use a Serial port of the Raspberry PI (USB) to read the NMEA data from the station, and then to re-broadcast the data as they were read on another channel. All the channels mentioned above can be consumed simultaneously from several clients. This way, the data read by the Raspberry PI are simultaneously available to all the devices interested in reading them.
The Navigation Console provides TCP, UDP, HTTP, and RMI servers. Those servers are very tiny, and do not overload the Raspberry PI.
The HTML5 WebSocket protocol is also available, through node.js and a user-exit.
Multiplexing is this technique that takes data from several several origins and merges them into a single channel.
Here we read NMEA data from the NMEA station (already NMEA formatted, obviously), and the program puts them in a cache (technically, it is a HashMap, living in a singleton). Whatever component - like other components of the soft that would need the GPS position, all the different servers (TCP, UDP, etc) would read that cache as the single point of truth. Computed data are also read from the cache. As a matter of fact, all computed data (like True Wind Direction and Speed, Current Speed and Direction, Performance, etc) are re-calculated every time a new value is inserted into the cache by the NMEA reader.
Two things to notice:
We will use those aspects to inject extra data in the cache.
- The HashMap is a Java dynamic structure
- The cache also uses a Publish/Subscribe architecture that implements a listener pattern
For example, you can read the battery voltage from some specific device you can build (Open Source as well), turn this value into an NMEA Sentence, and inject it in the cache. Whatever component has subscribed to the
manageEvent event in its listener will be notified of the injection of the NMEA sentence.
The same is true for any other data. I used a BMP180 PCB (from ) to get the air temperature and the atmospheric pressure (NB: unlike the battery voltage, those data do have an NMEA equivalent, but not available on the NMEA station I have on board). They are read from the sensors, turned into an NMEA string, and injected in the cache. See in the picture below the data prefixed with BAT (custom NMEA chain, BATtery), MTA (Air Temperature), MMB (Barometric Pressure). The Character Console featured below is reading the data from the cache they're injected in.
This one provides for (almost) nothing an access to the data computed by the Raspberry PI. It can be customized by the user. The goal here is to have an access to those data, without having to turn on a laptop or any such demanding device. The only one to switch on is the screen itself, which can be turned back off when done reading.
The Character Console, on a 7" RCA screen, on board.
TCP and friends
TCP and UDP are light protocols, designed for computer-to-computer communication. They are both based on a socket mechanism. Once a socket is established between two computers (a client, and a server), then the logic of the dialog will be implemented by the programs running on both client(s) and server, which they have to agree on (to understand each other). In our case, this is extremely simple, once a client is connected, the server is sending it all the valid NMEA strings it reads.
On the laptop, using TCP to get the data from the Raspberry PI, simultaneously using the Graphical Console, and OpenCPN.
HTTP has always been HTML's best friend. HTML is a markup language (widely used to design web pages), HTTP is a transport protocol that can convey HTML streams.
HTTP is based on TCP, but is has been designed to be a request-response protocol. For the server to do something, a client has to ask first.
As long as you have a browser on the device you want to use, then HTTP would be an obvious choice.
To refresh the data, we would use AJAX, in order to avoid a refresh to be performed by the client.
HTML5 provides elaborated graphic capabilities that will give us the possibility to come up with a nice graphical user interface.
The HTML console is refreshed every seconds. The AJAX request performed every second returns an XML document, parsed on the client side.
The HTML5 console, as seen in a browser (laptop, tablet, smart-phone, ...)
This page can be reached by default at
The WebSocket protocol has been introduced with the release of HTML5.
It is also based on TCP.
One of the drawbacks of HTTP is that it is a request-response (a.k.a. push-pull) protocol. You have to make a request to get a response. For example, if you want to get a flight status from some airline website, the first time you reach the page, it gives you the expected arrival time of the flight. Every time you want to see it this estimated time has changed, you must refresh your page. In other words, request it again.
The WebSocket protocol precisely addresses (among others) this kind of issue. Once the client (i.e. your browser) is connected on the server, data will be pushed (by the server, to the client) as needed, without requiring the client to refresh its page. This clearly divides the traffic by two.
The browser you use must be WebSocket aware though. As of now (2015), some browsers (like Internet Explorer 9) still do not support it.
In the Navigation Console, the WebSocket interface is implemented as a user-exit.
It requires a WebSocket server to be available. We can (fortunately) run it on the Raspberry PI. Node.js is the one we use, with its WebSocket module. Google it to see how to install all this, it is fast and easy.
In short, here is how it is going:
The WebSocket console looks exactly like the HTML5 one featured above. But it takes about half the resources.
And the data are refreshed by the server.
- An HTTP/WebSocket server is started on the Raspberry PI
- A user-exit (listening to the cache) is pinging the WebSocket server everytime some data is inserted
- A web page (WebSocket client) will reach the WebSocket server to display real-time data, pushed by the server, from as many clients as needed. The data to display are returned as a json object, embedded in the payload of the WebSocket message send by the server to the client.
Summary of the architecture
The full set. The Raspberry PI is the heart of the system.
HTTP and WebSocket play the same role on the picture.
The Raspberry PI is the only device connected to the NMEA Interface (the boat's instruments). It is the first to be turned on, and the last to be switched off. I've been running it continuously for weeks, without any glitch.
The Raspberry PI fulfils two distinct functions:
- It enriches the NMEA Stream read from the NMEA Station, by computing new data, and adding data read from the sensors it is connected to
- The enriched stream is then re-broadcasted using non-exclusive protocols, so it can be read and used simultaneously by a variety of devices, on its own network.
The Raspberry PI rebroadcasts the data using TCP, HTTP, and WebSocket (in this case). Data can also be logged on the Raspberry PI's SD card.
The laptop uses TCP to consume the data, and can run simultaneously several programs using the NMEA data.
The character console also runs on the Raspberry PI, but in another process than the one reading the data. This way, the character console can be stopped, without interrupting the logging and re-broadcasting performed by the NMEA Reader process.
Tablets and smart-phones can join the wireless network, using HTTP or WebSocket to display the HTML5 Console.
See on the picture above the central place taken by the Raspberry PI. It is acting as the main hub of all the system. It is the only one reading the NMEA data out of the NMEA station. In addition, it manages its own sensors to read extra data (in this case: battery voltage, atmospheric pressure and air temperature). All the data gathered by the Raspberry PI are re-broadcasted onto several channels, depending on the devices connected on the Raspberry PI's own ad-hoc wireless network. Those devices can join or leave the network at their leisure, the only piece remaining alive will be the Raspberry PI, maintaining all the infrastructure. And all this for between 0.13 and 0.19 Amps. The character console running on the 7" RCA screen preserves a rapid access to the data currently available on the Raspberry PI.
As of July 2016, we can now add a Pebble watch to the boat's network.
It is easy to connect it to the network, a first implementation is currently using WebSockets. XMLHttpRequest may follow.
And the basic Pebble works just fine, the battery lasts way long enough away from the power supply, and its price is under $100.
The code is on GitHub.
Currently, a smartphone - paired with the watch with BLE - is still required. I'm looking forward to playing with the PebbleCore...
What we've seen so far does not involve the extra data we can feed in the NMEA stream from the Raspberry and its connected sensors.
We've seen above that the Raspberry PI has 2 extra sensors to
The data read from those sensors are converted into an NMEA string, and injected into the NMEA stream (see the multiplexing section for details).
- Monitor the voltage of the batteries
- Read the atmospheric pressure and the air temperature
As they're part of the NMEA stream, any client reading those data cannot tell their origin.
For the same reason, those data can be logged along with all the others.
- About logging...
The disk of the Raspberry PI is actually an SD card. I use a 16GB SD Card. It allows me several weeks of continuous logging.
Let us take the battery voltage data as an example.
Here is a graphical rendering of a several day logging of the battery voltage.
Using another Java project I own, I can calculate the sunrise and sunset, at the location of the boat, for the date of the logging. This is what's rendered in the background of the graph, gray for the night, white for the day.
Battery Voltage logging
A quick analysis
The small notches on the red line correspond to the periods when the fridge goes on.
During the day (white background), you can notice that the voltage goes up, and back down before dark. This is because of the solar panel, that feeds the batteries.
Orienting the solar panel so it permanently faces the sun makes a very big difference! Specially on this graph, during the first part of the day.
During the night (gray background), there is nothing to charge the batteries.
The notches corresponding to the fridge are there, but beside that, it is clear that the average voltage does not drop during the night.
This means that there is no leak in the circuit. And that is good news!
We can also log the atmospheric pressure, read from the BMP180 sensor. That one can prove very useful to anticipate atmospheric phenomenons. Logging those values and sending a warning when the pressure drops below a given threshold becomes very easy, and can happen to be a precious asset.
There are many cheap sensors that can be used with the Raspberry PI. Many of the data they emit can certainly contribute to a safer and more accurate navigation.
The only boundary is your imagination!
It is also possible to compute NMEA data that would not be returned by your NMEA Station. Data about True Wind for example, like its speed, angle and direction. Those data are to be calculated, and turned into valid NMEA strings such as
Any program, aware of those sentences, can render them accordingly.
True Wind, available in OpenCPN.
Following the exact same pattern, you can insert the current speed and direction (String VDR). See the
OpenCPN 3.3.2316 MDA support for barometric pressure
olivsoftdesktopuserexits.LongTimeCurrentCalculator user exits to see how.
Hint: What is True Wind and Current calculation?
The calculations of the True Wind and the Current are not very complicated, but they rely on several parameters. Determining the values of those parameters is absolutely crucial
The wind measured by the instruments is the Apparent Wind
. This is the vectorial combination of the True Wind
with the Boat Speed and Course over the ground
. This is the wind you feel when riding your bike in no wind. You feel wind even if there is none.
The True Wind
can be calculated by triangulation, as seen above. The Apparent Wind
is in blue, the True Wind
is in black, and the pink vector is generated by the boat speed and heading over the ground
. And this is where it can become tricky.
You need the True North
for any further computation, but what you have on board is a compass, showing you its Compass' North
- The True North is the North of the charts
- Between the True North and the Magnetic North is the Magnetic Declination (D), that varies with the date and the location
- Between the Magnetic North and the Compass' North is the Compass' deviation (d), generated by the magnetic masses on board. It depends on the boat, and on its heading. You have on board a deviation curve that tells you the value of the deviation based on your heading.
- The algebric sum of the deviation and the Declination is called the Variation, noted W.
- Once you have the True Heading, you need to get the Course Made Good, by adding (or substracting) the leeway to it. The leeway is generated by the wind and waves, it has to be estimated by the navigator. The leeway is an angle.
- And between the Course Made Good and the Course Over Ground, is the current. As seen above, the current is a vector (not an angle).
It is not
possible to come up with an accurate computation of the current without
the right estimation of the leeway.
In theory, the current could be calculated by triangulation - like the true wind from the apparent Wind.
In practice, it is much more accurate over time.
On the figure above:
- The left pane shows the triangulation
- The middle pane compares the Course Over Ground (from the GPS) and the estimated position based on all the parameters above on a 1 minute period
- The right pane compares the Course Over Ground (from the GPS) and the estimated position based on all the parameters above on a 10 minute period
The experience does prove that the estimation on a several minutes period is much more accurate than the triangulation, mostly because of the movements of the boat, that impact the data read by the wind vane.
embarqued electronic station can come up with a right evaluation of
- The compass' deviation
- The leeway
- The current
Being able to compute
those data, and then inject
them in the NMEA stream is a real asset (current will be
- Set and Drift). The Raspberry PI is perfectly equiped to take care of all that, and for a ridiculous energy comsumption.
Hint: What to calculate True Wind with?
This would seem obvious to some, but absurd to others. That's why we have this small explanation here.
For years, it was admitted that the true wind should be calculated with the C
ood (CMG), the A
ngle (AWA), A
peed (AWS), and B
eed (BSP). The AWS and AWA are returned by the wind vane and anemometer, BSP by the speedometer (BSP is also called S
ater (STW)). The elaboration of the CMG is not trivial, as explained just above.
The reason for that is probably because this is all we had at that time.
But picture that (and draw a sketch if needed):
You are "sailing" in no
wind at all
(like in the San Francisco Bay in winter), and a 5 knot current is taking you out of the Bay (or inside, or wherever).
BSP is zero, T
peed (TWS) is zero too, and in this case, AWS would be the speed of the current (5 knots), the AWA will depend on (but be equivalent to) the direction the current is taking you to.
If you calculate the TWS based on BSP, CMG, AWA and AWS, you will find a TWS equal to AWS - which is wrong because there is no wind
, and a wrong TWA (and T
irection (TWD) as well, no wind has no direction).
, if you replace BSP with S
round (SOG), and CMG with C
round (COG), you are back in business; COG is the current direction, SOG is the current speed.
Think about it.
This obviously requires the knowledge of SOG & COG, returned by a GPS.
When the boat is moving, that eventually means that an accurate TWA and TWS (and TWD) is elaborated by a accurate knowledge of
In short: this is not trivial. At all, by far, mostly because of CMG (see above for details).
You will notice that in the Console, you have the possibility to compute the True Wind from (BSP, CMG), or from (SOG, COG). This way you can have an idea of the difference it generates...
More about TCP...
There is this Android soft, SeaWi, that can consume the TCP feed without any question.
Above is a replay of a trip between Nuku-Hiva and Rangiroa...
We've been talking about the Raspberry PI here. Why not other boards?
There are indeed many such boards already available, and new ones show up almost every day.
The criteria to choose the right board for your project could be - among others:
As of now (2015), a Raspberry PI B (and B+) costs less than $40. A Raspberry PI A (and A+) comes for less than $30.
- The price
- The energy consumption
- The power of the board (CPU, memory)
- Network connectivity
- Openness and Extensibility
- ... and all this kind of things.
An Arduino Uno is less than $20 (and this is a great board, probably the one that started all this), but to get the network, you need an extra shield that you will get for another $20. And the Arduino Uno has 32Kb of memory (yes, Kb, this is not a typo).
The BeagleBone is more powerfull than the Raspberry PI, but also more expensive.
The Raspberry PI comes with Linux and Java (both free and OpenSource). It has the GPIO Header we need for extensibility.
It does indeed seem to be the right choice for this project, mostly because of its memory, CPU, and connectivity capabilities. Even the Raspberry PI A+ (which I just tested) works just great. It comes with 256Mb of RAM, it has no Ethernet port, and just one USB port. The energy consumption is even lower than on the Raspberry PI B. And it is even smaller.
- About the CPU and memory
It is interesting to remind the youngests of us that 25 years back, I was working with a desktop that had 25 Mb of RAM (yes, about 10 times less than the Raspberry PI Model A). And this was a huge machine. At that time, programming skills included saving (and reusing) memory. That is a skill to keep alive in this area.
The B+ and A+ models use a micro-SD Card, very small in size (the actual challenge is not to lose it), not in capacity.
Here is a screenshot showing
top running on the Raspberry PI A+, with all the features above running, including the WebSocket server (nodejs).
My favorite configuration today (Jan-2015) would definitely include
Top at work
This being said, any Raspberry PI currently available would fit, as well as Banana PI, BeagleBone, Olimex, etc.
I believe that the Raspberry PI A+ is the one drawing the smallest amount of energy, among all the boards running Linux & Java (correct me if I'm wrong). Any board running Java (on Linux or not), and able to connect to a network will do the job.
- A Raspberry PI A+
- A USB Hub (for NMEA input, wireless dongle, wireless keyboard)
- A small breadboard on the side, for extra I2C sensors
One of my goals here was to save as much energy as possible.
Monitor the JVM
The Java Virtual Machine (JVM) comes with several tools, including
jconsole, that allows you to see what is going on regarding the resources, so you can tune the JVM's parameters.
jconsole utility lets you monitor a remote JVM. Run it from another box, like the one you develop on.
You need to add the following parameters when starting the JVM to monitor (i.e. on the RPi):
JAVA_OPTIONS="$JAVA_OPTIONS -Dcom.sun.management.jmxremote.port=1234 \
The port and the hostname need to match your environment, of course.
The other parameters should make sense, to whom it may concern...
New setting (Apr-2015)
I reworked the setting of the Raspberry PI on board. I got rid of the cigarette-lighter socket for the 12v-5v conversion.
I built a small voltage regulator, as explained here, and put everything on the same plexiglass board.
The voltage regulator
The new setting
In the boat
By default, the NMEA Serial port is connected on the laptop.
- Whatever program that needs to read the Serial port will have to wait for the port to be available.
- Whatever data is not emited by the NMEA station is just not available
With the Raspberry PI in the picture, the NMEA Serial port in read by the Raspberry PI. Other devices will use another protocol to reach the data (TCP, UDP, etc).
- Several programs, running on several devices, can use the NMEA data simultaneously
- Sensors can enrich the NMEA Stream (read by the devices and programs mentioned above)
- Extra data can be computed, and injected into the NMEA Stream
The pdf documentation of the NMEA Console (included in the Navigation Desktop) can be found here.
Originally, the software (the NMEA Console) was written to run on a laptop.
Putting the Raspberry PI in the picture substancially changed the paradigm, the architecture clearly became hub-and-spoke oriented.
The cache architecture was also quite impacted. An easy way around the problems raised by this hub-and-spoke architecture is to generate new NMEA Strings from the Raspberry PI, and inject them into the NMEA Stream. This is the case for the Atmospheric Pressure, the True Wind computation, the Current computation (with time buffer), and the list is not closed.
For the data that do not have an NMEA equivalent (like the battery load), I just came up with my own ones. All it requires is to have the software reading them to be aware of those (like the character console).
All the software used here is Open Source software, and as such, is free.
The hardware follows the same path (beside the boat itself, of course, and the NMEA electronics), the price for a Raspberry PI is ridiculous, the extra sensors, boards, small keyboards, small screens, and various components you would need to do the same will fit more than once in a $100 budget.
It is interesting though, to notice that this architecture is the exact same one that was used during the recent 34th America's Cup by those multi-million$ fantastic cats - including the glorious winner.
Well, now you can get to the data, you have to analyze them. And the next America's Cup is all yours.
Oliv fecit, AD 2014, 2015.