Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Registrador GPS Avanzado: Seguimiento de Vuelo en Tiempo Real, Monitor de Altitud y Velocidad Máxima

Componentes y suministros

ComponenteCantidad
Arduino UNO1
Jumpers (Barra de bus), Set de cables jumper1
Arduino Proto Shield1
Pantalla TFT SPI 1.8" con zócalo MicroSD (o similar con tarjeta SD)1
Módulo GPS u-blox NEO-6M1

Herramientas y máquinas necesarias

Sobre el proyecto

Introducción

Practico aeromodelismo y me gusta conocer la velocidad y altitud de mis aviones. Desafortunadamente, los registradores GPS comerciales son muy caros.

Por eso decidí construir mi propio registrador de datos GPS basado en Arduino por menos de 50€.

Mi primer prototipo utiliza un Arduino Uno R3 con una pantalla Sainsmart ST7735 (con ranura SD integrada) y un módulo GPS NEO 6M V2.

En una segunda versión planeo usar un Arduino Nano con pantalla OLED SSD1306, el mismo módulo GPS y una tarjeta microSD. El peso con carcasa debería ser de unos 40 gramos, fácil de integrar en un avión mediano (dimensiones aprox. 50×30×22 mm). Este será mi próximo proyecto (estoy esperando los materiales).

Pruebas

No es fácil filmar la pantalla del Arduino dentro de un coche, pero lo hice y puedes ver el resultado en el video.

La próxima prueba será con el nuevo prototipo, más pequeño y ligero, en un avión radiocontrolado. ¡Continuará!

Código

Registrador GPS (versión básica)

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#define cs 10
#define dc 9
#define rst 8
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
static const int RXPin = 4, TXPin = 3; // Comunicación GPS
static const uint32_t GPSBaud = 9600;
#define OLED_RESET 5

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

int x = 80, xh = 80;
int maxhigh = 0;
int maxspeed = 0, speed1 = 0;
int high1 = 0;

void setup() {
  Serial.begin(9600);
  ss.begin(GPSBaud);
  tft.initR(INITR_GREENTAB);
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(5, 58);
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
  tft.print("inicializacion");
}

