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

This year we want to support the Easter bunny to hide Easter eggs, which will also be recovered. For this we equip him (and later the seekers) with a GPS receiver. Hiding and reading the position is the lightest part, because the values ​​are displayed on our display and only need to be noted. But we also have to give him a basic understanding of our earth, so, Easter bunny: pay attention. 

Next time, the search will show us bigger challenges, because first we must determine the current position and then calculate course and distance to the destination. This requires a degree of mathematics knowledge, but in which we can make some simplifications in Germany or Central Europe due to short distances.

If we no longer need the GPS receiver for the search of Easter eggs or geocaching, we will build a tracking system in the third part, because we have a combined GPS / GSM module, with which we can also send the position via SMS to a smartphone.

What do we need?

Number Component
1 Micro Controller, e.g. The UNO R3 compatible MC
1 LCD, e.g. the LCD-Keypad-Shield
1 GPS/GSM module SIM 808 (in the third part with SIM card)
Battery or battery


In order not to blow up the framework of the contribution, I refer to the eBooks for the sim 808 and keypad-shield details, which are linked on the respective product page.


Who knows exactly what 54 ° 30'N 009 ° 15'E means can fly over the following paragraphs. Who is not, now learns our coordinate system on earth.

The earth looks like the fruit orange (only blue instead of orange), almost spherical, to the poles minimally flattened. To determine a point on the surface, smart people finally agreed on a uniform coordinate system. The earth turns on one day once around its own axis. We define this axis of rotation as the axis of the earth through the two poles and halve the ball with an imaginary line with name equator. Then we define the geographical width as the angle at the earth's midpoint between equator and our place. Germany is between 47 ° 16 '18 "and 55 ° 03' 31.1" ° Northern latitude. The poles are then 90 ° Nord or South; Southern latitude is often displayed with minus signs. The determination of the geographical length was difficult because every king wanted to have the zero line through his throne (e.g., the rose line at Dan Brown's "Da Vinci Code"). Finally, the observatory in Greenwich near London was set  as a reference meridian. Once around the earth are 360 ​​°, each 180 ° to the east and west; The western lengths possibly again with minus signs. Germany is between 005 ° 52 '01 "and 015 ° 02' 37"  Eastern longitude. The dates line (usually at 180 ° E / W) runs through the Pacific Ocean.

Image: Earth globe with latitude and longitude lines

The longitude lines are great circles that run from pole to pole. Great circles are circles on the globe around the earth's midpoint; The shortest route between two points runs along this circle through these points. The equator is the only latitude line that is a great circle, direction Pole the radius or perimeter of the latiitude becomes smaller . Who knows the function, which is at 0 ° maximum (= 1) and at 90 ° minimally (= 0)? Coming later, when we need to know a little more about trigonometry. Navigation has a lot to do with mathematics.

For a better understanding of the planet Earth you should look at a globe (best with interior lighting), but for navigation, we usually take a map, a flat piece of paper with the area in which we move. In the seafaring: Always take the map with the largest scale available, but what is bigger? 1: 2,000,000 or 1: 50,000? The first map matches 10 cm 200 km in reality, at the second, the 10cm is only 5 km. The second is therefore more detailed. The small scales (convergers) are used for route planning, the set of maps with the larger scales in conducting the tour. Today you do that with a touch screen, where you change the scale with two fingers.

To get a map, a two-dimensional image of the earth's surface, we use (but also Google Maps et al.) the methods of Gheert Cremer, better known as Gerhard Mercator (1512 - 1594) and Johann Heinrich Lambert (1728 - 1777). Mercator has described the so-called cylinder projection, Lambert the (cut) cone projection.

At the Mercator projection, a cylinder is pushed over the ball, in our wide axis parallel. The poles are not mapped and the island of Greenland looks bigger than the continent Africa. The picture is therefore not length or space-faith and unusable near the poles. But it will guide us good enough in Central Europe with short to medium distances .

Projection types: Left cylinder proj. (Mercator), right (cut) cone-projection (Lambert)

In the Lambert's cut cone projection, a cone is attached to the pole, which cuts the ball e.g. at 60 ° northern latitude, ie extends within the ball, and again at 30 degrees north latitude. This is (especially near the latitudes / cutting lines) the best compromise with regard to length, surface and angular loyalty, but nothing is true 100%. The ideal map for pilots, which are usually enroue on larger distances than the geocacher.

On these images of the earth's surface we then paint our auxiliary lines and so can determine every place with its geographical latitude (how much degrees north of the equator?) and longitude (how many degrees east of the observatory in Greenwich?) Or vice versa from the figures.

The actual difficulties start in detail, because there are different formats; And we want to have the location as exactly as possible. The angle in steps of 1° means an accuracy of 111 km, somewhere between Würzburg and Nuremberg. A finer subdivision was then made with the arc minutes. The word minute suggests that the number 60 comes into play. 1 ° (say: degree) equals 60 '(say: (arc) minutes.

Here we note in our long-term memory: an arc-minute at the Meridian (longitude circle) corresponds to a nautical mile or 1.852km.

Still too inaccurate for our search. So further divide into (arc) seconds (again with a factor 60) or after the decimal system. Both are possible and usual, you just have to control the conversion. The Geocachers prefer the format DDMM.mmmm, so the degree number (Degrees) double-digit, then the minutes double-digit and the fractions as decimal of the minutes here with small "m" shown. Alternatively, there are DDMMSSsss, so degrees (DD), minutes (MM), seconds (SS) and decimal of seconds (ss). For the conversion we only need the already mentioned number 60, ie e.g. 30 arc seconds correspond to 30/60 = ½ arc minute. Otherwise 0.8 arc minutes correspond to 0.8 * 60 = 48 arc seconds.


The following sketch should select the correct ones from the variety of data that our GPS receiver reports. If we connect our GPS receiver to a terminal program, the following information is obtained every second:


We quickly recognize that the interesting data stands in the lines that start with $ GPGGA and "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

The program library used by us in the sketch evaluates the bold line, which starts with GPRMC. However, the essential information is also in the other line. GP stands for Global Positioning System (GPS) and RMC for Recommended Minimum Navigation Information. (Source: https://de.wikipedia.org/wiki/NMEA_0183, http://www.nmea.de/nmea0183datensaetze.html#rmc)

Then follows:

1) Universal Time Coordinated (UTC) (previously known as Greenwich Mean Time (GMT))
2) Latitude (format DDMM.mmmm)
3) N OR S (North Or South)
4) Longitude (format DDDMM.mmmm)
5) E or W (East Or West)
6) GPS Quality Indicator, 0 - Fix Not Available, 1 - GPS Fix,
2 - Differential GPS Fix
7) Number of satellites in view, 00 - 12
8) Horizontal Dilution of Precision
9) Antenna Altitude Above / Below Mean Sea Level (Geoid)
10) Units of Antenna Altitude, Meters

