ESP32 LoRa mit GPS erweitern

Das ESP32-LoRa Board eignet sich sehr gut dazu mit einem GPS-Modul erweitert zu werden. Die Verdrahtung ist sehr einfach, da lediglich eine serielle Schnittstelle erforderlich ist. Die Daten vn GPS Modul können am integrierten OLED Display angezeigt werden.

Zum Aufbau benötigen wir ein Nodemcu ESP32 mit integriertem OLED Display und ein GPS-Modul mit aktiver Antenne. Für einen mobilen Betrieb sollte man einen geeigneten LiPo Akku mit 3.7 V einsetzen.

Zusätzlich fügen wir einen Taster hinzu. Wenn man diesen Taster drückt soll sich das Gerät die aktuellen Koordinaten merken und dann in Folge die Entfernung zu diesem Punkt sowie die Himmelsrichtung in der dieser Punkt zu finden ist anzeigen.

Neben diesen Daten zeigt das Gerät das genaue Datum und die Uhrzeit (UTC !) an. Darunter die Breiten und Längengrade sowie die Geschwindigkeit. Wenn durch drücken der Taste ein Referenzpunkt gespeichert wurde, zeigt das Gerät noch Distanz und Richtung zu diesem Referenzpunkt an. Unten rechts wird die Anzahl der gerade empfangbaren Satelliten angezeigt.

 

 

Sketch:

 

#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"
#include <TinyGPS.h>
;
#include<Arduino.h>

//Instanzen für die serielle Schnittstelle, das Display und das GPS Modul
HardwareSerial Serial1(1);
SSD1306  display(0x3c, 4, 15);
TinyGPS gps;

//Pin für den Taster
#define btn 23

//Deutsche Monatsabkürzungen
String monat[12] {"Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"};

//Globale Variablen für die laufende Position und für die Position des Referenzpunktes
float fslat = 0, fslon = 0, flat, flon;

//Warteschleife, die ankommende Daten vom GPS Modul verarbeitet und den Status des Tasters prüft
static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    if (!digitalRead(btn)) {
      fslat = flat; 
      fslon = flon;

    }
    while (Serial1.available())
      gps.encode(Serial1.read());
  } while (millis() - start < ms);
}

//Das Datum und die Uhrzeit vom GPS Modul anzeigen
void display_date(TinyGPS &gps, uint8_t x, uint8_t y){
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  char mnc[3];
  String mns;
  //diese Funktion von Tiny-GPS gibt Datum und Zeit aufgeasplittet in einzelne Variablen zurück
  //die Zeit ist im UTC Format, das heißt für die MEZ muss man 1 oder mit Sommerzeit 2 Stunden addieren
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    //wenn das Display diese Sterne anzeigt, weiß man dass das GPS Modul noch keine gültigen Daten geliefert hat
    display.drawString(x,y,"********** ******** ");
  else
  {
    //Monat als Abkürzung stattb Zahl anzeigen
    char sz[32];
    mns=monat[month-1];
    mns.toCharArray(mnc,4);
    sprintf(sz, "%02d.%3s.%02d %02d:%02d:%02d ",
        day, mnc, year, hour, minute, second);
    display.drawString(x,y,sz);
    Serial.println(sz);
  }
  smartdelay(0);
  
}


void setup() {
  //Display zurücksetzen
  pinMode(16,OUTPUT);
  digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
  delay(50); 
  digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high
  
  //serielle Schnittstelle starten
  Serial.begin(115200);
  Serial.println("Start");
  //serielle Schnittstelle zur Kommunikation mit dem GPS Modul starten
  //es werden nicht die Standard IO-Pins 9 und 10 sondern die IO-Pins 12 und 13 verwendet
  Serial1.begin(9600,SERIAL_8N1,12,13);
  //Pin  für Taster vorbereiten
  pinMode(btn,INPUT_PULLUP);
  // Display initialisieren
  display.init();
  //Display auf Querformat
  display.flipScreenVertically();
  display.clear();
  //Text Parameter
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_10);
  Serial.println("Setup fertig");
}

void loop() {
  float crs, fspd;
  uint8_t cx,cy;
  uint32_t dist;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  char tmp[32]; //Buffer für Ausgabe
  //Position vom GPS Modul lesen
  gps.f_get_position(&flat, &flon, &age);
  //Anzeige vorbereiten
  display.clear();
  //Datum und Uhrzeit anzeigen
  display_date(gps,0,0);
  //Breitengrade anzeigen
  sprintf(tmp,"Breite:  %10.6f °",flat);
  //Längengrade anzeigen
  display.drawString(0,10,tmp);
  sprintf(tmp,"Länge:  %10.6f *",flon);
  //Geschwindigkeit anzeigen
  display.drawString(0,20,tmp);
  sprintf(tmp,"Geschw.: %6.2f km/h",gps.f_speed_kmph());
  display.drawString(0,30,tmp);
  //Weitere Anzeigen nur wenn ein Referenzpunkt gesetzt wurde
  if (fslon > 0) {
    //Abstand zum Referenzpunkt anzeigen
    dist = gps.distance_between(flat, flon, fslat,fslon);
    if (dist >1000) {
      //größer als 1000 in km
      sprintf(tmp,"Distanz:  %8.2f km",dist/1000);
    } else {
      //sonst in m
      sprintf(tmp,"Distanz:  %8d m",dist);
    }
    display.drawString(0,40,tmp);
    //Richtung zum Referenzpunkt
    sprintf(tmp, "Richtung: %5s",gps.cardinal(gps.course_to(flat, flon, fslat, fslon)));
    display.drawString(0,50,tmp);
  }
  //Anzahl der Satelliten
  sprintf(tmp,"%3d",gps.satellites());
  display.drawString(100,50,tmp);    

  //Display aktualisieren
  display.display();
  //5 Sekunden warten
  smartdelay(5000);
}

 

Viel Spass beim experimentieren

 

Letzter Artikel ESP Easy
Neuer Artikel Sleep Timer ESP32

Hinterlasse einen Kommentar

Kommentare müssen vor der Veröffentlichung überprüft werden

Erforderliche Angabe