Ostereier verstecken mit GPS (GPS/GSM SIM 808) - Teil 1 - AZ-Delivery

Cette année, nous voulons aider le lapin de Pâques à cacher des œufs de Pâques qui seront retrouvés. Pour cela, nous l'équipons (et plus tard les chercheurs) d'un récepteur GPS. Le camouflage et la lecture de la position est la partie la plus facile, car les valeurs sont affichées sur notre écran et il suffit de les noter. Mais même pour cela, nous devons lui donner une compréhension de base de notre terre, alors lapin de Pâques : attention.

La recherche nous confronte alors à de plus grands défis la fois suivante, car nous devons d'abord déterminer la position actuelle, puis calculer le parcours et la distance jusqu'à la destination. Cela nécessite un certain nombre de connaissances mathématiques, mais nous pouvons faire quelques simplifications en raison des courtes distances ici en Allemagne ou en Europe centrale.

Lorsque nous n'avons plus besoin du récepteur pour la chasse aux œufs de Pâques ou le GeoCaching, nous en faisons un système de suivi dans la troisième partie, car nous avons ici un module combiné GPS/GSM, avec lequel nous pouvons également envoyer la position par SMS à un smartphone.

De quoi avons-nous besoin?

Numéro Composante
1 Micro contrôleur, par exemple le MC compatible UNO R3
1 LCD, E.G. que  LCD-KeyPad-Shield
1 Module GPS / GSM SIM 808 (Dans la troisième partie avec carte SIM)
Pile ou batterie rechargeable


Afin de ne pas déborder du cadre de ce post, je vous renvoie aux eBooks liés à la page produit respective pour plus de détails sur le SIM 808 et le Keypad Shield.

Ceux qui savent déjà exactement ce que signifie 54°30'N 009°15'E peuvent parcourir les paragraphes suivants. Ceux qui ne le font pas vont maintenant apprendre à connaître notre système de coordonnées sur Terre.

