# Anchor Alarm (simplified), version 1.0 # See: http://www.yachtd.com/news/anchor_alarm.html # # To configure the Alarm Button, send the following sequence of commands: # YD:RESET # YD:MODE DS # YD:LINK 7 SOUND 0 # YD:CHANNEL 7 FW_CAN1_TO_CAN2=OFF FW_CAN2_TO_CAN1=OFF SLOT1 = 000EF20D FF 08 00FDFFFFFFFFFFFF # Turn ON the the anchor alarm (Channel 1) SLOT2 = 000EF20D FF 08 00FCFFFFFFFFFFFF # Turn OFF the the anchor alarm SLOT3 = 000EF20D FF 08 0003C0FFFFFFFFFF # Turn off all channels, except Channel 1 # We'll run/stop the alarm once in 3 seconds to avoid fast switches heartbeat(3000) { if (D > 0) { # Alarm is set (D is the safe distance in meters) if (R > D) { # R is distance to D from current GPS position load(SLOT1) # Anchor alarm on M = 1 # Mark, that alarm was ON by the Bridge } else { load(SLOT2) # Anchor alarm off M = 0 # Alarm was OFF by the Bridge } send(CAN1) } } # Position, Rapid Update - calculate the distance from current position match(CAN1,0x1F80100,0x1FFFF00) { if (get(DATA,INT32) < 0x7FFFFFFF) { if (get(DATA+4,INT32) < 0x7FFFFFFF) { X = get(DATA,INT32) # Latitude, 0.0000001 deg Y = get(DATA+4,INT32) # Longitude, 0.0000001 deg T = timer() # Position is valid, save the time of position fix R = 0 # Reset the distance from current position if (D > 0) { # Is the alarm already set? # Calculate the distance by Haversine Formula W = (cast(X - A,FLOAT)/10000000) * M_PI / 180 # delta Lat Z = (cast(Y - B,FLOAT)/10000000) * M_PI / 180 # delta Lon W = sin(W/2) Z = sin(Z/2) U = W*W + cos((cast(X,FLOAT)/10000000) * M_PI / 180)*cos((cast(A,FLOAT)/10000000) * M_PI / 180)*Z*Z if (U != 0) { U = atan2(sqrt(U),sqrt(1-U)) R = 12742000*U # The distance to (A,B) in meters } } } } } # Binary Status Report match(CAN1,0x1F20D00,0x1FFFF00) { if (get(DATA,UINT8) == 0) { # Is it Bank 0 message? S = get(DATA+1,UINT16) # Status of Channels 1-8 (2 bit each: 1-ON, 0-OFF) if ((S & 3) != 1) { # Is anchor alarm NOT running? if ((S >> 12) & 3 == 1) { # Is hardware button was pressed (Channel 7 is set) ? if (timediff(T) < 2000) { # Is GPS position valid? if (D == 0) { # Set new alarm A = X B = Y D = 20 # Safe distance in meters } else { # The alarm is already set, canceled by user if (M == 1) { load(SLOT3) # Cancel the alarm send(CAN1) M = 0 D = 0 } } } else { # We have no actual position (GPS lost?) if (D > 0) { # Was the alarm set? if (M == 1) { # Was it canceled by user? load(SLOT3) send(CAN1) # Cancel the alarm M = 0 D = 0 } else { # It was not canceled by user R = 1000 # Run the Anchor Alarm! M = 0 # GPS position is lost! } } else { # User tries to set new alarm load(SLOT3) # Switch off all buttons, do not allow send(CAN1) # to set the alarm without valid position } } } } } } # End of program