Content
- Introduction
- Software
The Aanderaa Weather Station (AWS) onboard RV "Håkon Mosby" consists of Mod. 3010 Sensor
Scanning Unit hooked up to a DOS PC that runs a modified version of the Mod. P3081 Data Display Program. This program was made in 1989
and presents data in a tabular fashion on a single screen. There is no output of data from this PC. The GUI (?!) is like this:
Fig. 1. BEFORE: Screenshot of data presentation from Aanderaa Mod. P3081 Data Display Program (1989, modified for vessel useage).
These improvements were needed:
- Being able to watch weather data from several networked locations, preferably using a browser.
- Present data as graphs, with last 24-h data.
On the OBS-2003 survey we had some spare time as all instrumentation systems behaved very nicely. So we decided to update the AWS.
This is a short account of software that was written. Note that the software is a bit alpha and should be made less fragile when
time permits. Code danger areas are marked by comments. It was sort of a speed hack competition, taking some shortcuts.
Please email improvements and bug reports to ole.meyer at geo.uib.no. Have tried to stick to the Unix idea of splitting the task
into smaller units instead of creating a single monster application.
The result is this web page:

Fig 2. AFTER: Screenshot of prototype new web AWS interface, as part of vessel position/weather status page (click
for larger version).
On the right there are plots of last 24h barometric pressure and wind speed values. Plots showing other parameters from
the AWS can easily be added. The map on the left continuously plots the ship's current position (yellow star), with ship's
speed and course shown as a vector together with a 24h trackline (yellow). The OBS survey line that is active at the time
shown in red, with OBS positions marked with crosses.
Weather information is available every 10 minutes. The map is redrawn every minute. The web page is refreshed every 30 sec.
Software listings - with line numbers and syntax colour highlighting.
The software runs on a RedHat 9.0 Linux PC. Referring to the GREEN
boxes in figure 3 below, it comprises:
- aanderaa.c
: A standard C part that
- Collects serial raw data from the Mod. 3010 Sensor Scanning
Unit.
- Computes sensor values in engineering units based on coefficients stored in parameter file.
- Collects UDP telegrams from a shared memory segment; these telegrams holds information on ship's heading, in order to compute
true wind direction and speed. (The UDP telegrams are picked from the network and written to shared memory by another program.)
- Sends NMEA formatted data (ASCII strings preceeded by $PSHWEA) to standard output, allowing file redirection upon program
invocation.
- aanderaa.sh
: A shell script running a loop that
- Collects data sets for the last 24 hours from the file
holding the NMEA formatted weather telegrams.
- Feeds these data to Gnuplot, the program that makes the
graphs.
- Gnuplot outputs png-formatted images directly to the
correct position in the web three.
- read_udp.c
: A program that collects UDP telegrams from the network. These telegrams holds info on ships heading and position. Data is placed in
shared memory area for use by the aanderaa.c program.
- gmt-ex1.sh
: A shell
script running a loop, plotting - once a minute - a map consisting of these layers (using GMT
Generic Mapping Tools):
- Land area
- Cities, reading from file
- Current position of ship
- Ship's speed and heading, as a vector (arrow with direction; length representing speed)
- Current line in red, reading from file
- Last 24 hour positions in yellow