La terre ressemble à une orange (seulement bleue au lieu d'orange), presque sphérique, légèrement aplatie aux pôles. Pour déterminer un point sur la surface, des personnes astucieuses se sont finalement mises d'accord sur un système de coordonnées uniforme. En un jour, la terre tourne une fois autour de son axe. Nous définissons cet axe de rotation comme l'axe de la Terre passant par les deux pôles et coupons la sphère en deux par une ligne imaginaire appelée l'équateur. Ensuite, nous définissons la latitude comme l'angle au centre de la terre entre l'équateur et notre emplacement. L'Allemagne se situe entre 47° 16′ 18″ et 55°03′ 31,1″ ° de latitude nord. Les pôles sont alors respectivement à 90° nord et sud ; la latitude sud est souvent indiquée par des signes moins. L'établissement de la longitude était plus difficile car chaque roi voulait que la ligne zéro passe par son trône (par exemple, la ligne rose dans le "Da Vinci Code" de Dan Brown). Enfin, l'observatoire de Greenwich, près de Londres, a été établi comme méridien de référence. Une fois le tour de la terre fait 360°, 180° chacun à l'est et à l'ouest ; les longitudes occidentales avec des signes moins à nouveau si nécessaire. L'Allemagne se situe entre 005° 52′ 01″ et 015°02′ 37″ de longitude est. La ligne de changement de date (généralement à 180° E/W) traverse l'océan Pacifique.

Image : Globe terrestre avec cercles de longitude et de latitude

Les longitudes sont des grands cercles qui vont de pôle en pôle. Les grands cercles sont des cercles quelconques sur la surface de la sphère autour du centre de la terre ; la distance la plus courte entre deux points passe par ces points sur le grand cercle. L'équateur est le seul cercle de latitude qui soit un grand cercle ; vers le pôle, le rayon ou la circonférence des cercles de latitude devient de plus en plus petit. Qui connaît la fonction d'angle qui est maximale (=1) à 0° et minimale (=0) à 90° ? Cela viendra plus tard, lorsque nous devrons apprendre non seulement les angles en degrés mais aussi en radians. La navigation a beaucoup à voir avec les mathématiques.

Pour mieux comprendre la planète Terre, un globe terrestre (de préférence avec éclairage intérieur) est indispensable, mais pour la navigation, nous nous orientons dans une carte, une feuille de papier plate avec la zone dans laquelle nous nous déplaçons. Dans le domaine maritime, la règle est toujours de prendre la carte à la plus grande échelle disponible, mais laquelle est la plus grande ? 1:2.000.000 ou 1:50.000 ? Avec la première carte, 10 cm équivalent à 200 km en réalité, avec la deuxième, les 10 cm ne représentent que 5 km. Le second est donc plus détaillé. Les petites échelles (Übersegler) sont utilisées pour la planification d'itinéraires, le jeu de cartes avec les plus grandes échelles est utilisé pour la conduite. Aujourd'hui, vous le faites avec un écran tactile, où vous changez la gamme avec deux doigts.

Pour obtenir une telle carte, une image bidimensionnelle de la surface terrestre, nous (mais aussi Google Maps et d'autres) utilisons les méthodes de Gheert Cremer, plus connu sous le nom de Gerhard Mercator (1512 - 1594) et de Johann Heinrich Lambert (1728 - 1777). Mercator a décrit la projection dite cylindrique, Lambert la projection conique (intersection).

Avec la projection de Mercator, un cylindre est placé sur la sphère, dans nos latitudes, axe-parallèle. Ainsi, les pôles ne sont pas représentés et l'île du Groenland semble plus grande que le continent africain. L'image n'est donc pas fidèle à la longueur ou à la surface et est inutile près des pôles. Mais il est fidèle à l'angle et nous mène en Europe centrale à des distances courtes à moyennes suffisamment bien au but.

Types de projection : projection cylindrique gauche (Mercator), projection conique droite (sectionnelle) (Lambert)

La projection du cône d'intersection de Lambert place un cône au pôle qui coupe la sphère à, disons, 60 degrés de latitude nord, de sorte qu'il passe à l'intérieur de la sphère et en sort à 30 degrés de latitude nord. C'est (surtout près des cercles de latitude/des lignes d'intersection) le meilleur compromis en termes de longitude, de surface et de fidélité angulaire, mais rien n'est correct à 100%. La carte idéale pour les pilotes, qui parcourent généralement de plus longues distances que les GeoCachers.

Sur ces images de la surface terrestre, nous traçons ensuite nos lignes auxiliaires et pouvons ainsi déterminer chaque lieu avec sa latitude (combien de degrés au nord de l'équateur ?) et sa longitude (combien de degrés à l'est de l'observatoire de Greenwich ?) ou vice versa à partir des données numériques.

Les vraies difficultés commencent dans les détails, parce qu'il y a différentes notations ; et nous voulons que les informations de localisation soient aussi précises que possible. La latitude "exacte à 1°" signifie une précision de 111 km, donc quelque part entre Würzburg et Nuremberg. Une subdivision plus précise a été faite avec les minutes d'arc. Le mot minute indique déjà que le nombre 60 entre en jeu. 1° (parler : degré) correspond à 60' (parler : (arc-) minutes.

Rappelons ici qu'une minute d'arc sur le méridien (méridien de longitude) est égale à un mille nautique ou 1,852 km.

Encore trop imprécis pour notre recherche. Il faut donc subdiviser en secondes (d'arc) (toujours avec le facteur 60) ou selon le système décimal. Les deux sont possibles et courants, il suffit de maîtriser la conversion. Les géochercheurs préfèrent le format DDMM.mmmm, c'est-à-dire les degrés en deux chiffres, puis les minutes en deux chiffres et les fractions en décimales des minutes représentées ici par un petit "m". On peut aussi utiliser le format DDMMSSss, c'est-à-dire les degrés (DD), les minutes (MM), les secondes (SS) et les décimales de secondes (ss). Pour la conversion, nous n'avons besoin que du nombre 60 déjà mentionné, ainsi, par exemple, 30 secondes d'arc équivalent à 30/60 = ½ minute d'arc. Dans l'autre sens, 0,8 minute d'arc correspond à 0,8 * 60 = 48 secondes d'arc.

Le croquis suivant a pour but de nous aider à sélectionner les bonnes données parmi la multitude de données reçues par notre récepteur GPS. Si nous connectons notre récepteur GPS à un programme terminal, nous recevons les données suivantes toutes les secondes :


Vous pouvez rapidement voir que les données intéressantes se trouvent dans les lignes commençant par $GPGGA et "GPRMC :
$GPGGA,080635.000,5351.2345,N,00951.2345,E,1,9,1.02,32.1,M,45.6,M,,*67

$GPRMC,080635.000,A, 5351.2345,N, 00951.2345,E,0.20,159.92,140321,,,A*69

La bibliothèque de programmes que nous utilisons dans l'esquisse évalue la ligne en gras qui commence par GPRMC. Cependant, les informations essentielles se trouvent également dans l'autre ligne. Ici, GP signifie Global Positioning System (GPS) et RMC signifie Recommended Minimum Navigation Information. (Sources) :

https://fr.wikipedia.org/wiki/NMEA_0183, http://www.nmea.fr/nmea0183datensaetze.html#rmc)

Alors suivez :

1) Temps universel coordonné (UTC) (anciennement connu sous le nom de Greenwich Mean Time (GMT)
2) Latitude (Format DDMM.mmmm)
3) N ou S (Nord ou Sud)
4) Longitude (Format DDDMM.mmmm)
5) E ou W (Est ou Ouest) 
6) Indicateur de qualité du GPS, 0 - point non disponible, 1 - point GPS,
2 - Position GPS différentielle
7) Nombre de satellites en vue, 00 - 12
8) Altération horizontale de la précision
9) Altitude de l'antenne au-dessus/au-dessous du niveau moyen de la mer (géoïde) 
10) Unités d'altitude de l'antenne, mètres

