Ajouter un checksum NMEA0183 avec OpenPlotter

J'ai rencontré un soucis avec ma girouette. En effet, celle ci étant un modèle assez ancien, elle n'émet pas de checksum.

La longueur du câble étant faible (la communication se fait entre la girouette et la base via un câble coaxial, on va partir du principe que cette connexion est fiable, le nmea étant émis par le boîtier à la base connecté en nmea0183), sur un bus rs422 (Nmea0183), on peut considérer le risque d'erreurs faible (d'autant plus qu'il y a un champ nmea, le dernier, qui indique qui est à A si la donnée est valide).

Cependant, certains logiciels ont besoin d'un checksum et le vérifient. Utilisant OpenPlotter, j'ai donc décidé d'ajouter ce checksum avant arrivée des données sur le bus principal, ce qui est assez simple à faire.

Tout d'abord, il faut fixer le périphérique pour que node-red y accède toujours avec le même chemin. Pour cela, dans openplotter, série, sélectionner l'appareil, puis lui mettre le nom voulu (ici ttyOP_wind), affectation "aucun" (pour pouvoir l'affecter à node-red), puis appliquer. Ici j'utilise l'adaptateur usb-nmea0183 qui a fait l'objet d'un autre article sur le blog, je le mémorise par vendeur/produit (pas d'autre adaptateur avec le même numéro).

Ensuite, ouvrir le navigateur, il y a un raccourcis Node-RED, cliquer dessus.

Sur input, mettre un "serial". Le configurer ainsi:

Sur output, j'ai fait une sortie tcp pour Pypilot (Type: Connect to, port 20220, ip 127.0.0.1), une pour Kplex (Type: Listen On, port 40440 sur lequel je viens ensuite connecter kplex si nécessaire), puis j'ai ajouté un function.

J'ai nommé ce function "Calculate checksum".

Dans la partie code (Function), j'ai mis le code suivant:

var nmea = msg.payload;
var checksum = 0;


var nmea_stripped = nmea.substring(1, nmea.indexOf('\r\n'));

for(var i = 0; i < nmea_stripped.length; i++)
{
    checksum = checksum ^ nmea_stripped.charCodeAt(i);
}


checksum = checksum.toString(16);

padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;

while (checksum.length < padding) {
    checksum = "0" + checksum;
}

msg.payload = '$' + nmea_stripped + '*' + checksum.toUpperCase() + '\r\n';
return msg;

Il suffit ensuite de relier le tout.

Note: on peut aussi se servir de Node-Red en tant que multiplexeur au lieu de Kplex. Il suffit d'ajouter une fonction multiplexeur, qui ne fait rien (juste return msg;), et d'y câbler toutes les entrées et sorties que l'on veut. C'est bien plus fin que Kplex et pratique.