void loop() {
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
  
  while (ss.available() > 0) {
    gps.encode(ss.read());
    if (gps.location.isUpdated()) {
      dibujarMarco();
      
      // Latitud y longitud
      tft.setCursor(5, 44);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("Latitud: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.location.lat(), 6);
      
      tft.setCursor(5, 58);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("Longitud: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.location.lng(), 6);
      
      // Fecha
      tft.setCursor(5, 7);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("fecha: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.date.day()); tft.print(" ");
      tft.print(gps.date.month()); tft.print(" ");
      tft.print(gps.date.year());
      
      // Hora
      tft.setCursor(5, 20);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("hora: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.time.hour()+1); tft.print(" ");
      tft.print(gps.time.minute()); tft.print(" ");
      tft.print(gps.time.second()); tft.print(" ");
      
      // Altitud actual
      tft.setCursor(5, 80);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("H m: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.altitude.meters(), 0);
      
      // Altitud máxima
      tft.setCursor(5, 95);
      actualizarAltitudMax();
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("Hmax: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(maxhigh);
      graficarAltitud();
      
      // Velocidad actual
      tft.setCursor(5, 115);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("V act: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.speed.kmph(), 0);
      
      // Velocidad máxima
      tft.setCursor(5, 130);
      actualizarVelocidadMax();
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("vmax: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(maxspeed);
      graficarVelocidad();
      
      // Satélites
      tft.setCursor(5, 147);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("Sat: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.satellites.value());
      
      // HDOP
      Serial.print("HDOP = ");
      Serial.println(gps.hdop.value());
      
      smartDelay(400);
    }
  }
}

static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  do {
    while (ss.available()) gps.encode(ss.read());
  } while (millis() - start < ms);
}

void dibujarMarco() {
  // Dibuja el marco de la pantalla en rojo
  tft.drawLine(0,0,130,0,ST7735_RED);
  tft.drawLine(0,1,130,1,ST7735_RED);
  tft.drawLine(0,158,130,158,ST7735_RED);
  tft.drawLine(0,142,130,142,ST7735_RED);
  tft.drawLine(0,141,130,141,ST7735_RED);
  tft.drawLine(0,107,130,107,ST7735_RED);
  tft.drawLine(0,108,130,108,ST7735_RED);
  tft.drawLine(80,108,80,140,ST7735_RED);
  tft.drawLine(81,109,81,140,ST7735_RED);
  tft.drawLine(80,70,80,108,ST7735_RED);
  tft.drawLine(81,70,81,108,ST7735_RED);
  tft.drawLine(0,159,130,159,ST7735_RED);
  tft.drawLine(0,0,0,156,ST7735_RED);
  tft.drawLine(1,1,1,157,ST7735_RED);
  tft.drawLine(127,0,127,156,ST7735_RED);
  tft.drawLine(126,0,126,156,ST7735_RED);
  tft.drawLine(0,35,130,35,ST7735_RED);
  tft.drawLine(0,36,130,36,ST7735_RED);
  tft.drawLine(0,70,130,70,ST7735_RED);
  tft.drawLine(0,71,130,71,ST7735_RED);
}

void graficarVelocidad() {
  int nuevaValor = map(gps.speed.kmph(), 0, 150, 137, 110);
  x++;
  tft.drawPixel(x, nuevaValor, ST7735_CYAN);
  if (x > 123) {
    x = 80;
    tft.fillRect(82, 110, 43, 30, ST7735_BLACK);
  }
}

void graficarAltitud() {
  int nuevaValorh = map(gps.altitude.meters(), 0, 1000, 104, 72);
  xh++;
  tft.drawPixel(xh, nuevaValorh, ST7735_CYAN);
  if (xh > 123) {
    xh = 80;
    tft.fillRect(82, 72, 43, 35, ST7735_BLACK);
  }
}

void actualizarVelocidadMax() {
  speed1 = gps.speed.kmph();
  if (speed1 > maxspeed) maxspeed = speed1;
}

void actualizarAltitudMax() {
  high1 = gps.altitude.meters();
  if (high1 > maxhigh) maxhigh = high1;
}

Registrador GPS con guardado en tarjeta SD

#include <SPI.h>
#include <SD.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#define cs 10
#define dc 9
#define rst 8
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;
const int cs_sd = 4;
#define OLED_RESET 5

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

int x = 80, xh = 80;
int maxhigh = 0, maxspeed = 0, speed1 = 0, high1 = 0;

void setup() {
  Serial.begin(9600);
  ss.begin(GPSBaud);
  tft.initR(INITR_GREENTAB);
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(5, 58);
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
  tft.print("inicializacion");
  tft.setCursor(5, 70);
  tft.print("init SD");
  delay(1000);
  
  if (!SD.begin(cs_sd)) {
    tft.setCursor(5, 82);
    tft.print("Fallo SD");
    return;
  }
  tft.setCursor(5, 82);
  tft.print("Tarjeta SD OK");
  delay(1000);
  tft.fillScreen(ST7735_BLACK);
  
  File data = SD.open("datos.txt", FILE_WRITE);
  data.println("");
  data.println("Inicio adquisicion");
  data.close();
}

void loop() {
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
  
  while (ss.available() > 0) {
    gps.encode(ss.read());
    if (gps.location.isUpdated()) {
      dibujarMarco();
      
      // Latitud y longitud
      tft.setCursor(5, 44);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("Latitud: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.location.lat(), 6);
      
      tft.setCursor(5, 58);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("Longitud: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.location.lng(), 6);
      
      // Fecha
      tft.setCursor(5, 7);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("fecha: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.date.day()); tft.print(" ");
      tft.print(gps.date.month()); tft.print(" ");
      tft.print(gps.date.year());
      String Fecha = String(gps.date.day()) + " " + gps.date.month() + " " + gps.date.year();
      
      // Hora
      tft.setCursor(5, 20);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("hora: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.time.hour()+1); tft.print(" ");
      tft.print(gps.time.minute()); tft.print(" ");
      tft.print(gps.time.second()); tft.print(" ");
      String Hora = String(gps.time.hour()+1) + " " + gps.time.minute() + " " + gps.time.second();
      
      // Altitud
      tft.setCursor(5, 80);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("H m: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.altitude.meters(), 0);
      
      tft.setCursor(5, 95);
      actualizarAltitudMax();
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("Hmax: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(maxhigh);
      graficarAltitud();
      
      // Velocidad
      tft.setCursor(5, 115);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("V act: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.speed.kmph(), 0);
      
      tft.setCursor(5, 130);
      actualizarVelocidadMax();
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("vmax: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(maxspeed);
      graficarVelocidad();
      
      // Satélites
      tft.setCursor(5, 147);
      tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
      tft.print("Sat: ");
      tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
      tft.print(gps.satellites.value());
      
      // HDOP
      Serial.print("HDOP = ");
      Serial.println(gps.hdop.value());
      
      smartDelay(400);
      
      // Guardar en SD
      File data = SD.open("datos.txt", FILE_WRITE);
      data.println(Fecha + " " + Hora + " " + 
                   String(gps.location.lat(), 6) + " " +
                   String(gps.location.lng(), 6) + " " +
                   String(gps.altitude.meters(), 0) + " " +
                   String(maxhigh) + " " +
                   String(gps.speed.kmph(), 0) + " " +
                   String(maxspeed));
      data.close();
    }
  }
}

// Funciones smartDelay, dibujarMarco, graficarVelocidad, graficarAltitud, 
// actualizarVelocidadMax, actualizarAltitudMax idénticas a la versión básica

Esquemáticos

Consulte la imagen del esquemático adjunta para las conexiones detalladas.

Proceso de manufactura

  1. Construya un Sistema Rápido y Fiable de Detección de Incendios con Samsung SAMIIO, Arduino UNO y Raspberry Pi
  2. Monitorización en Tiempo Real de Panel Solar con Arduino: Sistema de Adquisición de Datos de Bajo Coste
  3. Construye un Monitor de Energía y Registrador de Datos Fiable con Arduino – Guía Paso a Paso
  4. Crea Animaciones y Juegos en LCD 16×2 con Arduino UNO
  5. Registrador de Temperatura y Humedad con Arduino, DHT11 y Ethernet Shield
  6. Calculadora Básica con Arduino UNO - Proyecto Fácil para Principiantes
  7. Construir una pantalla de persistencia de visión portátil con Arduino UNO y ATtiny85
  8. Módulo GPS u-blox LEA‑6H 02: Guía de integración con Arduino y Python
  9. Construye un Cubo LED 4x4x4 con Arduino Uno y 1Sheeld – Proyecto LED Interactivo
  10. Control Arduino UNO desde Python 3 – Envío de Comandos y Demo LED
  11. Construye una Radio FM Compacta con Arduino Nano y RDA5807M