July 1, 2019  Trigonometry and encryption in the Bridge

Firmware 1.30 offers trigonometric functions and constants, and allows distribution of protected programs and "locked" devices.

Math functions

Let's start from the simple things. New math functions and constants (see the picture above) allows creation of programs to manage autopilots and calculation of wind, drift, VMG, distance between waypoints, etc. The trigonometric functions accept arguments in radians.

Below is an example of a program (download the code) that calculates TWA, TWS and TWD (theoretical wind angle, speed and direction) using AWA/AWS (apparent wind angle and speed) and COG/SOG data. It receives and sends data from/to a CAN1 interface, so the CAN2 interface can be left unconnected.

The program looks big, but it actually takes up about 4% of the available memory. You can create programs 25 times bigger!

# Calculate TWS, TWD and TWA (teoretical wind) by COG/SOG and AWS/AWA
# (c) 2019, Yacht Devices Ltd. Version 1.1, 29/06/2019
# Byte code size is 660 bytes (4% of user program space)


	# T = 0 # No COG/SOG data, but all variables are 0 at start
	M = 0 - 1.0 # Float -1.0

# COG & SOG, Rapid Update
	R = get(DATA+1,UINT8) & 0x3 # True Reference = 0
	A = get(DATA+2,UINT16) # Course Over Ground, 0.0001 rad/bit
	B = get(DATA+4,UINT16) # Speed Over Ground, 0.01 m/s
	if (R == 0) {
	  if (A < 0xFFFD) {
	    if (B < 0xFFFD) {

		T = timer() # Timestamp of COG/SOG data
		C = cast(A,FLOAT) / 10000 # COG, to radians 
		S = cast(B,FLOAT) / 100   # SOG, m/s 

# Wind Data
	R = get(DATA+5,UINT8) & 0x7 # Apparent Wind = 2
	W = get(DATA+1,UINT16) # Wind speed, 0.01 m/s
	A = get(DATA+3,UINT16) # Wind direction, 0.0001 rad/bit

	# Have valid apparent wind data?
	if (R == 2) {
	   if (A < 0xFFFD) {
	      if (W < 0xFFFD) {

		# Have actual COG/SOG data (2000 ms)
		if (T > 0) {
		   if (timediff(T) < 2000) {

			# TWD calculation when no speed or TWS is about zero
			A = cast(A,FLOAT) / 10000 # Wind angle
			Y = C + A # TWD=COG+AWA

			if (S == 0) {

				X = W # TWS is equal to AWS when no speed
			else {
				W = cast(W,FLOAT) / 100   # Wind speed, float

				# Calculate TWS
				U = sqrt(W*W + S*S - 2*W*S*cos(A))
				X = cast(U*100,UINT16)	# 0.01 m/s per bit

				# Calculate TWD
				if (X != 0) {

					F = (S*S + U*U - W*W) / (2 * U * S)
					# Possible possible rounding issue
					if (F < M) {
						F = M
					F = M_PI - acos( F ) # M_PI is 3.14... constant
					if (A > M_PI) {
						Y = C - F
					else {
						Y = C + F

			# Check is TWD in 360 degrees
			if (Y > M_2PI) {  
				Y = Y - M_2PI # M_2PI is 2*PI constant, M_PI2 is PI/2
			if (Y < 0) {
				Y = Y + M_2PI

			# Calculate TWA and check the range of value
			Z = Y - C
			if (Z < 0) {
				Z = Z + M_2PI

			# Transform to NMEA 2000 resolution, 0.0001 rad/bit
			Y = cast(Y*10000,UINT16)  
			Z = cast(Z*10000,UINT16)  
			# Theoretical Wind (ground referenced, referenced to True North; 
			# calculated using COG/SOG) - TWD/TWS
			set(DATA+5, UINT8, 0xF8) # Data type
			set(DATA+1, UINT16, X) # TWS
			set(DATA+3, UINT16, Y) # TWD
			# Send message to the same interface, using the address
			# of the wind sensor

			# Theoretical (Calculated to Centerline of the vessel, refernced
			# to ground; calculated using COG/SOG) - TWA/TWS
			set(DATA+5, UINT8, 0xFB) # Data type
			set(DATA+3, UINT16, Z)   # TWA

# End of program

To test the program, you can use the CAN Log Viewer and our NMEA 2000 Wi-Fi Router YDNR-02. We'll send COG/SOG and AWA/AWS data from the CAN Log Viewer and check the results in Web Gauges.

In the routing rules of YDNR-02, turn on the routing from the server with CAN Log Viewer to Server #1, which is used for Web Gauges. This will allow you to see source data (sent from CAN Log Viewer) along with output data (sent by the Bridge).On the "NMEA Settings" page of YDNR, you also need to set wind calculations to "Any" (factory setting) or "COG/SOG". The YDNR will not actually calculate the theoretical wind if it is available on the NMEA 2000 network; it will use the data from the network. However, if you will set calculations to "Disabled", it will use theoretical wind data calculated using the STW/Heading to convert theoretical wind from NMEA 2000 to NMEA 0183.

Sending messages form CAN Log Viewer

Figure 1. Sending messages form CAN Log Viewer

Copy and paste messages from the table below to the CAN Log Viewer (see Figure 1) and send to the network.

Table 1. Test data for the program

TestSource messagesSource dataBridge's output
09F802A3 FF FC 39 14 E8 03 FF FF
09FD0205 A7 E8 03 38 14 FA FF FF
COG 30°, SOG 10 m/s
AWS 10 m/s, AWA 30°
TWS 5.1 m/s
TWA 104.8° TWD 134.5°
09F802A3 FF FC 39 14 E8 03 FF FF
09FD0205 A7 E8 03 FC E0 FA FF FF
COG 30°, SOG 10 m/s
AWS 10 m/s, AWA 330°
TWS 5.2 m/s
TWA 255° TWD 284.7°
09F802A3 FF FC 39 14 E8 03 FF FF
09FD0205 A7 00 00 FC E0 FA FF FF
COG 30°, SOG 10 m/s
AWS 0 m/s, AWA 330°
TWS 10 m/s
TWA 180° TWD 209.7°
09F802A3 FF FC 00 00 E8 03 FF FF
09FD0205 A7 E8 03 FC E0 FA FF FF
COG 0°, SOG 10 m/s
AWS 10 m/s, AWA 330°
TWS 5.2 m/s
TWA 255° TWD 255°
09F802A3 FF FC E0 FA E8 03 FF FF
09FD0205 A7 E8 03 FC E0 FA FF FF
COG 330°, SOG 10 m/s
AWS 10 m/s, AWA 330°
TWS 5.2 m/s
TWA 255° TWD 330°
09F802A3 FF FC 00 00 E8 03 FF FF
09FD0205 A7 E8 03 AE 1E FA FF FF
COG 0°, SOG 10 m/s
AWS 10 m/s, AWA 45°
TWS 7.7 m/s
TWA 112.5° TWD 112.5°

The best way check the results is to configure Web Gauges in the way shown in Figure 2, you will see input and output data on the same page.

Web Gauges with wind data (Test 1)

Figure 2. Web Gauges with wind data (Test 1)

And, of course, you can use the log() function for deep debug of the program.

This year we have served several customers who have created very complicated programs for the Bridge, use proprietary protocols and have non-disclosure obligations. To meet their requirements, we added encryption to the Bridge.

Please, read the following carefully, or you can lock your Bridge forever!

Table 2. The PASSWORD_LEVEL key

Bit #
Bit is set (1)
Bit is reset (0)
1Password protection is enabledPassword protection is disabled, all other bits are ignored (will be reset to 0)
2Device's serial is used for encryptionSerial number is not used for encryption
3The program cannot be downloaded from the BridgeEncrypted program can be downloaded from the Bridge
4The Bridge can be reset using the password onlyThe Bridge can be reset by user, the program will be erased

The protection is managed by the PASSWORD (from 1 to 64 symbols) and PASSWORD_LEVEL (values from 0 to 15) settings. If the PASSWORD is empty in the user program, the PASSWORD_LEVEL will be reset to 0 and these settings will not be saved in the YDNBSAVE.CFG file.

To enable password protection, add the following lines to your program:


The YDNBSAVE.CFG with the encrypted program will be saved (see the example). After that, the Bridge will only accept programs encrypted with the password "abc123". To reset the Bridge, load the configuration file with a special comment:


Then, turn on the "maximum protection":


The YDNBSAVE.CFG will contain a message that the program is locked and cannot be downloaded. Because you set bit 4 (15 is 8+4+2+1, all bits are set), you can reset the Bridge with the original password only. You will need to load the configuration file:

   # YD:RESET abc123

We do not publicize the encryption algorithm, but you can be certain that a software attack will be more expensive than hardware attack. If the Bridge is protected, there is no way to restore the password or save unencrypted program.

How you can use this feature:

  • you can re-sell Bridges with the user program protected from unauthorized access or modification, and you can distribute encrypted updates to your users;
  • if the bit 4 is set, the Bridge cannot be reset by the user and can be used only with your own programs;
  • if the bit 2 is set, you will need to generate individual updates for your users, but you will have the opportunity to sell individual updates and prevent unauthorized distribution of updates;
  • bit 3 increases protection, the user can check with the LED signals whether the received update has successfully uploaded to the Bridge or not.

To generate programs for end-users, we added one more key, PASSWORD_SERIAL, it must contain the serial number (eight digits) of the target device. This key is not stored in the YDNBSAVE.CFG file and used for its generation only. If bit 2 is not set in the PASSWORD_LEVEL, you can use any valid number (for example, 00000000), because the serial number will not be used in the encryption. If the key is set, PASSWORD and PASSWORD_LEVEL will be reset after YDNBSAVE.CFG file generation, and you will not need to reset your Bridge after generation of each encrypted program.

When bit 2 is set, and PASSWORD_SERIAL key is not present, the Bridge will use the serial number of your own Bridge to encrypt the YDNBSAVE.CFG file.

Knowledge of the password allows to reset the Bridge, but does not allow decryption of the program. Therefore, you can ask the end-user to send you the serial number and any password he or she likes. Then, you need to send back the usual YDNB.CFG with PASSWORD and PASSWORD_LEVEL settings (1 or higher), to switch the Bridge to protected mode. Another YDNB.CFG with the protected program is generated with PASSWORD_LEVEL set to 3 or higher value. You can be sure that the program you send will be used with the customer's Bridge only.

The PASSWORD_LEVEL setting allows setting of protection bits (increases the protection), but not to reset bits. The only way to reset bits (decrease the protection) is to reset the Bridge along with erasing the user program.

The update for 1.30 is available in the Downloads section. To learn more about the NMEA 2000 Bridge, visit the product's home page. The User Manual will be updated soon.


Next articles:

Previous articles:

See also: recent news, all news...