Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Zuverlässiger GPS-Tracker fürs Auto mit Thinger.io Echtzeit-Karte

Benötigte Bauteile

Arduino Leonardo Wichtig: dedizierter Hardware-Serial (Serial1) für GPS 1
SIM900 Development Board GSM/GPRS (auch SIM800 kompatibel, ungetestet) 1
u-blox NEO-6M GPS-Modul Mit Antenne 1
GPS-Antenne Qualität beachten – billige Antennen oft schlechter Empfang 1
Widerstand 220 Ω Für Status-LEDs 2
LED (beliebig) Power & GPS-Lock Anzeige 2
Lochrasterplatine 7×5 cm Für LED-Schaltung (passt in 3D-Gehäuse) 1
12 V → 5 V Step-Down Modul Für Auto-Bordnetz / Zigarettenanzünder 1
MicroSD-Kartenleser (Adafruit, 5 V tolerant) SPI-Interface 1
MicroSD-Karte FAT32 formatiert 1

Benötigte Werkzeuge

Software & Dienste

Projektfunktionen

Warum Arduino Leonardo?

Zwei serielle Schnittstellen nötig: Hardware-Serial (Serial1) für GPS (9600 Baud), Software-Serial für SIM900 (Pins 8/9). Uno hätte nur einen Hardware-Serial – GPS müsste zum Flashen abgeklemmt werden, kein Debug-Monitor.

Bibliotheks-Konfiguration

NeoGPS einrichten

Datei GPSport.h im NeoGPS-Installationsordner komplett ersetzen:

#ifndef GPSport_h
#define GPSport_h
#define gpsPort Serial1
#define GPS_PORT_NAME "Serial1"
#define DEBUG_PORT Serial
#endif

Bei anderen Boards (Mega: Serial2/Serial3) hier anpassen.

PetitFS einrichten

Datei pffArduino.h: SD_CS_PIN auf 10 setzen (SPI SS).

Datei pffconf.h: Folgende Optionen deaktivieren (0 setzen) für kleinere Binary:

Erster Kompilierfehler (fehlender Return-Typ in pff.cpp) ignorieren oder FRESULT als Return-Typ ergänzen.

SD-Karte vorbereiten

  1. Als FAT32 formatieren (offizielles „SD Card Formatter“ Tool).
  2. Dateien dist.txt (Startwert Kilometer, z. B. „0“) und settings.txt (Trigger-Distanz in Metern, z. B. „4000000“) auf Karte kopieren. Exakt die mitgelieferten Referenzdateien nutzen – PetitFS ist pingelig bei Format/Länge.
  3. Test: Sketch starten, Serial Monitor prüfen – Kilometerstand & Trigger werden gelesen.

SIM900 vorbereiten

Code-Anpassungen (vor Upload)

Thinger.io Integration

  1. Account erstellen → „Bucket“ anlegen (Datenbank).
  2. „HTTP Device“ anlegen (Doku: thinger.io HTTP Devices).
  3. Device Callback → Settings: „Write Bucket“ auf eigenen Bucket zeigen.
  4. Callback Overview: Method URL & Authorization Header (ohne „Bearer“) notieren.
  5. Im Code: URL & Key in postDataThinger() einsetzen. Kurzgerätenamen wählen (langer Name → langer Key → Pufferüberlauf >256 Byte).
  6. Erfolg: Serial Monitor zeigt +HTTPACTION: 1,200,0.
  7. Dashboard: Maps-Widget mit Bucket als Datenquelle.

Zusätzliche Daten an Thinger senden

Im sprintf(httpContent, ...) weitere Felder im JSON ergänzen: {"longitude":%s,"latitude":%s,"date":"%s %s","speed":%s,...}. Exakte Bytezahl in AT+HTTPDATA=len,10000 anpassen.

3D-Gehäuse

Stromversorgung im Auto

Anschluss an „Zigarettenanzünder“-Stromkreis (schaltet mit Zündung) – Gerät läuft nur bei laufendem Auto. Für Diebstahlschutz (Tracker auch bei ausgeschaltetem Auto) Direktanschluss an Batterie + Puffer-Akku. Step-Down (12 V → 5 V, 2× USB) versorgt Arduino & SIM900. Verbrauch ca. 110 mA (GSM aktiv), mehr bei schlechtem Empfang.

Bekannte Probleme

Code (Haupt-Sketch: GPS_tracker_Leonardo_v2.ino)

#include <SoftwareSerial.h>
#include <NMEAGPS.h>
#include <GPSport.h>
#include <TimeLib.h>
#include "PF.h"
#include "PetitSerial.h"

#define UTC_OFFSET 1
#define TXPin 8
#define RXPin 9
#define PWRPin 7
#define DEFAULT_NUMBER "+49123456789"

FATFS fs;
String textMessage, number = DEFAULT_NUMBER;
char sms_msg[160];
float Lat = 0, Long = 0;
boolean valid_location = false;
uint8_t num_sat;
NeoGPS::Location_t prevFix;
NMEAGPS gps;
gps_fix fix;
const char *googlePrefix = "https://maps.google.com/maps?q=";
const char *filename = "DIST.TXT";
const char *settings = "SETTINGS.TXT";
NeoGPS::time_t timeFix;
char datePrint[13], timePrint[10];
float totalDistance = 0;
float triggerDistance = 4000000;
SoftwareSerial SIM900(TXPin, RXPin);

