Le projet de pilote automatique : Différence entre versions

De minos2
Aller à : navigation, rechercher
(Déploiement de l'application)
(Vitesse du vent : $GPMWV)
 
(24 révisions intermédiaires par le même utilisateur non affichées)
Ligne 890 : Ligne 890 :
  
 
=== La carte de conversion ===
 
=== La carte de conversion ===
 +
J'ai eu beaucoup de mal à mettre en oeuvre la carte de convertion 4-20mA.
 +
 +
J'ai essayé en premier cette carte , mais elle a été détruite à cause d'une fausse manip.
 +
 
[[Fichier:Current-to-Voltage-Signal-ModuleExemple.png]]
 
[[Fichier:Current-to-Voltage-Signal-ModuleExemple.png]]
  
Ligne 910 : Ligne 914 :
 
  OUT: Signal output connector (0.00V ~ 5.00V).
 
  OUT: Signal output connector (0.00V ~ 5.00V).
 
  G: Power to the ground interface.
 
  G: Power to the ground interface.
 +
 +
La carte ci-dessus a crâmé suite à une fausse manip...:-(
 +
 +
J'utilise maintenant une carte HW-685 (0.86 € chez aliexpress) :
 +
[[Fichier:hw-685.png]]
 +
 +
Le site https://docs.turais.de/docs/modules/hw685/ propose une doc pour le montage de la carte. La page sauvegardée au format pdf se trouve [http://www.minos2.fr/files/HW-685.4-20mA-configuration-documentation.pdf ici]
 +
 +
Description:
 +
 +
Dans le processus de transmission de signal de circuit, le signal de tension s'affaiblira avec l'augmentation de la distance de transmission, et la transmission actuelle peut éviter l'affaiblissement du signal.
 +
* Le module est utilisé pour la fin de la transmission du signal actuel, le signal est converti en signal de tension pour la détection SCM.
 +
* L'entrée de courant prend en charge 4-20mA et 0-20mA, et la sortie de tension prend en charge 0-3.3V 0-5V 0-10V.
 +
 +
Point culminant:
 +
La plage de tension d'alimentation est large et la tension de sortie prend en charge plusieurs plages;
 +
* Zéro et gamme complète peuvent être ajustés automatiquement;
 +
* Haute stabilité, bonne linéarité, qualité industrielle;
 +
* La résistance d'échantillonnage du signal actuel adopte une résistance d'anneau de couleur de haute précision, qui a une haute précision, une petite dérive de température et une puissance élevée
 +
 +
Instruction:
 +
* 1. Le module est connecté selon la définition, la tension d'alimentation est de 7-36V (si la sortie est à 10V, la tension d'alimentation doit être supérieure à 12V)
 +
* 2. Après la mise sous tension, la lumière D2 doit être brillante, sinon veuillez vérifier la connexion de ligne. Carte avec protection de connexion inverse, connexion inverse ne brûlant pas.
 +
* 3. Lorsque l'entrée de courant est minimale (0mA ou 4mA), ajustez le potentiomètre zéro, de sorte que la sortie de VOUT soit minimale (0.0V ou autre tension)
 +
* 4. Lorsque l'entrée de courant est maximale (20mA), ajustez le potentiomètre d'envergure, de sorte que la sortie VOUT soit la valeur maximale (3.3V ou 5V ou 10V, quand l'entrée est 4-20mA, la sortie minimum peut être 2.5V).
 +
 +
Selon vos besoins, sélectionnez la gamme correspondante par bouchon de cavalier:
 +
* 4 -- 20ma:0 -- 2.5V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds connexion courte
 +
Gamme 0-3.3V: J1 1, 2 pieds, 3, 4 pieds
 +
* 0 -- 5.0V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds connexion courte
 +
* 0 -- 10.0V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds off
 +
* 0 -- 20ma:0 -- 3.3V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds connexion courte
 +
* 0 -- 5.0V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds connexion courte
 +
* 0 -- 10.0V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds off
 +
 +
Emballage Inclus:
 +
 +
1 * courant à la tension 0/4-20mA à 0 -10V Module émetteur
 +
 +
 +
Le montage final utilise la carte suivante :
 +
[[Fichier:Convertisseur-de-courant-tension-0-5V-0-20mA-convertisseur-de-tension-courant-Module-de-Signal-I.jpg]]
  
 
=== Le programme ===
 
=== Le programme ===
Ligne 1 010 : Ligne 1 056 :
 
   
 
   
 
http://www.gpsinformation.org/dale/nmea.htm#nmea
 
http://www.gpsinformation.org/dale/nmea.htm#nmea
 +
 +
https://www.junkrigassociation.org/page-1858647 : donne des informations sur les phrases NMEA propriétaires.
 +
 +
==== Syntaxe des trames ====
 +
* $ : délimiteur de début de trame
 +
* GP : trame provenant d'un GPS
 +
* II : Integrated Instrumentation
  
 
==== Les codes NMEA ====
 
==== Les codes NMEA ====
 
All $GPxxx sentence codes and short descriptions (http://aprs.gids.nl/nmea/)
 
All $GPxxx sentence codes and short descriptions (http://aprs.gids.nl/nmea/)
  
 +
    '''$GPAAM''' - Waypoint Arrival Alarm
 +
    '''$GPALM''' - GPS Almanac Data
 +
    '''$GPAPA''' - Autopilot Sentence "A"
 +
    '''$GPAPB''' - Autopilot Sentence "B"
 +
    '''$GPASD''' - Autopilot System Data
 +
    '''$GPBEC''' - Bearing & Distance to Waypoint, Dead Reckoning
 +
    '''$GPBOD''' - Bearing, Origin to Destination
 +
    '''$GPBWC''' - Bearing & Distance to Waypoint, Great Circle
 +
    '''$GPBWR''' - Bearing & Distance to Waypoint, Rhumb Line
 +
    '''$GPBWW''' - Bearing, Waypoint to Waypoint
 +
    '''$GPDBT''' - Depth Below Transducer
 +
    '''$GPDCN''' - Decca Position
 +
    '''$GPDPT''' - Depth
 +
    '''$GPFSI''' - Frequency Set Information
 +
    '''$GPGGA''' - Global Positioning System Fix Data
 +
    '''$GPGLC''' - Geographic Position, Loran-C
 +
    '''$GPGLL''' - Geographic Position, Latitude/Longitude
 +
    '''$GPGSA''' - GPS DOP and Active Satellites
 +
    '''$GPGSV''' - GPS Satellites in View
 +
    '''$GPGXA''' - TRANSIT Position
 +
    '''$GPHDG''' - Heading, Deviation & Variation
 +
    '''$GPHDT''' - Heading, True
 +
    '''$GPHSC''' - Heading Steering Command
 +
    '''$GPLCD''' - Loran-C Signal Data
 +
    '''$GPMTA''' - Air Temperature (to be phased out)
 +
    '''$GPMTW''' - Water Temperature
 +
    '''$GPMWD''' - Wind Direction
 +
    '''$GPMWV''' - Wind Speed and Angle (cf IIMWV)
 +
    '''$GPOLN''' - Omega Lane Numbers
 +
    '''$GPOSD''' - Own Ship Data
 +
    '''$GPR00''' - Waypoint active route (not standard)
 +
    '''$GPRMA''' - Recommended Minimum Specific Loran-C Data
 +
    '''$GPRMB''' - Recommended Minimum Navigation Information
 +
    '''$GPRMC''' - Recommended Minimum Specific GPS/TRANSIT Data
 +
    '''$GPROT''' - Rate of Turn
 +
    '''$GPRPM''' - Revolutions
 +
    '''$GPRSA''' - Rudder Sensor Angle
 +
    '''$GPRSD''' - RADAR System Data
 +
    '''$GPRTE''' - Routes
 +
    '''$GPSFI''' - Scanning Frequency Information
 +
    '''$GPSTN''' - Multiple Data ID
 +
    '''$GPTRF''' - Transit Fix Data
 +
    '''$GPTTM''' - Tracked Target Message
 +
    '''$GPVBW''' - Dual Ground/Water Speed
 +
    '''$GPVDR''' - Set and Drift
 +
    '''$GPVHW''' - Water Speed and Heading
 +
    '''$GPVLW''' - Distance Traveled through the Water
 +
    '''$GPVPW''' - Speed, Measured Parallel to Wind
 +
    '''$GPVTG''' - Track Made Good and Ground Speed
 +
    '''$GPWCV''' - Waypoint Closure Velocity
 +
    '''$GPWNC''' - Distance, Waypoint to Waypoint
 +
    '''$GPWPL''' - Waypoint Location
 +
    '''$GPXDR''' - Transducer Measurements
 +
    '''$GPXTE''' - Cross-Track Error, Measured
 +
    '''$GPXTR''' - Cross-Track Error, Dead Reckoning
 +
    '''$GPZDA''' - Time & Date
 +
    '''$GPZFO''' - UTC & Time from Origin Waypoint
 +
    '''$GPZTG''' - UTC & Time to Destination Waypoint
 +
 +
==== Direction du vent : $IIMWV ====
 +
 +
'''$IIMWV''' est la phrase NMEA pour le vent mesuré par le capteur LCJ CV7.
 +
* II signifie integrated instrumentation,
 +
* MWV pour acoustic wind sensor.
 +
 +
Le format est le suivant :
 +
 +
'''$IIMWV,318.0,R,014.8,N,A*3A'''
 +
 +
* direction du vent en degrés (318.0)
 +
* R = relative or apparent wind,
 +
* vitesse du vent (014.8)
 +
* N = knots, cela peut être K/M/N (Kilometres/hr, M/s, knots)
 +
* A indique le status, “A” indique une mesure correcte, V indique une mesure incorrecte,
 +
* 3D is a checksum.
 +
 +
==== Vitesse du vent relatif (vent apparent) et angle : $GPVWR ====
 +
* $GPVWR donne la vitesse relative du vent et l'angle (vent apparent et l'angle).
 +
 +
Le format :
 +
'''$GPVWR,42.00,L,14.80,N,7.61,M,27.41,K*7B'''
 +
 +
* Direction magnitude en degrés.
 +
* Direction du vent Left/Right of Bow
 +
* Vitesse
 +
* N = Knots
 +
* Vitesse
 +
* M = metres/sec
 +
* Vitesse
 +
* K = Kilometres/hr
 +
*  Checksum
 +
 +
==== Vitesse du vent : $GPMWV ====
 +
'''$GPMWV''' donne la vitesse du vent et l'angle le détail voir [http://www.minos2.fr/wiki/index.php/Le_projet_de_pilote_automatique#Direction_du_vent_:_.24IIMWV $IIMWV]
 +
 +
==== $GPVHW :  vitesse et cap ====
 +
 +
donne la vitesse par rapport à l'eau et le cap.
 +
 +
Le format:
 +
 +
'''$GPVHW,,,,,4.79,N,8.87,K*56'''
  
    $GPAAM - Waypoint Arrival Alarm
+
* cap en degrés vrais.
    $GPALM - GPS Almanac Data
+
* T = True
    $GPAPA - Autopilot Sentence "A"
+
* cap en degrés magnetic.
    $GPAPB - Autopilot Sentence "B"
+
* M = Magnetic
    $GPASD - Autopilot System Data
+
* vitesse (4.79) in knots,
    $GPBEC - Bearing & Distance to Waypoint, Dead Reckoning
+
* N = knots
    $GPBOD - Bearing, Origin to Destination
+
* Vitesse relative à l'eau en Kilometres/hr,
    $GPBWC - Bearing & Distance to Waypoint, Great Circle
+
* K = kilometres,
    $GPBWR - Bearing & Distance to Waypoint, Rhumb Line
+
* checksum.
    $GPBWW - Bearing, Waypoint to Waypoint
 
    $GPDBT - Depth Below Transducer
 
    $GPDCN - Decca Position
 
    $GPDPT - Depth
 
    $GPFSI - Frequency Set Information
 
    $GPGGA - Global Positioning System Fix Data
 
    $GPGLC - Geographic Position, Loran-C
 
    $GPGLL - Geographic Position, Latitude/Longitude
 
    $GPGSA - GPS DOP and Active Satellites
 
    $GPGSV - GPS Satellites in View
 
    $GPGXA - TRANSIT Position
 
    $GPHDG - Heading, Deviation & Variation
 
    $GPHDT - Heading, True
 
    $GPHSC - Heading Steering Command
 
    $GPLCD - Loran-C Signal Data
 
    $GPMTA - Air Temperature (to be phased out)
 
    $GPMTW - Water Temperature
 
    $GPMWD - Wind Direction
 
    $GPMWV - Wind Speed and Angle
 
    $GPOLN - Omega Lane Numbers
 
    $GPOSD - Own Ship Data
 
    $GPR00 - Waypoint active route (not standard)
 
    $GPRMA - Recommended Minimum Specific Loran-C Data
 
    $GPRMB - Recommended Minimum Navigation Information
 
    $GPRMC - Recommended Minimum Specific GPS/TRANSIT Data
 
    $GPROT - Rate of Turn
 
    $GPRPM - Revolutions
 
    $GPRSA - Rudder Sensor Angle
 
    $GPRSD - RADAR System Data
 
    $GPRTE - Routes
 
    $GPSFI - Scanning Frequency Information
 
    $GPSTN - Multiple Data ID
 
    $GPTRF - Transit Fix Data
 
    $GPTTM - Tracked Target Message
 
    $GPVBW - Dual Ground/Water Speed
 
    $GPVDR - Set and Drift
 
    $GPVHW - Water Speed and Heading
 
    $GPVLW - Distance Traveled through the Water
 
    $GPVPW - Speed, Measured Parallel to Wind
 
    $GPVTG - Track Made Good and Ground Speed
 
    $GPWCV - Waypoint Closure Velocity
 
    $GPWNC - Distance, Waypoint to Waypoint
 
    $GPWPL - Waypoint Location
 
    $GPXDR - Transducer Measurements
 
    $GPXTE - Cross-Track Error, Measured
 
    $GPXTR - Cross-Track Error, Dead Reckoning
 
    $GPZDA - Time & Date
 
    $GPZFO - UTC & Time from Origin Waypoint
 
    $GPZTG - UTC & Time to Destination Waypoint
 
  
 
=== La carte d'aquisition des données ===
 
=== La carte d'aquisition des données ===

Version actuelle datée du 9 septembre 2021 à 17:18

Navigation: Accueil -> Le projet de pilote automatique

L'objectif du projet

J'ai eu l'idée et l'envie de concevoir un pilote automatique pour mon bateau basé sur un Raspberry PI et un arduino.

A cette étape j'imagine que le Raspberry sera trop lent pour réagir suffisament vite sur la barre.

J'ai lu quelques articles dans lesquels les formules mathématiques m'ont un peu effrayé.

J'ai donc décidé une approche plus empirique;

Voici le principe général de réalisation du pilote :

L'arduino

Commande du cap

L'arduino aura la tâche d'assurer le cap demandé.

Le cap sera programmé par un clavier équipé de boutons poussoir.

+ 1° - 1° + 10° - 10° auto -> passage en mode pilote automatique standby -> passage en pilotage manuel

Gyroscope, accéléromètre et magnétomètre

L'arduino sera relié à une carte comportant les fonctionnalité suivantes

  • gyroscope
  • accéléromètre
  • magnétomètre

MPU-9250.png

La station météo basée sur un BME280

Le BME280 est un composant qui fournit la température, la pression et l'hygrométrie.

Bme280.jpeg

Pour la programmation je me suis inspiré du site de Gilles Thebault : http://gilles.thebault.free.fr/spip.php?article47 ...merci à lui...!

Le code du programme arduino

Le code ci-dessous effectue les mesures de température, pression et humidité et aussi la lecture des trames du GPS.

#include <SoftwareSerial.h>
#include <Wire.h>
#include "SparkFunBME280.h"

BME280 bme280;
 
//Création de la variable SoftSerial (connexion software au port serie) RX sur le pin D2 et TX sur le pin D3
#define rxPin 10
#define txPin 11

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

//On crée un tableau de caractères qui contiendra notre trame GPS
unsigned char buffer[256];
// On conserve l'heure courante
char heureCourante[10];
//la variable count nous servira à ne pas dépasser les 256 caractères du tableau.
int count=0;   
// On déclenche une mesure de température, pression et humidité toutes les ...
long compteur = 0;
 
void setup() {
  // Initialisation du GPS
  // -----------------------
  //On initialise le port série software 
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  mySerial.begin(9600);

  // Initialisation du BME280
  // ------------------------
  //configuration du capteur
  bme280.settings.commInterface = I2C_MODE; 
  bme280.settings.I2CAddress = 0x76;
  bme280.settings.runMode = 3; 
  /*
      bme280.settings.tStandby = ...

      bme280.settings.tStandby = 0  durée du standby entre 2 mesures 0.5ms
      bme280.settings.tStandby = 1   durée du standby entre 2 mesures 62.5ms
      bme280.settings.tStandby = 2   durée du standby entre 2 mesures 125ms
      bme280.settings.tStandby = 3   durée du standby entre 2 mesures 250ms
      bme280.settings.tStandby = 4   durée du standby entre 2 mesures 500ms
      bme280.settings.tStandby = 5   durée du standby entre 2 mesures 1000ms
      bme280.settings.tStandby = 6   durée du standby entre 2 mesures 10ms
      bme280.settings.tStandby = 7   durée du standby entre 2 mesures 20ms
  */
  bme280.settings.tStandby = 0;
  /*
    bme280.settings.filter = ... (permet de filtrer et supprimer les variations brusques (courant d’air ...))

    bme280.settings.filter = 0  pas de filtrage
    bme280.settings.filter = 1   coefficient de filtrage 2
    bme280.settings.filter = 2   coefficient de filtrage 4
    bme280.settings.filter = 3   coefficient de filtrage 8
    bme280.settings.filter = 4   coefficient de filtrage 16
  
   */
  bme280.settings.filter = 0;
  /*
   *  bme280.settings.tempOverSample = ...

      bme280.settings.tempOverSample=0  pas de mesure de la température.
      bme280.settings.tempOverSample=1   sur-échantillonnage x1. Résolution : 16 bit / 0.0050°C
      bme280.settings.tempOverSample=2   sur-échantillonnage x2. Résolution : 17 bit / 0.0025°C
      bme280.settings.tempOverSample=3   sur-échantillonnage x4. Résolution : 18 bit / 0.0012°C
      bme280.settings.tempOverSample=4   sur-échantillonnage x8. Résolution : 19 bit / 0.0006°C
      bme280.settings.tempOverSample=5   sur-échantillonnage x16. Résolution : 17 bit / 0.0003°C
   */
  bme280.settings.tempOverSample = 1 ;
  /*
   *  bme280.settings.pressOverSample =...

      bme280.settings.pressOverSample =0  pas de mesure de pression
      bme280.settings.pressOverSample =1   sur-échantillonnage x 1. Résolution 16 bit / 2.62 Pa
      bme280.settings.pressOverSample =2   sur-échantillonnage x 2. Résolution 17 bit / 1.31 Pa
      bme280.settings.pressOverSample =3   sur-échantillonnage x 4. Résolution 18 bit / 0.66 Pa
      bme280.settings.pressOverSample =4   sur-échantillonnage x 8. Résolution 19 bit / 0.33 Pa
      bme280.settings.pressOverSample =5   sur-échantillonnage x 16. Résolution 20 bit / 0.16 Pa
   */
  bme280.settings.pressOverSample = 1;
  /*
   *  bme280.settings.humidOverSample = ...

      bme280.settings.humidOverSample =0  pas de mesure d’humidité
      bme280.settings.humidOverSample =1   sur-échantillonnage x 1.
      bme280.settings.humidOverSample =2   sur-échantillonnage x 2.
      bme280.settings.humidOverSample =3   sur-échantillonnage x 4.
      bme280.settings.humidOverSample =4   sur-échantillonnage x 8.
      bme280.settings.humidOverSample =1   sur-échantillonnage x 16.
   */
  bme280.settings.humidOverSample = 1;
 
  Serial.println("Starting BME280... ");
  delay(10);  // attente de la mise en route du capteur. 2 ms minimum
  // chargement de la configuration du capteur
  bme280.begin();
  
  //On initialise le port série de l'arduino
  Serial.begin(9600); 
  Serial.println("Lancement...");
}
 
void loop() {
  // On récupère la trame GPS
  getGPS();

  // Le relevé des mesures température, pression et humidité est rapide
  // le compteur permet d'avoir un relevé toute les seconde environ
  compteur++;
  if (compteur>64000)
   {
    getBME280();
    compteur = 0;
   } 
}

void getBME280() {
  // Construit une trame au format similaire à NMEA
  //sprintf(trame,"$BME280,%f,%f,%f*FF",bme280.readTempC(),bme280.readFloatPressure()/100,bme280.readFloatHumidity());
  Serial.print("$BME280,");
  Serial.print(heureCourante);
  Serial.print(",");
  Serial.print(bme280.readTempC(), 2);
  Serial.print(",");
  Serial.print(bme280.readFloatPressure()/100, 2);
  Serial.print(",");
  Serial.print(bme280.readFloatHumidity(), 2);
  Serial.println("*FF"); // Checksum n'est pas calculé, il est là pour respecter la syntaxe.

}

void getGPS() {
   static int trameEnCours = 0;
   
   if (mySerial.available()>0)                    
    {
      char currentchar = mySerial.read();
      
      if (trameEnCours == 1)
      {
        if ((currentchar != 0x0A) && (currentchar != 0x0D))
        buffer[count++] = currentchar;
      }

      if (currentchar == '$')
      {
        trameEnCours = 1;
        count=0;
        buffer[count++] = '$';
      }
      
      if (currentchar == '*')
      {
        // Les caractères du checksum
        while (mySerial.available()==0) ; // wait for one char
        currentchar = mySerial.read();
        buffer[count++] = currentchar;
        while (mySerial.available()==0) ; // wait for one char
        currentchar = mySerial.read();
        buffer[count++] = currentchar;
        trameEnCours = 0;
        // conserver la date courante : $GPGGA,222625.00,4
        if((buffer[1]=='G') && (buffer[2]=='P') && (buffer[3]=='G') && (buffer[4]=='G') && (buffer[5]=='A')) {
          int i;
          for (i=0; i<9;i++) 
            heureCourante[i]=buffer[i+7];
          heureCourante[i]=0;
        }
        Serial.write(buffer,count);
        Serial.println("");
      }
    }
}

Un témoin d'angle de barre

Le GPS

Le GPS est connecté sur les pin 10 et 11 de l'arduino. (10 = TX du GPS , 11 = RX du GPS)

Le code du programme pour gérer les trames NMEA du GPS
#include <SoftwareSerial.h>
 
//Création de la variable SoftSerial (connexion software au port serie) RX sur le pin D2 et TX sur le pin D3
#define rxPin 10
#define txPin 11

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);
//On crée un tableau de caractères qui contiendra notre trame GPS
unsigned char buffer[256];
//la variable count nous servira à ne pas dépasser les 200 caractères du tableau.
int count=0;   
 
void setup() {
  //On initialise le port série software 
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  mySerial.begin(9600);
  //On initialise le port série de l'arduino
  Serial.begin(9600); 
  Serial.println("Lancement...");
}
 
void loop() {
  //On récupère la trame GPS
  getGPS();
}

void getGPS() {
   static int trameEnCours = 0;
   
   if (mySerial.available()>0)                    
    {
      char currentchar = mySerial.read();
      
      if (trameEnCours == 1)
      {
        if ((currentchar != 0x0A) && (currentchar != 0x0D))
        buffer[count++] = currentchar;
      }

      if (currentchar == '$')
      {
        trameEnCours = 1;
        count=0;
        buffer[count++] = '$';
      }
      
      if (currentchar == '*')
      {
        trameEnCours = 0;
        // buffer[count++] = 0; // Fin de la chaine de caractères
        Serial.write(buffer,count);
        Serial.println("");
      }
    }
}
 
//Fonction permettant de vérifier si la trame commence par les caractères $GPGGA
int isGPSGPGGA(unsigned char* trameGPS) {
  if(trameGPS[0] == '$' && trameGPS[1] == 'G' && trameGPS[2] == 'P' && trameGPS[3] == 'G' && trameGPS[4] == 'G' && trameGPS[5] == 'A')
    return 1;
  else
    return 0;
  }
 
//Methode permettant de remettre à 0 le tableau de caractères
void clearBufferArray()                     
{
    for (int i=0; i<count;i++)
    { buffer[i]=NULL;}                      
}
Exemple de trames générées
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.49,3.30,4.38*0F
$GPGSV,3,1,12,02,40,300,18,03,12,107,21,05,11,292,,06,61,218,20*75
$GPGSV,3,2,12,07,42,155,21,09,71,055,18,16,06,057,,19,08,225,*78
$GPGSV,3,3,12,23,40,060,17,26,05,031,07,29,02,343,,30,18,179,23*72
$GPGLL,4709.75657,N,00123.61570,W,192009.00,A,A*71
$GPRMC,192010.00,A,4709.75675,N,00123.61542,W,0.871,,200818,,,A*6C
$GPVTG,,T,,M,0.871,N,1.612,K,A*29
$GPGGA,192010.00,4709.75675,N,00123.61542,W,1,05,3.30,4.9,M,47.9,M,,*4F
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.49,3.30,4.38*0F
$GPGSV,3,1,12,02,40,300,17,03,12,107,20,05,11,292,,06,61,218,19*71
$GPGSV,3,2,12,07,42,155,22,09,71,055,17,16,06,057,,19,08,225,*74
$GPGSV,3,3,12,23,40,060,17,26,05,031,07,29,02,343,,30,18,179,23*72
$GPGLL,4709.75675,N,00123.61542,W,192010.00,A,A*78
$GPRMC,192011.00,A,4709.75666,N,00123.61571,W,0.362,,200818,,,A*66
$GPVTG,,T,,M,0.362,N,0.670,K,A*25
$GPGGA,192011.00,4709.75666,N,00123.61571,W,1,05,3.30,5.2,M,47.9,M,,*46
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.49,3.30,4.38*0F
$GPGSV,3,1,12,02,40,300,17,03,12,107,20,05,11,292,,06,61,218,19*71
$GPGSV,3,2,12,07,42,155,22,09,71,055,16,16,06,057,,19,08,224,*74
$GPGSV,3,3,12,23,40,060,17,26,05,031,07,29,02,343,,30,18,179,23*72
$GPGLL,4709.75666,N,00123.61571,W,192011.00,A,A*7B
$GPRMC,192012.00,A,4709.75763,N,00123.61639,W,0.905,,200818,,,A*65
$GPVTG,,T,,M,0.905,N,1.676,K,A*29
$GPGGA,192012.00,4709.75763,N,00123.61639,W,1,05,3.30,5.4,M,47.9,M,,*48
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.48,3.30,4.38*0E
$GPGSV,3,1,12,02,40,300,17,03,12,107,20,05,11,292,,06,61,218,18*70
$GPGSV,3,2,12,07,42,155,22,09,71,055,17,16,06,057,,19,08,224,*75
$GPGSV,3,3,12,23,40,060,17,26,05,031,07,29,02,343,,30,18,179,22*73
$GPGLL,4709.75763,N,00123.61639,W,192012.00,A,A*73
$GPRMC,192013.00,A,4709.75708,N,00123.61644,W,0.344,,200818,,,A*6C
$GPVTG,,T,,M,0.344,N,0.636,K,A*23
$GPGGA,192013.00,4709.75708,N,00123.61644,W,1,05,3.30,5.5,M,47.9,M,,*4F
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.48,3.30,4.38*0E
$GPGSV,3,1,12,02,40,300,17,03,12,107,19,05,11,292,,06,61,218,18*7A
$GPGSV,3,2,12,07,42,155,22,09,71,055,18,16,06,057,,19,08,224,*7A
$GPGSV,3,3,12,23,40,060,16,26,05,031,07,29,02,343,,30,18,179,21*71
$GPGLL,4709.75708,N,00123.61644,W,192013.00,A,A*75
$GPRMC,192014.00,A,4709.75743,N,00123.61658,W,0.743,,200818,,,A*6A
$GPVTG,,T,,M,0.743,N,1.376,K,A*20
$GPGGA,192014.00,4709.75743,N,00123.61658,W,1,05,3.30,5.8,M,47.9,M,,*47
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.48,3.30,4.38*0E
$GPGSV,3,1,12,02,40,300,18,03,12,107,19,05,11,292,,06,61,218,19*74
$GPGSV,3,2,12,07,42,155,22,09,71,055,18,16,06,057,,19,08,224,*7A
$GPGSV,3,3,12,23,40,060,16,26,05,031,08,29,02,343,,30,18,179,22*7D
$GPGLL,4709.75743,N,00123.61658,W,192014.00,A,A*70
$GPRMC,192015.00,A,4709.75755,N,00123.61721,W,0.989,,200818,,,A*6B
$GPVTG,,T,,M,0.989,N,1.832,K,A*23
$GPGGA,192015.00,4709.75755,N,00123.61721,W,1,05,3.30,6.1,M,47.9,M,,*44
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.48,3.30,4.38*0E
$GPGSV,3,1,12,02,40,300,18,03,12,107,19,05,11,292,,06,61,218,18*75
$GPGSV,3,2,12,07,42,155,23,09,71,055,18,16,06,057,,19,08,224,*7B
$GPGSV,3,3,12,23,40,060,17,26,05,031,08,29,02,343,,30,18,179,22*7C
$GPGLL,4709.75755,N,00123.61721,W,192015.00,A,A*79
$GPRMC,192016.00,A,4709.75726,N,00123.61727,W,0.662,,200818,,,A*60
$GPVTG,,T,,M,0.662,N,1.226,K,A*26
$GPGGA,192016.00,4709.75726,N,00123.61727,W,1,05,3.30,6.3,M,47.9,M,,*47
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.48,3.30,4.37*01
$GPGSV,3,1,12,02,40,300,18,03,12,107,19,05,11,292,,06,61,218,19*74
$GPGSV,3,2,12,07,42,155,23,09,71,055,18,16,06,057,,19,08,224,*7B
$GPGSV,3,3,12,23,40,060,17,26,05,031,08,29,02,343,,30,18,179,23*7D
$GPGLL,4709.75726,N,00123.61727,W,192016.00,A,A*78
$GPRMC,192017.00,A,4709.75647,N,00123.61751,W,0.741,,200818,,,A*66
$GPVTG,,T,,M,0.741,N,1.372,K,A*26
$GPGGA,192017.00,4709.75647,N,00123.61751,W,1,05,3.30,6.2,M,47.9,M,,*40
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.48,3.30,4.37*01
$GPGSV,3,1,12,02,40,300,18,03,12,107,19,05,11,292,,06,61,218,18*75
$GPGSV,3,2,12,07,42,155,23,09,71,055,19,16,06,057,,19,08,224,*7A
$GPGSV,3,3,12,23,40,060,17,26,05,031,08,29,02,343,,30,18,179,22*7C
$GPGLL,4709.75647,N,00123.61751,W,192017.00,A,A*7E
$GPRMC,192018.00,A,4709.75657,N,00123.61796,W,0.771,,200818,,,A*60
$GPVTG,,T,,M,0.771,N,1.428,K,A*2D
$GPGGA,192018.00,4709.75657,N,00123.61796,W,1,05,3.30,6.3,M,47.9,M,,*44
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.47,3.30,4.37*0E
$GPGSV,3,1,12,02,40,300,18,03,12,107,19,05,11,292,,06,61,218,19*74
$GPGSV,3,2,12,07,42,155,22,09,71,055,19,16,06,057,,19,08,224,*7B
$GPGSV,3,3,12,23,40,060,17,26,05,031,08,29,02,343,,30,18,179,22*7C
$GPGLL,4709.75657,N,00123.61796,W,192018.00,A,A*7B
$GPRMC,192019.00,A,4709.75635,N,00123.61707,W,0.286,,200818,,,A*60
$GPVTG,,T,,M,0.286,N,0.530,K,A*29
$GPGGA,192019.00,4709.75635,N,00123.61707,W,1,05,3.30,6.5,M,47.9,M,,*4F
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.47,3.30,4.37*0E
$GPGSV,3,1,12,02,40,300,18,03,12,107,19,05,11,292,,06,61,218,18*75
$GPGSV,3,2,12,07,42,155,22,09,71,055,19,16,06,057,,19,08,224,*7B
$GPGSV,3,3,12,23,40,060,16,26,05,031,08,29,02,343,,30,18,179,22*7D
$GPGLL,4709.75635,N,00123.61707,W,192019.00,A,A*76
$GPRMC,192020.00,A,4709.75682,N,00123.61680,W,0.209,,200818,,,A*6F
$GPVTG,,T,,M,0.209,N,0.386,K,A*25
$GPGGA,192020.00,4709.75682,N,00123.61680,W,1,05,3.30,6.5,M,47.9,M,,*47
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.47,3.30,4.37*0E
$GPGSV,3,1,12,02,40,300,17,03,12,107,18,05,11,292,,06,61,218,17*74
$GPGSV,3,2,12,07,42,155,22,09,71,055,20,16,06,057,,19,08,224,*71
$GPGSV,3,3,12,23,40,060,16,26,05,031,09,29,02,343,,30,18,179,22*7C
$GPGLL,4709.75682,N,00123.61680,W,192020.00,A,A*7E
$GPRMC,192021.00,A,4709.75652,N,00123.61685,W,0.321,,200818,,,A*6D
$GPVTG,,T,,M,0.321,N,0.594,K,A*2B
$GPGGA,192021.00,4709.75652,N,00123.61685,W,1,05,3.29,6.6,M,47.9,M,,*45
$GPGSA,A,3,23,03,06,09,07,,,,,,,,5.47,3.29,4.37*06
$GPGSV,3,1,12,02,40,300,17,03,12,107,18,05,11,292,,06,61,218,16*75
$GPGSV,3,2,12,07,42,155,21,09,71,055,20,16,06,057,,19,08,224,*72
$GPGSV,3,3,12,23,40,060,16,26,05,031,09,29,02,343,,30,18,179,22*7C
$GPGLL,4709.75652,N,00123.61685,W,192021.00,A,A*77
$GPRMC,192022.00,A,4709.75656,N,00123.61764,W,0.491,,200818,,,A*68

Le Raspberry

Le Raspberry sera raccordé au GPS et recevra les relevés du gyroscope, de l'accéléromètre et du magnétomètre via le port RS232.

Finalement , après réflexion le GPS est raccordé à l'Arduino.

L'acquisition des données

Pour l'acquisition des données j'ai utilisé :

   un arduino NANO
   un capteur BME280 (Humidité, température, pression)
   un GPS Ublox
   Un capteur 9 axes (MPU 9250 (voir https://lucidar.me/fr/inertial-measurement-unit/mpu-9250-and-arduino-9-axis-imu/)
   Un raspberry relier à l'arduino NANO par une liaison série à 115200 baud.

Le MPU-9250 est constitué de plusieurs circuits encapsulés dans un seul boitier, il contient :

  un accéléromètre 3 axes
  un gyroscope 3 axes
  un magnétomètre 3 axes

Le programme d'acquisition

La version du 2 mars 2020 du fichier NAVPI-central.ino.

la dernière version se trouve dans le gitlab ici.

/* 
 * NAVPI-centrale 
 * ce programme collecte les informations provenant de :
 *  - BME280 : pression, température, humidité
 *  - MPU-9250 : 9 axes
 *  - GPS ublox sur le port série 
 */

#include <SoftwareSerial.h>
#include <BME280I2C.h>
#include <Wire.h>

// Liaison série utilisant les pins 10 et 11 digital
SoftwareSerial gpsSerial(10, 11);


BME280I2C bme;    // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,

void setup() {
  // Initialisation des ports série
  Serial.begin(115200);
  gpsSerial.begin(9600);

  // Initialisation du capteur BME280
  initBME280();

  // Initialisation de l'accéléromètre MPU 9250
  initMPU9250();
  
}

int cpt=0;

void loop() {
  
  readgps();
}


//--------------------------------------------------
//
//  READGPS
//
//--------------------------------------------------
void readgps()
{
  
 String str;

 
 if(gpsSerial.available() > 0)
    {
        // Lecture sur le port série n°
        //str = gpsSerial.readString();
        str = gpsSerial.readStringUntil('\n');
        // renvoie les données sur le port n°0
        Serial.print(str);
        Serial.print("\n");
        //Serial.print(gpsSerial.read());
        cpt=0;
    }
   else
    {
      if(cpt==0)
       {
         // Lectrue des autres périphériques dans les temps morts
         printBME280Data(&Serial);
         printMPU9250(&Serial);
         cpt=1;
       }  
    }
}


/*
  BME280 I2C Test.ino

  This code shows how to record data from the BME280 environmental sensor
  using I2C interface. This file is an example file, part of the Arduino
  BME280 library.

  GNU General Public License

  Written: Dec 30 2015.
  Last Updated: Oct 07 2017.

  Connecting the BME280 Sensor:
  Sensor              ->  Board
  -----------------------------
  Vin (Voltage In)    ->  3.3V
  Gnd (Ground)        ->  Gnd
  SDA (Serial Data)   ->  A4 on Uno/Pro-Mini, 20 on Mega2560/Due, 2 Leonardo/Pro-Micro
  SCK (Serial Clock)  ->  A5 on Uno/Pro-Mini, 21 on Mega2560/Due, 3 Leonardo/Pro-Micro

*/

//--------------------------------------------------
//
//  INITBME280
//
//--------------------------------------------------
void initBME280()
{
Wire.begin();

  while (!bme.begin())
  {
    Serial.println("Could not find BME280 sensor!\n");
    delay(1000);
  }

  // bme.chipID(); // Deprecated. See chipModel().
  switch (bme.chipModel())
  {
    case BME280::ChipModel_BME280:
      Serial.println("Found BME280 sensor! Success.");
      break;
    case BME280::ChipModel_BMP280:
      Serial.println("Found BMP280 sensor! No Humidity available.");
      break;
    default:
      Serial.println("Found UNKNOWN sensor! Error!");
  }
}

//--------------------------------------------------
//
//  printBME280Data
//
//--------------------------------------------------
void printBME280Data (Stream* client)
{
  float temp(NAN), hum(NAN), pres(NAN);

  BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
  BME280::PresUnit presUnit(BME280::PresUnit_Pa);

  bme.read(pres, temp, hum, tempUnit, presUnit);

  // $GPGGA,,,,,,0,00,99.99,,,,,,*48
  
  String str ="";
  char data[100];

  str += "$BME280,";
  str +=temp;
  str +=",";
  str +=hum;
  str +=",";
  str +=pres;

  str.getBytes(data, 100);
  
  int c = checksum(data);
  client->print(data);
  sprintf(data,",*%02X",c);
  client->println(data);
  
  // delay(1000);
}

//--------------------------------------------------
//
//  checksum(const char *s)
//
//--------------------------------------------------
int checksum(const char *s) {
    int c = 0;

    while(*s)
        c ^= *s++;

    return c;
}

//---------------------------------------------------------------------------------------------------------
//
//  MPU9250
//
//---------------------------------------------------------------------------------------------------------

#define    MPU9250_ADDRESS            0x68
#define    MAG_ADDRESS                0x0C

#define    GYRO_FULL_SCALE_250_DPS    0x00  
#define    GYRO_FULL_SCALE_500_DPS    0x08
#define    GYRO_FULL_SCALE_1000_DPS   0x10
#define    GYRO_FULL_SCALE_2000_DPS   0x18

#define    ACC_FULL_SCALE_2_G        0x00  
#define    ACC_FULL_SCALE_4_G        0x08
#define    ACC_FULL_SCALE_8_G        0x10
#define    ACC_FULL_SCALE_16_G       0x18

// This function read Nbytes bytes from I2C device at address Address. 
// Put read bytes starting at register Register in the Data array. 
void I2Cread(uint8_t Address, uint8_t Register, uint8_t Nbytes, uint8_t* Data)
{
  // Set register address
  Wire.beginTransmission(Address);
  Wire.write(Register);
  Wire.endTransmission();
  
  // Read Nbytes
  Wire.requestFrom(Address, Nbytes); 
  uint8_t index=0;
  while (Wire.available())
    Data[index++]=Wire.read();
}


// Write a byte (Data) in device (Address) at register (Register)
void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data)
{
  // Set register address
  Wire.beginTransmission(Address);
  Wire.write(Register);
  Wire.write(Data);
  Wire.endTransmission();
}

volatile bool intFlag=false;

//--------------------------------------------------
//
//  INITMPU9250
//
//--------------------------------------------------
void initMPU9250()
{
    // Set accelerometers low pass filter at 5Hz
  I2CwriteByte(MPU9250_ADDRESS,29,0x06);
  // Set gyroscope low pass filter at 5Hz
  I2CwriteByte(MPU9250_ADDRESS,26,0x06);
 
  
  // Configure gyroscope range
  I2CwriteByte(MPU9250_ADDRESS,27,GYRO_FULL_SCALE_1000_DPS);
  // Configure accelerometers range
  I2CwriteByte(MPU9250_ADDRESS,28,ACC_FULL_SCALE_4_G);
  // Set by pass mode for the magnetometers
  I2CwriteByte(MPU9250_ADDRESS,0x37,0x02);
  
  // Request continuous magnetometer measurements in 16 bits
  I2CwriteByte(MAG_ADDRESS,0x0A,0x16);
  
   pinMode(13, OUTPUT);
//  Timer1.initialize(10000);         // initialize timer1, and set a 1/2 second period
//  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt
  
  
  // Store initial time
  //ti=millis();

}

void callback()
{ 
  intFlag=true;
  digitalWrite(13, digitalRead(13) ^ 1);
}


//--------------------------------------------------
//
//  PRINTMPU9250
//
//--------------------------------------------------
void printMPU9250(Stream* client)
{
   digitalWrite(13, digitalRead(13) ^ 1);
  // ----------------------------------------
  // accelerometer and gyroscope 
  // Read accelerometer and gyroscope
  // ----------------------------------------
  uint8_t Buf[14];
  I2Cread(MPU9250_ADDRESS,0x3B,14,Buf);
  
  // Create 16 bits values from 8 bits data
  
  // Accelerometer
  int16_t ax=-(Buf[0]<<8 | Buf[1]);
  int16_t ay=-(Buf[2]<<8 | Buf[3]);
  int16_t az=Buf[4]<<8 | Buf[5];

  // Gyroscope
  int16_t gx=-(Buf[8]<<8 | Buf[9]);
  int16_t gy=-(Buf[10]<<8 | Buf[11]);
  int16_t gz=Buf[12]<<8 | Buf[13];
  
  // Creation de trame MPU9250 au format NMEA
  String strmpu="";
  strmpu += "$MPU9250,";
  // Accelerometer
  strmpu +=ax;
  strmpu +=",";
  strmpu +=ay;
  strmpu +=",";
  strmpu +=az;
  strmpu +=",";

  // Gyroscope
  strmpu +=gx;
  strmpu +=",";
  strmpu +=gy;
  strmpu +=",";
  strmpu +=gz;
  strmpu +=",";
 
  // ----------------------------------------
  // Magnetometer 
  // Read register Status 1 and wait for the DRDY: Data Ready
  // ----------------------------------------
  
  uint8_t ST1;
  do
  {
    I2Cread(MAG_ADDRESS,0x02,1,&ST1);
  }
  while (!(ST1&0x01));

  // Read magnetometer data  
  uint8_t Mag[7];  
  I2Cread(MAG_ADDRESS,0x03,7,Mag);
  

  // Create 16 bits values from 8 bits data
  
  // Magnetometer
  //Serial.print ("mx:");
  int16_t mx=-(Mag[3]<<8 | Mag[2]);
  int16_t my=-(Mag[1]<<8 | Mag[0]);
  int16_t mz=-(Mag[5]<<8 | Mag[4]);
  
  
  // Magnetometer
  int16_t i;
  i=mx+200;
  strmpu +=i;
  strmpu +=",";
  i=my-70;
  strmpu +=i;
  strmpu +=",";
  i=mz-700;
  strmpu +=i;

  char data[100];
  strmpu.getBytes(data, 100);
  int c = checksum(data);
  client->print(data);
  sprintf(data,",*%02X",c);
  client->println(data); 
  
}

Exemple de sortie

Exemple de sortie récupérée sur le port série du raspberry.

  • Les trames $BME280 et $MPU9250 ne sont pas standards. J'ai utilisé le même format avec une dénomination personnelle.
  • Syntaxe de la trame $BME280 : $BME280,température,%humidité, Pression en Pa
  • Syntaxe de la trame $MPU9250 : $MPU9250,ax,ay,az,gx,gy,gz,mx,my,mz
$GPGGA,221231.00,,,,,0,00,99.99,,,,,,*67
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,3,1,12,01,31,265,,08,84,303,15,10,46,058,,11,57,291,*7C
$GPGSV,3,2,12,14,09,133,,16,14,178,25,20,16,047,,22,19,209,*78
$GPGSV,3,3,12,27,59,124,17,28,05,329,,30,02,300,,32,20,112,*76
$GPGLL,,,,,221231.00,V,N*4B
$BME280,22.24,37.67,100573.97,*5B
$MPU9250,4955,-590,4116,-10,66,-31,-105,-271,-847,*45
$GPRMC,221232.00,V,,,,,,,020320,,,N*7C
$GPVTG,,,,,,,,,N*30
$GPGGA,221232.00,,,,,0,00,99.99,,,,,,*64
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,3,1,12,01,31,265,,08,84,303,14,10,46,058,28,11,57,291,*77
$GPGSV,3,2,12,14,09,133,,16,14,178,25,20,16,047,,22,19,209,*78
$GPGSV,3,3,12,27,59,124,17,28,05,329,,30,02,300,,32,20,112,*76
$GPGLL,,,,,221232.00,V,N*48
$BME280,22.22,37.74,100570.81,*5B
$MPU9250,4955,-590,4121,-10,63,-32,-109,-269,-851,*45
$GPRMC,221233.00,V,,,,,,,020320,,,N*7D
$GPVTG,,,,,,,,,N*30
$GPGGA,221233.00,,,,,0,00,99.99,,,,,,*65
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,3,1,12,01,31,265,,08,84,303,13,10,46,058,,11,57,291,28*70
$GPGSV,3,2,12,14,09,133,,16,14,178,25,20,16,047,,22,19,209,*78
$GPGSV,3,3,12,27,59,124,18,28,05,329,,30,02,300,,32,20,112,*79
$GPGLL,,,,,221233.00,V,N*49
$BME280,22.23,38.11,100573.19,*54
$MPU9250,4957,-593,4113,-10,65,-32,-112,-272,-848,*4B

Calculer le checksum

La somme de contrôle à la fin de chaque phrase est le XOR de tous les octets de la phrase, à l'exclusion du signe dollar initial.

  • Le code C suivant génère une somme de contrôle pour la chaîne entrée en tant que "mystring" et l’affiche dans le flux de sortie. .
#include <stdio.h>

int checksum(const char *s) {
    int c = 0;

    while(*s)
        c ^= *s++;

    return c;
}

int main()
{
    // La trame NMEA complete
    // $GPGSV,3,1,12,02,40,300,18,03,12,107,21,05,11,292,,06,61,218,20*75
    char mystring[] = "GPGSV,3,1,12,02,40,300,18,03,12,107,21,05,11,292,,06,61,218,20";

    printf("String: %s\nChecksum: 0x%02X\n", mystring, checksum(mystring));

    return 0;
}

Montage de la girouette et anémometre

La girouette

Mesure de 0 a 360 degres

Input voltage: 12V-24V DC 
The output signal "4-20mA 
Wind direction value = (Output current -4) / 16 * 360 

L'anemometre

Range:0~32. 4 m/s

Supply voltagec:12V~24V  DC  
Output signals:4~20 mA
Load capacity:≤200Ω
Wind speed values =(output current -4)/16*32.4


QS-FX01.png

La carte de conversion

J'ai eu beaucoup de mal à mettre en oeuvre la carte de convertion 4-20mA.

J'ai essayé en premier cette carte , mais elle a été détruite à cause d'une fausse manip.

Current-to-Voltage-Signal-ModuleExemple.png

Description:

Module parameters

1, the working voltage: 9V ~ 17V
2, the input current: 4.00MA ~ 20.00MA
3, the output voltage: 0.00V ~ 5.00V /
4, the control mode: 4.00MA (mA) ~ 20.00MA (mA) input is converted to the corresponding 0.00v (V) to 5.00V (volts)
5, Size: (L) 26mm * (W) 23mm * (height) 10mm
6, drive: no drive.
7, Applications: Current signal transduction voltage signal; remote data acquisition and control equipment;
8, the module interface:
12V: power supply positive interfaces (9V ~ 17V).
G: Power to the ground interface.
IN: Signal input interface (4.00MA ~ 20.00MA).
G: Power to the ground interface.
OUT: Signal output connector (0.00V ~ 5.00V).
G: Power to the ground interface.

La carte ci-dessus a crâmé suite à une fausse manip...:-(

J'utilise maintenant une carte HW-685 (0.86 € chez aliexpress) : Hw-685.png

Le site https://docs.turais.de/docs/modules/hw685/ propose une doc pour le montage de la carte. La page sauvegardée au format pdf se trouve ici

Description:

Dans le processus de transmission de signal de circuit, le signal de tension s'affaiblira avec l'augmentation de la distance de transmission, et la transmission actuelle peut éviter l'affaiblissement du signal.

  • Le module est utilisé pour la fin de la transmission du signal actuel, le signal est converti en signal de tension pour la détection SCM.
  • L'entrée de courant prend en charge 4-20mA et 0-20mA, et la sortie de tension prend en charge 0-3.3V 0-5V 0-10V.

Point culminant: La plage de tension d'alimentation est large et la tension de sortie prend en charge plusieurs plages;

  • Zéro et gamme complète peuvent être ajustés automatiquement;
  • Haute stabilité, bonne linéarité, qualité industrielle;
  • La résistance d'échantillonnage du signal actuel adopte une résistance d'anneau de couleur de haute précision, qui a une haute précision, une petite dérive de température et une puissance élevée

Instruction:

  • 1. Le module est connecté selon la définition, la tension d'alimentation est de 7-36V (si la sortie est à 10V, la tension d'alimentation doit être supérieure à 12V)
  • 2. Après la mise sous tension, la lumière D2 doit être brillante, sinon veuillez vérifier la connexion de ligne. Carte avec protection de connexion inverse, connexion inverse ne brûlant pas.
  • 3. Lorsque l'entrée de courant est minimale (0mA ou 4mA), ajustez le potentiomètre zéro, de sorte que la sortie de VOUT soit minimale (0.0V ou autre tension)
  • 4. Lorsque l'entrée de courant est maximale (20mA), ajustez le potentiomètre d'envergure, de sorte que la sortie VOUT soit la valeur maximale (3.3V ou 5V ou 10V, quand l'entrée est 4-20mA, la sortie minimum peut être 2.5V).

Selon vos besoins, sélectionnez la gamme correspondante par bouchon de cavalier:

  • 4 -- 20ma:0 -- 2.5V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds connexion courte

Gamme 0-3.3V: J1 1, 2 pieds, 3, 4 pieds

  • 0 -- 5.0V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds connexion courte
  • 0 -- 10.0V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds off
  • 0 -- 20ma:0 -- 3.3V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds connexion courte
  • 0 -- 5.0V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds connexion courte
  • 0 -- 10.0V gamme: J1 1, 2 pieds connexion courte, 3, 4 pieds off

Emballage Inclus:

1 * courant à la tension 0/4-20mA à 0 -10V Module émetteur


Le montage final utilise la carte suivante : Convertisseur-de-courant-tension-0-5V-0-20mA-convertisseur-de-tension-courant-Module-de-Signal-I.jpg

Le programme

La formule de calcul donnée par la documentation

Wind speed value = (output voltage -0.4) /1.6*32.4

Le code du programme ce trouve dans la gitlab audiens.

Les documents

Les données AIS

Liens utiles


Montage des prises vissées

Montag des prises PL vissées

Pour gérer l'AIS j'ai mis en oeuvre un transpondeur AIS Matsuteck HA102

La liaison série (38400) donne ces informations lorsque le transpondeur n'est pas connecté à l'antenne VHF.

23:08:44.091 -> $GPRMC,220844.00,A,4709.75353,N,00123.60589,W,0.185,219.18,190320,,,A*7D
23:08:45.075 -> $GPRMC,220845.00,A,4709.75357,N,00123.60605,W,0.248,219.18,190320,,,A*7D
23:08:46.070 -> $GPRMC,220846.00,A,4709.75359,N,00123.60603,W,0.201,219.18,190320,,,A*7B
23:08:47.067 -> $GPGSA,A,3,10,03,27,11,08,14,32,22,,,,,2.16,1.32,1.70*0A
23:08:47.137 -> $GPRMC,220847.00,A,4709.75358,N,00123.60619,W,0.488,219.18,190392903,2,16,9,086015,3,1,20049287D
23:08:48.146 -> $GPRMC,220848.00,A,4709.75358,N,00123.60612,W,0.654,219.18,190320,,,A*70
23:08:48.146 -> !AIVDO,1,1,,B,B3IE;b001WvItAVgjCv8ueP108L07AD1,C;0IgvPLU11111BP
23:08:49.058 -> $GPRMC,220849.00,A,4709.75359,N,00123.60619,W,0.401,219.18,190320,,,A*79
23:08:50.068 -> $GPRMC,220850.00,A,4709.75360,N,00123.60618,W,0.463,219.18,190320,,,A*7E
23:08:50.153 -> ais silent end
23:08:51.077 -> $GPVTG,219.18,T,,M,0.463,N,0.858,K,A*3A
23:08:51.158 -> $GPGGA,220850.00,4709.75360,N,00123.60618,W,1,08,1.32,26.0,M,47.9,M,,*71
23:08:51.158 -> $GPRMC,220851.00,A,4709.753,0261W3,9890,7ais silent end
23:08:52.073 -> $GPGSA,A,3,10,03,27,11,08,14,32,22,,,,,2.16,1.32,1.70*0A
23:08:52.137 -> $GPRMC,220852.00,A,4709.75362,N,00123.60612,W,0.272,219.18,19029,9,3,2,26,2,08,6153351019,49,8*D
23:08:53.067 -> $GPRMC,220853.00,A,4709.75362,N,00123.60609,W,0.063,219.18,190320,,,A*7B
23:08:53.157 -> ais silent end
23:08:54.062 -> $GPRMC,220854.00,A,4709.75364,N,00123.60612,W,0.085,219.18,190320,,,A*78
23:08:54.142 -> ais silent end
23:08:55.090 -> $GPRMC,220855.00,A,4709.75367,N,00123.60629,W,0.134,219.18,190320,,,A*79
23:08:55.174 -> ais silent end
23:08:56.086 -> $GPRMC,220856.00,A,4709.75367,N,00123.60629,W,0.209,219.18,190320,,,A*77
23:08:56.165 -> ais silent end
23:08:57.180 -> $GPGSA,A,3,10,03,27,11,08,14,32,22,,,,,2.16,1.32,1.70*0A
23:08:57.338 -> $GPRMC,220857.00,A,4709.75368,N,00123.60650,W,0.255,219.18,19039,903,2,16,1,08,61533610,9,4929*F
23:08:57.338 -> $GS3,,,,,0,,9,,,221312GS,17,1,21,32,227*C
23:08:58.105 -> $GPRMC,220858.00,A,4709.75366,N,00123.60656,W,0.319,219.18,190320,,,A*70
23:08:58.105 -> !AIVDO,1,1,,A,B3IE;b000ovIt?VgjD28ueP10D00,0*3BAD,,3b0tj80JBU11ais sart end
23:09:00.094 -> $GPRMC,220859.00,A,4709.75368,N,00123.60664,W,0.425,219.18,190320,,,A*76
23:09:00.178 -> $GPRMC,220900.00,A,4709.75369,N,00123.60645,W,071890,4ais silent end
23:09:00.178 -> $GPVTG,219.18,T,,M,0.817,N,1.513,K,A*36
23:09:00.260 -> $GPGGA,220900.00,4709.75369,N,00123.60645,W,1,08,1.32,25.6,M,47.9,M,,*71
23:09:01.089 -> $GPRMC,220901.00,A,4709.75370,N,00123.60663,W,0.670,219.18,190320,,,A*76
23:09:02.083 -> $GPGSA,A,3,10,03,27,11,08,14,32,22,,,,,2.16,1.32,1.70*0A
23:09:03.113 -> $GPRMC,220903.00,A,4709.75371,N,00123.60661,W,0.683,219.18,190320,,,A*7B
23:09:04.071 -> $GPRMC,220904.00,A,4709.75372,N,00123.60651,W,0.785,219.18,190320,,,A*7B
23:09:05.066 -> $GPRMC,220905.00,A,4709.75373,N,00123.60659,W,0.811,219.18,190320,,,A*71
23:09:05.145 -> ais silent end
23:09:06.061 -> $GPRMC,220906.00,A,4709.75371,N,00123.60648,W,0.765,219.18,190320,,,A*7C
23:09:06.131 -> ais sart end
23:09:06.208 -> $GPGSA,A,3,10,03,27,11,08,14,32,22,,,,,2.16,1.32,1.70*0A
23:09:07.134 -> ais silent end
23:09:08.097 -> $GPRMC,220907.00,A,4709.75376,N,00123.60667,W,0.460,219.18,190320,,,A*71
23:09:08.179 -> ai srtend
23:09:08.179 -> ais sart end
23:09:09.056 -> $GPRMC,220909.00,A,4709.75386,N,00123.60653,W,0.581,219.18,190320,,,A*79
23:09:09.124 -> ais silent end
23:09:10.084 -> $GPRMC,220910.00,A,4709.75389,N,00123.60629,W,0.695,219.18,190320,,,A*75
23:09:10.170 -> ais silent end
23:09:11.078 -> $GPVTG,219.18,T,,M,0.695,N,1.287,K,A*38
23:09:11.167 -> $GPGGA,220910.00,4709.75389,N,00123.60629,W,1,08,1.32,25.9,M,47.9,M,,*7B
23:09:11.167 -> $GPRMC,220911.00,A,4709.759N0304,4,9,00,Dais silent end
23:09:11.254 -> $GPGSA,A,3,10,03,27,11,08,14,32,22,,,,,2.16,1.32,1.71*0B
23:09:12.090 -> $GPRMC,220912.00,A,4709.75394,N,00123.60580,W,0.844,219.18,190320,,,A*79
23:09:12.175 -> $GPGSV,3,1,11,01,59,289,31,03,25,216,15,08,60,53099*
23:09:13.065 -> $GPRMC,220913.00,A,4709.75399,N,00123.60565,W,0.776,219.18,190320,,,A*70
23:09:14.059 -> $GPRMC,220914.00,A,4709.75401,N,00123.60546,W,0.733,219.18,190320,,,A*71
23:09:14.146 -> ais silent end
23:09:15.085 -> $GPRMC,220915.00,A,4709.75403,N,00123.60525,W,0.820,219.18,190320,,,A*7A
23:09:15.166 -> ais silent end 


Voici le lien vers AIVDM/AIVDO protocol decoding : https://gpsd.gitlab.io/gpsd/AIVDM.html

Le lien vers une appli GNUAIS http://gnuais.sourceforge.net/

Exploitation des données

NMEA

Liens utiles

http://www.gpsinformation.org/dale/nmea.htm#nmea

https://www.junkrigassociation.org/page-1858647 : donne des informations sur les phrases NMEA propriétaires.

Syntaxe des trames

  • $ : délimiteur de début de trame
  • GP : trame provenant d'un GPS
  • II : Integrated Instrumentation

Les codes NMEA

All $GPxxx sentence codes and short descriptions (http://aprs.gids.nl/nmea/)

   $GPAAM - Waypoint Arrival Alarm
   $GPALM - GPS Almanac Data
   $GPAPA - Autopilot Sentence "A"
   $GPAPB - Autopilot Sentence "B"
   $GPASD - Autopilot System Data
   $GPBEC - Bearing & Distance to Waypoint, Dead Reckoning
   $GPBOD - Bearing, Origin to Destination
   $GPBWC - Bearing & Distance to Waypoint, Great Circle
   $GPBWR - Bearing & Distance to Waypoint, Rhumb Line
   $GPBWW - Bearing, Waypoint to Waypoint
   $GPDBT - Depth Below Transducer
   $GPDCN - Decca Position
   $GPDPT - Depth
   $GPFSI - Frequency Set Information
   $GPGGA - Global Positioning System Fix Data
   $GPGLC - Geographic Position, Loran-C
   $GPGLL - Geographic Position, Latitude/Longitude
   $GPGSA - GPS DOP and Active Satellites
   $GPGSV - GPS Satellites in View
   $GPGXA - TRANSIT Position
   $GPHDG - Heading, Deviation & Variation
   $GPHDT - Heading, True
   $GPHSC - Heading Steering Command
   $GPLCD - Loran-C Signal Data
   $GPMTA - Air Temperature (to be phased out)
   $GPMTW - Water Temperature
   $GPMWD - Wind Direction
   $GPMWV - Wind Speed and Angle (cf IIMWV)
   $GPOLN - Omega Lane Numbers
   $GPOSD - Own Ship Data
   $GPR00 - Waypoint active route (not standard)
   $GPRMA - Recommended Minimum Specific Loran-C Data
   $GPRMB - Recommended Minimum Navigation Information
   $GPRMC - Recommended Minimum Specific GPS/TRANSIT Data
   $GPROT - Rate of Turn
   $GPRPM - Revolutions
   $GPRSA - Rudder Sensor Angle
   $GPRSD - RADAR System Data
   $GPRTE - Routes
   $GPSFI - Scanning Frequency Information
   $GPSTN - Multiple Data ID
   $GPTRF - Transit Fix Data
   $GPTTM - Tracked Target Message
   $GPVBW - Dual Ground/Water Speed
   $GPVDR - Set and Drift
   $GPVHW - Water Speed and Heading
   $GPVLW - Distance Traveled through the Water
   $GPVPW - Speed, Measured Parallel to Wind
   $GPVTG - Track Made Good and Ground Speed
   $GPWCV - Waypoint Closure Velocity
   $GPWNC - Distance, Waypoint to Waypoint
   $GPWPL - Waypoint Location
   $GPXDR - Transducer Measurements
   $GPXTE - Cross-Track Error, Measured
   $GPXTR - Cross-Track Error, Dead Reckoning
   $GPZDA - Time & Date
   $GPZFO - UTC & Time from Origin Waypoint
   $GPZTG - UTC & Time to Destination Waypoint

Direction du vent : $IIMWV

$IIMWV est la phrase NMEA pour le vent mesuré par le capteur LCJ CV7.

  • II signifie integrated instrumentation,
  • MWV pour acoustic wind sensor.

Le format est le suivant :

$IIMWV,318.0,R,014.8,N,A*3A
  • direction du vent en degrés (318.0)
  • R = relative or apparent wind,
  • vitesse du vent (014.8)
  • N = knots, cela peut être K/M/N (Kilometres/hr, M/s, knots)
  • A indique le status, “A” indique une mesure correcte, V indique une mesure incorrecte,
  • 3D is a checksum.

Vitesse du vent relatif (vent apparent) et angle : $GPVWR

  • $GPVWR donne la vitesse relative du vent et l'angle (vent apparent et l'angle).

Le format :

$GPVWR,42.00,L,14.80,N,7.61,M,27.41,K*7B
  • Direction magnitude en degrés.
  • Direction du vent Left/Right of Bow
  • Vitesse
  • N = Knots
  • Vitesse
  • M = metres/sec
  • Vitesse
  • K = Kilometres/hr
  • Checksum

Vitesse du vent : $GPMWV

$GPMWV donne la vitesse du vent et l'angle le détail voir $IIMWV

$GPVHW : vitesse et cap

donne la vitesse par rapport à l'eau et le cap.

Le format:

$GPVHW,,,,,4.79,N,8.87,K*56
  • cap en degrés vrais.
  • T = True
  • cap en degrés magnetic.
  • M = Magnetic
  • vitesse (4.79) in knots,
  • N = knots
  • Vitesse relative à l'eau en Kilometres/hr,
  • K = kilometres,
  • checksum.

La carte d'aquisition des données

La carte d'aquisition des données contient :

Le MPU-9250 est constitué de plusieurs circuits encapsulés dans un seul boitier, il contient :
   un accéléromètre 3 axes
   un gyroscope 3 axes
   un magnétomètre 3 axes

L'interface graphique

Installation X11 minimale pour le projet NAVPI

Installer les packages

apt-get update && apt-get -y install xorg 

Modifier le fichier /etc/rc.local

vi /etc/rc.local

le contenu du fichier

#!/bin/bash

echo `date` >> /tmp/startx.log
su - -c "/usr/bin/startx" >> /tmp/startx.log 2>&1 &

exit 0

Créer le fichier ~/.xinitrc

echo "exec /usr/bin/xeyes" >> ~/.xinitrc

Tester le redémarrage

reboot

Installation de Qt5

J'ai installé les outils de développement Qt5 sur un raspberry 4 model B doté de 2Go de RAM.

apt-get -y install qt5-default qt5-qmake

Le composant jauge

La source du programme se trouve dans le gitlab.

L'application jauge

Fonctionnement

Le composant jauge lit les données depuis un named pipe (/tmp/girouette-anemometre) créé automatiquement par le programme.

Les données sont au format suivant : 118;6.60

  • 118 : angle du vent en degrés
  • 6.60 : vitesse du vent en noeuds

Déploiement de l'application

Pour déployer l'application qt5 sur un raspberry :

  • installer Xorg minimal
  • installer les librairies qt5
  • installer les packages qt5 suivants:
apt-get -y install qt5dxcb-plugin
  • installer l'utilitaire bc
apt-get -y install bc