Fig. 3. Software block diagram.
# Aanderaa Weather Station onboard RV "Haakon Mosby"
# Parameter file
# OM, June 5, 2003
#
# Value = A + BN + CNexp2 + DNexp3
# where N is raw data, of 10 bit resolution [0..1023]
# Comments or empty lines MUST start with '#' in first coloumn
#
#--------------------------------------------------------------------------------------------------
# Ch Description Calculations Coefficients Units Format
# '_' -> space max min avr A B C D
#--------------------------------------------------------------------------------------------------
#
1 Reference 0 0 0 0.000E+00 1.000E+00 0.000E+00 0.000E+00 counts 4:0
2 Rel.wind_speed/ship 1 1 1 0.000E+00 7.460E-02 0.000E+00 0.000E+00 m/s 4:1
3 Rel.wind_dir./ship 0 0 1 1.500E+00 3.490E-01 0.000E+00 0.000E+00 deg. 4:0
4 Ship_speed 1 1 1 0.000E+00 1.543E-02 0.000E+00 0.000E+00 m/s 4:0
5 Heading 0 0 1 0.000E+00 1.000E+00 0.000E+00 0.000E+00 deg. 4:1
6 Air_Pressure 1 1 1 9.053E+02 1.927E-01 0.000E+00 0.000E+00 mB 5:1
7 Air_Temperature 1 1 1 -4.386E+01 8.118E-02 9.432E-06 0.000E+00 deg.C 4:1
8 Relative_Humidity 1 1 1 -1.222E+00 1.019E-01 0.000E+00 0.000E+00 %RH 4:0
9 Sea_Temperature 1 1 1 -6.453E+00 3.702E-02 -1.655E-05 4.931E-09 deg.C 4:1
10 True_wind_speed 1 1 1 0.000E+00 1.000E+00 0.000E+00 0.000E+00 m/s 4:1
11 True_wind_direction 0 0 1 0.000E+00 1.000e+00 0.000E+00 0.000E+00 deg. 4:1
|
Don't try to change sensor sequnce - the aanderaa.c makes certain assumptions, see the program. Code improvement
could be to let the configuration file determine sensor sequence. Anyhow, the Mod 3010 Sensor Scanning Unit wouldn't like
this either - the manual says you should keep this sensor sequence ...
Parsing of the parameter file depends on the sscanf function in c. This function is very picky when it comes to format
correctness. If you alter any parameters you must ensure that the format given above is preserved. Don't forget '_' in
sensor descriptions, if you do the aanderaa.c will go down in flames, not a pretty sight ... So making parameter file
reading more robust should be added to the TO-DO list.
BTW, the parameter file was present on the Aanderaa DOS PC - only got this information too late.
This program consists of these parts.
- Initialization:
- Installing a custom <CTRL>+<C> handler in order to terminate program in an orderly manner with regard to shared
memory.
- Setting up shared memory using definitions in the file 'shared_memory_common.h'
- Reading and parsing parameter file 'aanderaa.conf'. Parameters stored in an array of structures called 'par_list[]' (note:
indexed from zero).
- Setup serial port that gets data from Mod. 3010 Sensor Scanning Unit.
- Starting two threads, one handling Aanderaa serial data reception, the other reading UDP telegrams (that, among other
things, holds information on ship's heading which is used to compute true wind speed and direction).
- Thread A: Collect serial data from Mod. 3010 Sensor Scanning Unit. This is just a couple of lines. First get rid of excess <LF>s -
the 3010 seems to terminate lines by two <LF>, that's odd isn't it? Then check the string length so that we don't start processing
incomplete telegrams - could easily happen if program was started when the 3010 sends data, this takes several seconds. If telegram of proper
length is detected, set flag so that main loop can start processing.
- Thread B: Collect UDP telegrams transferred via shared memory from other program. Also just a couple of lines. We're looking for two
types of NMEA telegrams: $GPRMC and $GPHDT. Ship's heading information in the $GPHDT telegram is used to calculate true wind speed
and direction; the other piece of information needed to perform this calculation is the ship's speed, which is obtained from the 3010
Sensor Scanning Unit itself (one of the sensor inputs seems to be connected to a pulse speed log). To be correct one should also take
the difference between ship's heading and course into account - the latter is available in the $GPRMC telegram. Later, perhaps ...
If any of these two telegrams are detected (by checking flags in the shared memory structure), the main loop is informed that UDP
telegram can be parsed.
- Main loop.
- If UDP telegrams available, start parsing
- Likewise, if Aanderaa data available, start parsing and
processing. First convert from raw data (10-bit numbers in the
range [0..1023]) to values in engineering units, applying
coefficients previously read from the parameter file. Results
stored in array of floats, called 'converted[]', indexed from
zero. If fresh UDP telegrams available - testing a flag called
'UDP_alive' that is currently not implemented, it's always TRUE! -
then first convert UDP time and data information to a format that
suits Gnuplot, then start computing true wind speed and direction.
From the 3010 wind direction is given relative to ship's bow, and
wind speed is also relative to ship's own movement. Express
relative wind speed/direction and ship's speed/heading as vectors
(ship's heading zero, until next stage), and calculate
"intermediate" true wind speed/direction as a vector
subtraction. The vector stuff is done using complex numbers. After
that compensate for ship's heading and check and correct true wind
direction angle. (Could be errors here, only limited testing, but
it looked good so far.) Last, format output string.
Example from the file aanderaa.dat:
$PSHWEA,MOSBY,13:03:29,2003-06-13,A,1011.5,5.6,71.4,8.5,5.1,338.9,Y*
$PSHWEA,MOSBY,13:13:29,2003-06-13,A,1011.3,5.6,71.0,8.5,5.0,327.4,Y*
$PSHWEA,MOSBY,13:23:29,2003-06-13,A,1011.3,5.7,71.0,8.6,6.1,351.6,Y*
|
Field no |
Example |
Description |
1 |
$PSHWEA |
P = proprietary, SH = ship, WEA = Weather data |
2 |
MOSBY |
Ship name |
3 |
13:03:29 |
Time [hh:mm:ss] |
4 |
2003-06-13 |
Date [yyyy-mm-dd] |
5 |
A |
L = PC clock, not necessarily corrected by NTP -
must be checked. See comments in file header.
A = Time received from UDP telegrams over the network. UTC. |
6 |
1011.3 |
Barometric pressure |
7 |
5.7 |
Air temperature |
8 |
71.0 |
Relative humidity |
9 |
8.6 |
Sea temperature |
10 |
6.1 |
True wind speed |
11 |
351.6 |
True wind direction |
12 |
Y |
If "Y", true wind speed/direction are
valid. "N" they are not valid as UDP telegrams are
missing .. |
|
* |
End of line indicator. Could later add checksum ... |
#!/bin/bash
# Aanderaa Weather Station: Plot last 24 hour values using gnuplot
while [ 1 ]
do
tail -n 144 aanderaa.dat | awk -F "," '{print $3, $4, $6, $10}' > last-24h.dat
gnuplot barometer-png.gplot > /var/www/html/mosby/barometer.png
gnuplot windspeed-png.gplot > /var/www/html/mosby/windspeed.png
sleep 60
done
|
This is running an endless loop with an embedded 60 second sleep. Get readings from the last 24 hours (144 lines - assuming 10 minute
sampling interval on the 3010 Sensor Scanning Unit, yielding 6 * 24 = 144). Extract time, date, barometric pressure and wind speed
- the "print $3, $4, $6, $10" stuff in awk - and put this into a file. Then make two calls to Gnuplot; see description of Gnuplot
command files below.
set xdata time
set timefmt "%H:%M:%S %Y-%m-%d"
set format x "%d%b\n%Hhr"
set title "BAROMETRIC PRESSURE"
set ylabel "Barometric pressure [mBar]"
set xlabel "Time [UTC]"
set yrange [990:1025]
set xtics 21600
set mxtics 6
set grid
# Color sequence: Background, axis (all), grids, curve (add for more line types)
set terminal png small notransparent color xdcdcdc x000000 xaaaaaa x0000ff
set size 0.55,0.55
plot "/home/aanderaa/last-24h.dat" using 1:3 with linespoints -1
|
Comments:
- Note how you must instruct Gnuplot to plot time series, specifying the time format with "%H:%M:%S %Y-%m-%d".
The x-axis annotation is given by the 'set format x "%d%b\n%Hhr"' where '\n' means new line.
- Major x tics every 6 hour; "xtics" is in seconds (21600 = 6 hours), and minor tics has 6 divisions
- The png terminal mode is set, together with some plot attributes. Set grey background (RGB = 0xdcdcdc), black grids,
darker grey grids (RGB = 0xaaaaaa) and blue curve (RGB = 0x0000ff). Oops, curve is black, don't know why.
set xdata time
set timefmt "%H:%M:%S %Y-%m-%d"
set format x "%d%b\n%Hhr"
set title "WIND SPEED"
set ylabel "Wind speed [m/s]"
set xlabel "Time [UTC]"
set yrange [0:30]
set grid
set xtics 21600
set mxtics 6
# Color sequence: Background, axis (all), grids, curve (add for more line types)
set terminal png small notransparent color xdcdcdc x000000 xaaaaaa x0000ff
set size 0.55,0.55
plot "/home/aanderaa/last-24h.dat" using 1:4 with linespoints -1
|
Similar, except that another coloumn is selected.
Here is the Gnuplot manual, if your want to make any changes. Gnuplot homepage is here.
Software to read UDP data from the network.
Refer to this web page. Shell script is called gmt-ex1.sh.
|