void setup() {
  pinMode(3, OUTPUT); pinMode(4, OUTPUT);
  digitalWrite(3, HIGH); // Power LED
  Serial.begin(9600);
  // while (!Serial); // Nur für Debug!
  SIM900.begin(9600);
  gpsPort.begin(9600);
  initializeSD();
  SIM900power();
  SIM900.println(F("AT")); delay(500); updateSIM900();
  SIM900.println(F("AT+CMGF=1")); delay(500); updateSIM900();
  SIM900.println(F("AT+CNMI=1,2,0,0,0")); delay(500); updateSIM900();
  connectGPRS();
}

void loop() {
  while (gps.available(gpsPort)) {
    fix = gps.read();
    num_sat = fix.satellites;
    if (fix.valid.location) {
      digitalWrite(4, HIGH); // GPS Lock LED
      Lat = fix.latitude(); Long = fix.longitude();
      if (Lat != 0 && Long != 0 && !valid_location) {
        valid_location = true; prevFix = fix.location;
      }
    }
    if (fix.valid.date && fix.valid.time) {
      timeFix = fix.dateTime; updateTime();
    }
    if (valid_location) {
      // Distanz-Update alle 15 s
      static const unsigned long REFRESH_INTERVAL_UPD = 15000;
      static unsigned long lastRefreshTime = millis();
      if (millis() - lastRefreshTime >= REFRESH_INTERVAL_UPD) {
        lastRefreshTime += REFRESH_INTERVAL_UPD;
        float distanceDelta = prevFix.DistanceKm(fix.location) * 1000;
        if (distanceDelta > 10 && distanceDelta < 10000) totalDistance += distanceDelta;
        prevFix = fix.location;
      }
      // SD-Schreiben & Thinger-Upload alle 2 Min
      static const unsigned long REFRESH_INTERVAL_WRITE_SD = 120000UL;
      static unsigned long lastRefreshTimeWriteSD = millis();
      if (millis() - lastRefreshTimeWriteSD >= REFRESH_INTERVAL_WRITE_SD) {
        lastRefreshTimeWriteSD += REFRESH_INTERVAL_WRITE_SD;
        char buf[9]; dtostrf(totalDistance, 8, 0, buf);
        if (PF.open(filename)) Serial.println(F("error open file"));
        while (1) {
          UINT nr;
          if (PF.writeFile(buf, sizeof(buf), &nr)) Serial.println(F("error write file"));
          if (nr == sizeof(buf)) { PF.writeFile(0, 0, &nr); break; }
        }
        // HTTP POST an Thinger
        char httpContent[60], tempstrLong[10], tempstrLat[10];
        dtostrf(Lat, 2, 6, tempstrLat); dtostrf(Long, 2, 6, tempstrLong);
        sprintf(httpContent, "{\"longitude\":%s,\"latitude\":%s,\"date\":\"%s %s\"}", tempstrLong, tempstrLat, datePrint, timePrint);
        char httpdataLen[20]; sprintf(httpdataLen, "AT+HTTPDATA=%i,10000", strlen(httpContent));
        postDataThinger(httpdataLen, httpContent);
      }
    }
  }
  // Odometer-Trigger SMS
  if (totalDistance > triggerDistance) {
    char distanceTotalMsg[10];
    itoa((totalDistance / 1000), distanceTotalMsg, 10);
    sprintf(sms_msg, "Empty catchtank! Current distance: %skm", distanceTotalMsg);
    textMessage = ""; number = DEFAULT_NUMBER; totalDistance = 0;
    sendSMS(sms_msg);
  }
  updateSerial();
}

// ... Hilfsfunktionen: updateSerial(), SIM900power(), updateSIM900(), extractSenderNumber(),
// sendSMS(), connectGPRS(), postDataThinger(), initializeSD(), updateTime() ...
// (Vollständiger Code im Original-Projekt)

Dateien im Projekt

Herstellungsprozess

  1. Bügelbrett-Fertigung: Design, Materialien und Produktionsprozess
  2. Surfboard-Konstruktion und Design: Von polynesischen Wurzeln zur modernen Innovation
  3. Outdoor GPS Asset Tracking: Trends, Challenges, Emerging Technologies
  4. Raspberry Pi stellt RP2040 MCU und 4-Dollar Pico Board vor
  5. Sensordaten in Raspberry Pi integrieren: GPS & MPU-9150 Hands-On Guide
  6. PSoC 6 Pioneer Board mit IoT Add-On Shield meistern: Entwickler-Leitfaden
  7. COVID-19-Medikamenten-Repurposing mit BIOVIA Living Map beschleunigen
  8. Pythons map()-Funktion meistern: Syntax, Beispiele und Best Practices
  9. Interne Integrationssysteme nutzen für Präzisionsfertigung
  10. Risiken des Fahrens mit zu niedrigem Kühlmittelstand