Compass and inclination sensor

The OpenPlotter comes with support for the 9250 MPU board which connect with the usual I²C bus. The 9250 is a remarkable chip, accelerometer (x,y,z axis), Gyro (x,y,z) and a magnetic compass (x,y,z), a total of 9 axis as they claim. Documentation are available and here. Common practice is to place the fluxgate compass in the middle and at the bottom of the boat, maybe also a bit forward, away from the engine. If this practice is to be followed a long cable is needed. This is easy done using an I²C bus extender. See infro in another page in the list on the left.

The picture on the left show a waterproof box containing the 9250 MPU with a I²C bus range extender chip installed. With the range extender the range can be several tens of meters, see the I²C range extender on the list to the left. I have used a cost effective alternative version of the 9250 MPU from Aliexpress.

This one of the few sensors connected to the Raspberry yacht computer by cable, most other sensors are using the IoToB (Internet of Things on Board) approach and send the SingnalK message string over wifi.

Connecting to the RPi must be done through a little board containing the I²C range extender chip, otherwise it's only SCL and SDA in addition to power (3.3V) that is needed.


An electronic compass is an integral part of any navigation system. The microchip HMC5883L is triple axis magnetometer with an I²C bus interface. It comes on a small evaluation board and is easy to interface to the Pi. It require 3.3V power and two wires for the I²C bus. Only drawback is the fact that the I²C is not supporting long cables. The magnetometer should sit midships and down below. Placing electronics down below is generally a not a good idea. In case of even the smallest flooding all electronics below the floor will be knocked out unless it totally waterproof. Maybe the magnetometer is an exception. The problem with long cables can be overcome with a chip that extend the I²C connection. With a couple of these chips the I²C bus can be extended to tens of meters, see this project page.

Before any practical usage of the magnetometer the directions and output must be calibrated so that a sensible bearing can be calculated. Below is shown a calibration

curve showing the x and y axis output from the magnetometer. This curve is obtained by rotating the magnetometer 360 degrees and recording the X and Y outputs, the inclination of the magnetic field is not taken into account and will mess up the picture. However, close to the magnetic poles this can be quite interesting as the magnetic field lines curve inwards and at some point become more or less perpendicular to the earth's surface. At these places the magnetic compass becomes practically useless. Luckily very few yachts venture into these waters. For most of us we can always assume the magnetic field lines are parallel to the water surface and hence a magnetic compass works well. Errors like magnetic variation and deviation are Yachtmaster curriculum and assumed well known. There are software, also build into OpenCPN as a plug in, that have models of the world magnetic variation. This is the easy part. The deviation is specific to every yacht and placement of the magnetometer. A deviation chart need to recorded and a model of the deviation need to be recorded and integrated into the compass software.

In addition to magnetic bearing (inclination is also measured) the heel angle of the boat is also quite nice to collect and display.

We all know the old fashion pendulum inclinometer. Today we can do this electronic with a gyro chip, MPU6050. This gyro chip measure angles and acceleration in all three directions (x,y,z). We are mostly interested in the heel angle and this is easily collected. The software for this is readily available with a simple search. I have used code found on various sites. I use Python3 code and Python modules for most of the sensors are readily available.The code for the magnetometer are found at "Connecting and calibrating a HMC5883L Compass on the Raspberry Pi" and for the gyro are found at "Reading data from the MPU-6050 on the Raspberry Pi".


The output from the compass chip contain noise and changes quite rapidly. In order to dempen the reponse somewhat a Kalman filter might be applied. This dampen the response a little bit and make the reading much more stable. Imaging a number fluctating plus minus 5-10 degress per second, this a dampen to a smooth change and stabke when the signal should be stable.

A simple code to perform this operations is given below:

from pykalman import KalmanFilter

import numpy as np

import smbus

import time

import math

bus = smbus.SMBus(1)

address = 0x1e

def read_byte(adr):

return bus.read_byte_data(address, adr)

def read_word(adr):

high = bus.read_byte_data(address, adr)

low = bus.read_byte_data(address, adr+1)

val = (high << 8) + low

return val

def read_word_2c(adr):

val = read_word(adr)

if (val >= 0x8000):

return -((65535 - val) + 1)


return val

def write_byte(adr, value):

bus.write_byte_data(address, adr, value)

write_byte(0, 0b01110000) # Set to 8 samples @ 15Hz

write_byte(1, 0b00100000) # 1.3 gain LSb / Gauss 1090 (default)

write_byte(2, 0b00000000) # Continuous sampling

def bearing():

x_out = (read_word_2c(3) - x_offset) * scale

y_out = (read_word_2c(7) - y_offset) * scale

z_out = (read_word_2c(5)) * scale

br = math.atan2(y_out, x_out)

if (br < 0):

br+= 2 * math.pi

return math.degrees(br)

scale = 0.92

x_offset = 71.5

y_offset = -223.0




for j in range(SIZE):





while True:



j= j+1 if j<(SIZE-1) else 0


brs="Bearing: "+'{:03.0f}'.format(br)+"\u00b0"