Pour le matériel, j'avais décidé d'utiliser le bouclier à clavier LCD, où vous pouvez rapidement passer d'une vue à l'autre en utilisant les boutons du clavier. Nous utilisons le bouton GAUCHE pour la position au format DDMMmmmm, BAS pour la date et l'heure en temps universel coordonné (UTC), HAUT pour notre fuseau horaire et DROIT pour la position au format DDMMSSs ; nous utilisons le bouton SELECT la prochaine fois pour le cap et la distance.

Notes préliminaires sur le schéma :

  1. Pour le récepteur GPS j'utilise SoftwareSerial à A3 = GPIO 17 et A4 = GPIO 18.
  2. La bibliothèque utilisée contient un bug pour la conversion des secondes d'arc en décimales de minutes d'arc et vice versa.
  3. La bibliothèque est également très pressée par le temps. La requête if (sim808.getGPS()) peut éventuellement devenir une fausse piste.
  4. Les noms de variables commençant par LAT font référence à la géo. Latitude ;
    Les noms de variables commençant par LON font référence à la géo. {Longitude).
  1. Le décalage doit être saisi pour CET/CEST. Lors de la conversion de l'heure, le changement de date est pris en compte, mais pas le mois et l'année (effort).

Le croquis:


#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>
#define PIN_TX    17
#define PIN_RX    18

//  LCD has no I2C-Adapter, data transfer with Pins D4 to D7 
#include <LiquidCrystal.h>
//LCD pin to Arduino
//const int pin_BL = 15; 
const int pin_EN = 9; 
const int pin_RS = 8; 
const int pin_D4 = 4; 
const int pin_D5 = 5; 
const int pin_D6 = 6; 
const int pin_D7 = 7;

LiquidCrystal lcd( pin_RS,  pin_EN,  pin_D4,  pin_D5,  pin_D6,  pin_D7);

// Offset for Time, here UTC zu MEZ / MESZ
// Summertime MESZ: 2, Wintertime MEZ: 1
#define Offset 1

SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial); //Connect RX,TX,PWR

// unterbrechungsfreie Zeitsteuerung
unsigned long previousMillis = 0;
const long interval = 10;

// Buttons
int buttonInput = -1;
int buttonSelect = 0;

void setup() {
  mySerial.begin(9600);
  Serial.begin(9600);
  lcd.begin(16,2); // initialize the lcd
  lcd.clear();
  lcd.setCursor(0,0); //Zählung beginnt bei Null, erst Zeichen, dann Zeile
  lcd.print("AZ-Delivery.com");
  lcd.setCursor(0,1); // 0=Erstes Zeichen, 1=zweite Zeile


 //******** Initialize sim808 module *************
  while(!sim808.init()) {
    delay(1000);
    Serial.print("Sim808 init error\r\n");
  }
//************* Turn on the GPS power************
if( sim808.attachGPS())
  Serial.println("Open the GPS power success");
else
  Serial.println("Open the GPS power failure");
}