In the case of the hardware, I had decided on the LCD-Keypad-Shield, in which you can quickly switch between different views using the buttons of the keypad. We use the left button for the position in the format DDMM.mmmm, Down for Date and Time in Universal Time Coordinated (UTC), UP for our time zone and right for the position in the DDMMSS.s format; We use the Select Button next time for course and distance.

Preliminary remarks on the sketch:

  1. For the GPS receiver I use software serial to A3 = GPIO 17 and A4 = GPIO 18.
  2. The library used for the conversion of arc seconds in decimal of the arc minutes and vice versa has a bug. Do not use.
  3. The library is also very time-critical. The query if (sim808.getGPS ())  may become a stumbling block.
  4. Variable names beginning with LAT relate to the Geo. Latitude;
    Variable names starting with LON relate to the Geo. Longitude.
  1. For MEZ / MESZ, offset must be entered. When converting the time, the date change is taken into account, but not month and year (time and effort).

The sketch:

#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 to MEZ/ MESZ
// Summertime Mesz: 2, Winter Time Mez: 1
#Define offset 1

SoftwareSerial mySerial (pin_tx, pin_rx);
Dfrobot_sim808 SIM808 (& mySerial); // Connect RX, TX, PWR

// Uninterrupted timing
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); // Count starts at zero, first sign, then line
lcd.print ("az-delivery.com");
LCD.SetCursor (0.1); // 0 = First sign, 1 = second line

// ******** Initialize SIM808 Modules *************
While (! Sim808.init ()) {
Delay (1000);
Serial.Print ("SIM808 Init Error \ 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) {
// ************** GPS Data *******************
IF (SIM808.GETGPS ()) {
INT MONTH = SIM808.GPSDATA.MONTH;
INT DAY = SIM808.GPSDATA.DAY;
INT DALLCL = 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 ()


So, dear Easter bunny, with this sketch you can hide the Easter eggs and give the children hints where they need to look for. The seekers need to be patient until the next sketch, when we will program direction and distance to the waypoints.


AmateurfunkDisplaysFor arduinoProjects for beginners

9 comments

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 :-)

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN