"Ciencia y Tecnología" por Manolo: Localizador GPS NEO6 y ZUM core de BQ

Marquesina

"AQUÍ NO NOS DETENEMOS A MIRAR EL PASADO POR MUCHO TIEMPO SIGUE SIEMPRE ADELANTE, ABRIENDO NUEVAS PUERTAS Y HACIENDO COSAS NUEVAS. SÉ CURIOSO" Walt Disney.

sábado, 8 de mayo de 2021

Localizador GPS NEO6 y ZUM core de BQ

Una práctica que considero como menos curiosa

En esta entrada al blog voy a intentar explicar cómo usar la placa #ZumCore de BQ, tanto la primera versión como la core 2, con un localizador GPS NEO6.

Lo primero es describir el material que voy a usar:

Placa #ZumCore de BQ

Localizador GPS NEO6

Pantalla LED 1602

Cables de conexión (dupont, hembra macho)




Para entender cómo funciona el GPS os remito a este link, donde ya lo expliqué pero usándolo con una arduino MEGA. Cliquea en el botón. 




Conexiones:

Módulo GP NEO6Pin Arduino UNO/ZUMPin Arduino MEGA
VCC5 V.5 V.
GNDGNDGND
RXD4 (u otro)TX1 (18)
TXD3 (u otro)RX1 (19)


En la placa Zum core se pueden usar los pines D0 y D1 destinados a tal fin, Repito, como dije en la entrada anterior y que trataba de GPS y Mega, que el pin RX del localizador no hace falta conectarlo al TX de la placa porque no vamos a transmitir nada pero si el otro, es decir el TX del localizador al RX de la placa.






Librerías:

Para la placa #ZumCore puedo usar el programa que puse en la entrada de Mega de arduino. No uso librerías para el GPS, sí para la pantalla LCD, sino que cadena GPRMC la descompongo en datos que da dicha cadena, como puede ser: longitud, latitud, horaUTC, ....,

Para ello haz clic en el botón de arriba para ir y coger el progama.


Si uso la #ZumCore2, uso la librería SoftSerial que permite por ejemplo usar cualquier pin como conexión UART que es la que usa este módulo GPS. Y cojo el D3 y D4 para tal fin. Podría coger otros cualquiera. También uso la librería TinyGPS.h (disponible dentro del gestor de librerías de ARDUINO), que hace lo mismo que anterior programa.


Para la #ZumCore uso este progrma
/*Programa para usar GPS NEO6 con ZUM de BQ
Modificación Manolo
No usa librerías para el GPS
Para la pantalla LCD uso la LiquidCrystal_I2C.h
 */

#include <LiquidCrystal_I2C.h>
char nmeaSentence[68];
String latitude;    //latitud
String longitude;   //longitud
String lndSpeed;    //velocidad
String gpsTime;     //Hora UTC, la hora a 0 grados de longitud del primer meridiano, a 8 horas de la hora de Beijing
String madridTime;  //Hora de Madrid
String gpsDate;     //Fecha

#define GpsSerial Serial
#define DebugSerial Serial

#define I2C_ADDR    0x27                 //Comprobado con scaner I2C
LiquidCrystal_I2C lcd(I2C_ADDR,2, 1, 0, 4, 5, 6, 7);

void setup()  //Contenido inicial
{
  #define GpsSerial Serial
  GpsSerial.begin(9600);
//Tasa de baudios de 9600.
  DebugSerial.begin(9600);
  DebugSerial.println("Test GPS Arduino/mega2560");
  DebugSerial.println("@ManoloJCR/Tao");
  DebugSerial.println("Wating to get gps data...");
       lcd.begin (16,2);          // Inicializa el display con 16 caraceres 2 lineas
       lcd.setBacklightPin(3,POSITIVE); // El pin 3 es la luz
       lcd.setBacklight(HIGH);          // Se ilumina
       lcd.clear();

}

void loop()   //Bucle principal
{

  for (unsigned long start = millis(); millis() - start < 1000;)  
//Escanea la información del GPS continuamente en un segundo
  {
    while (GpsSerial.available()) 
//El puerto serie obtiene los datos y comienza a analizar
    {
      char c = GpsSerial.read();  //Leer un byte de datos
      switch(c)         //Determinar el valor del byte
      {
        case '$':         
//Si es $, significa el comienzo de un marco de datos
        GpsSerial.readBytesUntil('*', nmeaSentence, 67);    
//Lee los siguientes datos y los guarda en la matriz de caracteres nmeaSentence, hasta 67 bytes
        //Serial.println(nmeaSentence);
        latitude = parseGprmcLat(nmeaSentence); //Obtener valor de latitud
        longitude = parseGprmcLon(nmeaSentence);//Obtener valor de longitud
        lndSpeed = parseGprmcSpeed(nmeaSentence);//Obtener valor de velocidad
        gpsTime = parseGprmcTime(nmeaSentence);//Obtener la hora del GPS
        gpsDate = parseGprmcDate(nmeaSentence);//Obtener la fecha del GPS

          if(latitude > "")   //Imprimir cuando no esté vacío
          {
          //  DebugSerial.println("latitude: " + latitude);
            DebugSerial.println("------------------------------------");
          int glat = latitude.substring(0,2).toInt();
          int mlat = latitude.substring(2,4).toInt();
          int slat = latitude.substring(5,8).toInt();
          slat = slat*0.0060;
          DebugSerial.print("Latitud: ");
          DebugSerial.print(glat);
          DebugSerial.print("º ");
          DebugSerial.print(mlat);
          DebugSerial.print("´ ");
          DebugSerial.print(slat);
          DebugSerial.print("´´ ");
          
            String llat = latitude.substring(11,12);
            Serial.println(latitude.substring(11,12));
          
          lcd.clear();                  // borramos la pantalla
       lcd.setCursor ( 2, 0 );       // situamos cursor en el 2ºcaracter y 1ªfila 
       lcd.print("Latitud:");
       lcd.setCursor ( 2, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(glat);
       lcd.setCursor ( 4, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("");
       lcd.setCursor ( 6, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(mlat);
       lcd.setCursor ( 8, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("'");
       lcd.setCursor ( 10, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(slat);
       lcd.setCursor ( 12, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("''");
       lcd.setCursor ( 14, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(llat);
       delay (3000);
       
          }

          if(longitude > "")    //Imprimir cuando no esté vacío
          {
//       DebugSerial.println("longitude: " + longitude);
         int glong = longitude.substring(0,3).toInt();
         int mlong = longitude.substring(3,5).toInt();
         int slong = longitude.substring(6,10).toInt();
         slong = slong*0.0060;
         DebugSerial.print("Longitud: ");
         DebugSerial.print(glong);
         DebugSerial.print("º");
         DebugSerial.print(mlong);
         DebugSerial.print("´ ");
         DebugSerial.print(slong);
         DebugSerial.print("´´ ");
         String llon = longitude.substring(12,13);
         DebugSerial.println(longitude.substring(12,13));
       lcd.clear();                  // borramos la pantalla
       lcd.setCursor ( 2, 0 );       // situamos cursor en el 2ºcaracter y 1ªfila 
       lcd.print("Longitud:");
       lcd.setCursor ( 2, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(glong);
       lcd.setCursor ( 4, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("");
       lcd.setCursor ( 6, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(mlong);
       lcd.setCursor ( 8, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("'");
       lcd.setCursor ( 10, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(slong);
       lcd.setCursor ( 12, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("''");
       lcd.setCursor ( 14, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(llon);
       delay (3000);
         }  

         if(lndSpeed > "")    //Imprimir cuando no esté vacío
         {
         DebugSerial.println("Speed (knots): " +  lndSpeed);
         }

         if(gpsDate > "")   //Imprimir cuando no esté vacío
         {
         //DebugSerial.println("gpsDate: "+gpsDate);
         int year = gpsDate.substring(4,6).toInt();
         int month = gpsDate.substring(2,4).toInt();
         int day = gpsDate.substring(0,2).toInt();
         DebugSerial.print("gpsDate: ");
         DebugSerial.print(day);
         DebugSerial.print("/");
         DebugSerial.print(month);
         DebugSerial.print("/");
         DebugSerial.println(year);
         lcd.clear();                  // borramos la pantalla
       lcd.setCursor ( 2, 0 );       // situamos cursor en el 2ºcaracter y 1ªfila 
       lcd.print("Fecha:");
       lcd.setCursor ( 2, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(day);
       lcd.setCursor ( 4, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("/");
       lcd.setCursor ( 6, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(month);
       lcd.setCursor ( 8, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("/");
       lcd.setCursor ( 10, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(year);
       delay (3000);
         }
    
         if(gpsTime > "")    //Imprimir cuando no esté vacío
         {
         //DebugSerial.println("gpsTime: "+gpsTime);
         int hour = gpsTime.substring(0,2).toInt();
         int minute = gpsTime.substring(2,4).toInt();
         int second = gpsTime.substring(4,6).toInt();
         DebugSerial.print("gpsTime: ");
         DebugSerial.print(hour);
         DebugSerial.print("h: ");
         DebugSerial.print(minute);
         DebugSerial.print("min. ");
         DebugSerial.print(second);
         DebugSerial.println("s. "); 
         lcd.clear();                  // borramos la pantalla
       lcd.setCursor ( 2, 0 );       // situamos cursor en el 2ºcaracter y 1ªfila 
       lcd.print("UTCTime:");
       lcd.setCursor ( 2, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(hour);
       lcd.setCursor ( 4, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("h");
       lcd.setCursor ( 6, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(minute);
       lcd.setCursor ( 8, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("min.");
       lcd.setCursor ( 13, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(second);
       lcd.setCursor ( 15, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("s");
       delay (3000);
         
         madridTime = madridgetTime(gpsTime);  //Obtener la hora de Madrid
         //DebugSerial.println("madridTime: "+madridTime);
         int mhour = madridTime.substring(0,2).toInt();
         if(mhour > 23)
      mhour -= 24;
         int mminute = madridTime.substring(2,4).toInt();
         int msecond = madridTime.substring(4,6).toInt();
         DebugSerial.print("madridTime: ");
         DebugSerial.print(mhour);
         DebugSerial.print("h: ");
         DebugSerial.print(mminute);
         DebugSerial.print("min. ");
         DebugSerial.print(msecond);
         DebugSerial.println("s. ");
         lcd.clear();                  // borramos la pantalla
       lcd.setCursor ( 2, 0 );       // situamos cursor en el 2ºcaracter y 1ªfila 
       lcd.print("MadridTime:");
       lcd.setCursor ( 2, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(mhour);
       lcd.setCursor ( 4, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("h");
       lcd.setCursor ( 6, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(mminute);
       lcd.setCursor ( 8, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("min.");
       lcd.setCursor ( 13, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print(msecond);
       lcd.setCursor ( 15, 1 );        // situamos cursor en el 2ºcaracter y 2ªfila
       lcd.print("s");
       delay (3000);
         
         } 
           
        }   
      }
    }
  
       
       lcd.clear();
       lcd.setCursor ( 1, 0 );
       lcd.print("Prueba LCD1602");
       lcd.setCursor ( 4, 1 );        
       lcd.print("ManoloJCR");
       delay (3000);                  //Esperamos 3 s

  }


String madridgetTime(String s)
{
  int hour = 0;
  int minute = 0;
  int second = 0;
  int onehour = s.substring(0,1).toInt();
  int oneminute = s.substring(2,3).toInt();
  hour = s.substring(0,2).toInt();
              minute = s.substring(2,4).toInt();
              second = s.substring(4,6).toInt();
              hour += 2;
         // DebugSerial.println(minute);
         // DebugSerial.println(oneminute);
          if(hour<10)
          {
            if(minute<10)
  s = String(onehour)+String(hour)+String(oneminute)+String(minute)+String(second);
            else
            {
  s = String(onehour)+String(hour)+String(minute)+String(second);
            }
          }
          else
          {
            
            if(minute<10)
  s = String(hour)+String(oneminute)+String(minute)+String(second);
  //DebugSerial.println(s);
            else 
            {
  s = String(hour) + String(minute) + String(second);
            }
          
          }
          
      
    return s;
}

//Descomponemos cadena NMEA 
//La cadena debe ser GPRMC o no la analizamos
//Return Latitude
String parseGprmcLat(String s)
{
  int pLoc = 0; //paramater location pointer
  int lEndLoc = 0; //lat parameter end location
  int dEndLoc = 0; //direction parameter end location
  String lat;

/*Buscamos GPRM al principio cadena */
    if(s.substring(0,4) == "GPRM")
  {
 // Serial.println(s);
    for(int i = 0; i < 5; i++)
    {
      if(i < 3) 
      {
        pLoc = s.indexOf(',', pLoc+1);
      }
      if(i == 3)
      {
        lEndLoc = s.indexOf(',', pLoc+1);
        lat = s.substring(pLoc+1, lEndLoc);
      }
      else
      {
        dEndLoc = s.indexOf(',', lEndLoc+1);
        lat = lat + " " + s.substring(lEndLoc+1, dEndLoc);
      }
    }
    return lat; 
  }
 }
 

//Descomponemos cadena NMEA 
//La cadena debe ser GPRMC o no la analizamos
//Return Longitude
String parseGprmcLon(String s)
{
  int pLoc = 0; //paramater location pointer
  int lEndLoc = 0; //lat parameter end location
  int dEndLoc = 0; //direction parameter end location
  String lon;

 /*Buscamos GPRM al principio cadena */
  if(s.substring(0,4) == "GPRM")
  {
    //Serial.println(s);
    for(int i = 0; i < 7; i++)
    {
      if(i < 5) 
      {
        pLoc = s.indexOf(',', pLoc+1);
      }
      if(i == 5)
      {
        lEndLoc = s.indexOf(',', pLoc+1);
        lon = s.substring(pLoc+1, lEndLoc);
      }
      else
      {
        dEndLoc = s.indexOf(',', lEndLoc+1);
        lon = lon + " " + s.substring(lEndLoc+1, dEndLoc);
      }
    }
    return lon; 
  }
}


//Descomponemos cadena NMEA 
//La cadena debe ser GPRMC o no la analizamos
//Return velocidad
String parseGprmcSpeed(String s)
{
  int pLoc = 0; //paramater location pointer
  int lEndLoc = 0; //lat parameter end location
  int dEndLoc = 0; //direction parameter end location
  String lndSpeed;

/*Buscamos GPRM al principio cadena */
  if(s.substring(0,4) == "GPRM")
  {
    //Serial.println(s);
    for(int i = 0; i < 8; i++)
    {
      if(i < 7) 
      {
        pLoc = s.indexOf(',', pLoc+1);
      }
      else
      {
        lEndLoc = s.indexOf(',', pLoc+1);
        lndSpeed = s.substring(pLoc+1, lEndLoc);
      }
    }
    return lndSpeed; 
  }
}



//Descomponemos cadena NMEA 
//La cadena debe ser GPRMC o no la analizamos
//Return date
String parseGprmcDate(String s)
{
  int pLoc = 0; //paramater location pointer
  int lEndLoc = 0; //lat parameter end location
  int dEndLoc = 0; //direction parameter end location
  String gpsDate;

  /*Buscamos GPRM al principio cadena */
  if(s.substring(0,4) == "GPRM")
  {
    //Serial.println(s);
    for(int i = 0; i < 10; i++)
    {
      if(i < 9) 
      {
        pLoc = s.indexOf(',', pLoc+1);
      }
      else
      {
        lEndLoc = s.indexOf(',', pLoc+1);
        gpsDate = s.substring(pLoc+1, lEndLoc);
      }
    }
    return gpsDate; 
  }
}


//Descomponemos cadena NMEA 
//La cadena debe ser GPRMC o no la analizamos
//Return tiempo
String parseGprmcTime(String s)
{
  int pLoc = 0; //paramater location pointer
  int lEndLoc = 0; //lat parameter end location
  int dEndLoc = 0; //direction parameter end location
  String gpsTime;

  /*Buscamos GPRM al principio cadena */
  if(s.substring(0,4) == "GPRM")
  {
    //Serial.println(s);
    for(int i = 0; i < 2; i++)
    {
      if(i < 1) 
      {
        pLoc = s.indexOf(',', pLoc+1);
        
      }
      else
      {
        lEndLoc = s.indexOf(',', pLoc+1);
        gpsTime = s.substring(pLoc+1, lEndLoc);
        
      }
    }
    return gpsTime; 
  }
  }



Para la #ZumCore2, uso este progrma


 #include <SoftwareSerial.h>
#include <TinyGPS.h>

TinyGPS gps;
SoftwareSerial softSerial(4, 3);

void setup()
{
   Serial.begin(115200);
   softSerial.begin(9600);
}

void loop()
{
   bool newData = false;
   unsigned long chars;
   unsigned short sentences, failed;
   
   // Intentar recibir secuencia durante un segundo
   for (unsigned long start = millis(); millis() - start < 1000;)
   {
      while (softSerial.available())
      {
         char c = softSerial.read();
         if (gps.encode(c)) // Nueva secuencia recibida
            newData = true;
      }
   }

   if (newData)
   {
      float flat, flon;
      unsigned long age;
      gps.f_get_position(&flat, &flon, &age);
      Serial.print("LAT=");
      Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
      Serial.print(" LON=");
      Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
      Serial.print(" SAT=");
      Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
      Serial.print(" PREC=");
      Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
   }

   gps.stats(&chars, &sentences, &failed);
   Serial.print(" CHARS=");
   Serial.print(chars);
   Serial.print(" SENTENCES=");
   Serial.print(sentences);
   Serial.print(" CSUM ERR=");
   Serial.println(failed);
}