void loop() {


buttonInput = Button();
  switch (buttonInput) {
    case 0: Serial.println("0");buttonSelect=0; break;
    case 1: Serial.println("1");buttonSelect=1; break;
    case 2: Serial.println("2");buttonSelect=2; break;
    case 3: Serial.println("3");buttonSelect=3; break;
    case 4: Serial.println("4");buttonSelect=4; break;
    default: break;
  }

if (millis() - previousMillis >= interval) {
  //************** Get GPS data *******************
    if (sim808.getGPS()) {
    int MONTH = sim808.GPSdata.month;
    int DAY = sim808.GPSdata.day;
    int DAYLCL = DAY;
    int HOUR = sim808.GPSdata.hour;
    int HOURLCL = HOUR + Offset;
    int MINUTE = sim808.GPSdata.minute;
    int SECOND = sim808.GPSdata.second;
    if (HOURLCL>24) {
      HOURLCL = HOURLCL-24;
      DAYLCL = DAYLCL + 1; }
    Serial.print(sim808.GPSdata.year);
    Serial.print("/");
    Serial.print(MONTH);
    Serial.print("/");
    Serial.print(DAY);
    Serial.print(" ");
    Serial.print(HOUR);
    Serial.print(":");
    Serial.print(MINUTE);
    Serial.print(":");
    Serial.println(SECOND);
    float LAT = sim808.GPSdata.lat;
    int LATDD = int(LAT);
    float LATMMmmmm = (LAT - LATDD)*100;
    float LON = sim808.GPSdata.lon;
    int LONDDD = int(LON);
    float LONMMmmmm = (LON - LONDDD)*100;
    Serial.print("latitude: ");
    Serial.print(LATDD);
    Serial.print("°");
    Serial.print(LATMMmmmm,4);
    Serial.println("'N");
    Serial.print("longitude: ");
    if (LON<100.0) Serial.print("0");
    if (LON<10.0) Serial.print("0");
    Serial.print(LONDDD);
    Serial.print("°");
    Serial.print(LONMMmmmm,4);
    Serial.println("'E");
    float SPEED = sim808.GPSdata.speed_kph;
    if (SPEED >= 3.0) {
      Serial.print("speed_kph: ");
      Serial.println(SPEED);
      Serial.print("heading: ");
      Serial.println(sim808.GPSdata.heading); }
    else {
      Serial.print("speed_kph :");
      Serial.println("below 3");
      Serial.print("heading :");
      Serial.println("not determined"); }

 if (buttonSelect==0) {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(LATDD);
      lcd.print("\xDF");
      int LATMM = int(LATMMmmmm);
      float LATSSs = (LATMMmmmm-LATMM)*60;
      lcd.print(LATMM);
      lcd.print("'");
      lcd.print(LATSSs,1);
      lcd.print("\x22\ N");
      lcd.setCursor(0,1);
      if (LON<100.0) lcd.print("0");
      if (LON<10.0) lcd.print("0");
      lcd.print(LONDDD);
      lcd.print("\xDF");
      int LONMM = int(LONMMmmmm);
      float LONSSs = (LONMMmmmm-LONMM)*60;
      if (LONMM<10) lcd.print("0");
      lcd.print(LONMM);
      lcd.print("'");
      if (LONSSs<10.0) lcd.print("0");
      lcd.print(LONSSs,1);
      lcd.print("\x22\ E"); }

    else if (buttonSelect==1) {
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("EUR: ");
       if (DAYLCL<10) lcd.print("0");
       lcd.print(DAYLCL);
       lcd.print(".");
       if (MONTH<10) lcd.print("0");
       lcd.print(MONTH);
       lcd.print(".");
       lcd.print(sim808.GPSdata.year);
       lcd.setCursor(5,1);
       if (HOURLCL<10) lcd.print("0");
       lcd.print(HOURLCL);
       lcd.print(":");
       if (MINUTE<10) lcd.print("0");
       lcd.print(MINUTE);
       lcd.print(":");
       if (SECOND<10) lcd.print("0");
       lcd.print(SECOND);
     }
    else if (buttonSelect==2) {
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("UTC: ");
       lcd.print(sim808.GPSdata.year);
       lcd.print("/");
       if (MONTH<10) lcd.print("0");
       lcd.print(MONTH);
       lcd.print("/");
       if (DAY<10) lcd.print("0");
       lcd.print(DAY);
       lcd.setCursor(5,1);
       if (HOUR<10) lcd.print("0");
       lcd.print(HOUR);
       lcd.print(":");
       if (MINUTE<10) lcd.print("0");
       lcd.print(MINUTE);
       lcd.print(":");
       if (SECOND<10) lcd.print("0");
       lcd.print(SECOND);
     }
    else if (buttonSelect==3) {
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print(LATDD);
       lcd.print("\xDF");
       lcd.print(LATMMmmmm,4);
       lcd.print("' N");
       lcd.setCursor(0,1);
       if (LON<100.0) lcd.print("0");
       if (LON<10.0) lcd.print("0");
       lcd.print(LONDDD);
       lcd.print("\xDF");
       if (LONMMmmmm<10.0) lcd.print("0");
       lcd.print(LONMMmmmm,4);
       lcd.print("' E"); }
     else if (buttonSelect==4) {
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("AZ-Delivery.com"); }
       //
    // //************* Turn off the GPS power ************
    // sim808.detachGPS();
    previousMillis = millis();
    }
  }
}


int Button() {
  int A0;
  // all buttons are connected to A0 via voltage divider
  // Values of ADC are between 0 and 1023
  // if necessary, values must be changed slightly
  A0 = analogRead(0); //
  if (A0 < 60) {
    return 0;
  }
  else if (A0 >= 60 && A0 < 250) {
    return 1;
  }
  else if (A0 >= 250 && A0 < 450){
    return 2;
  }
  else if (A0 >= 450 && A0 < 700){
    return 3;
  }
  else if (A0 >= 700 && A0 < 900){
    return 4;
  }
  else {
    return -1;
  }
}   //end Button()


Alors, cher lapin de Pâques, avec ce sketch, vous pouvez cacher les œufs de Pâques et donner aux enfants des indices pour savoir où chercher. Les chercheurs devront attendre le prochain croquis, lorsque nous calculerons la direction (parcours) et la distance des points de repère.

AmateurfunkDisplaysFür arduinoProjekte für anfänger

9 commentaires

Bernd Albrecht

Bernd Albrecht

Die Wahl fiel auf das SIM808, weil hier GPS und GSM vereint sind. Im Blog-Beitrag (Teil 3) zeige ich, wie man per SMS die Positionsmeldung triggern kann.
https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/positionsmeldung-mit-gps-und-sms-gps-gsm-sim-808-teil-3

Klaus

Klaus

Inetessantes Projekt, würde es gern meinem Hund anhängen, wenn die Akkus nicht zu schwer würden.
Kann das Projekt auch mit dem SIM900 realisiert werden? Auch bis zum 3. Teil? Wenn ja, warum fiel die Wahl auf SIM808?
Welches ist neuer, welches stromsparender?
Würde mich über eine Antwort freuen, weil fertige Produkte nur mit der Cloud des Herstellers funktionieren und ein meist teures Abo voraussetzen.

Dirk Harms

Dirk Harms

Sehr schönes Projekt, meine Kinder freuen sich schon ;-)
Falls auf dem Display nichts erscheint – einfach mal den Kontrast am Poti verändern.

Bernd Albrecht

Bernd Albrecht

Danke an Ingo für den Hinweis und die Lösung des Problems. Ich hatte schon die Sim-Karte eingesteckt für den dritten Teil der Blog-Reihe. Deshalb ist mir diese unüberwindliche Hürde nicht aufgefallen. Tatsächlich funktioniert der Sketch mit den folgenden Zeilen nur, wenn eine Sim-Karte eingesteckt ist.
//******** Initialize sim808 module *************
while(!sim808.init()) {
delay(1000);
Serial.print(“Sim808 init error\r\n”);
}
Deshalb: Wer den Sketch ohne Sim-Karte benutzen möchte, diese Zeilen bitte auskommentieren.

Reinhard Völler

Reinhard Völler

Ich bekomme leider das LCD Display Shield nicht zum laufen. Habe im Sketch mal alles auskommentiert, was nichts mit dem LCD zu tun hat, aber “AZ-Delivery” erscheint bei mir nicht. Auch die angepassten Beispiele aus der Liquidcrystal Library funktionieren bei mir nicht. Ich habe D4-D7 auf 4-7 gesetzt, EN=9, RS=8. Hintergrundbeleuchtung ist an. Was mache ich da falsch?

Ingo

Ingo

Ich habe das ganze mal bei mir aufgebaut. Bekomme aber immer Sim808 init error. Kann es sein das die Funktion while(!sim808.init()) { nur funktioniert wenn eine SIM Karte eingelegt ist? Wenn ich diesen Teil auskommentiere läuft alles einwandfrei.
Viele Grüße Ingo

Juergen

Juergen

Hallo,
schöner Bericht, danke dafür.
Es wäre noch ganz hilfreich wenn man einen Anschlussplan bekommen könnte, um zu wissen wie die Komponenten verbunden werden sollen.
mfg

Jürgen

Jürgen

So etwas in der Art stand schon lange auf meiner ToDo-Liste.
Ich denke, ich werde, das mit dieser Superunterstützung jetzt
auch mal in Micropython versuchen.
Schönen Gruß
Jürgen

Reinhard Völler

Reinhard Völler

Witziges Projekt, habe ich gleich mal geordert.
Ein Hinweis, dass man die Library auf github findet, wäre vielleicht hilfreich:
https://github.com/DFRobot/DFRobot_SIM808
Gruß an den Osterhasen :-)

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés

Articles de blog recommandés

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery