Проблеммы с работой модуля GPS NEO 6M

Yaroslav575
Offline
Зарегистрирован: 31.07.2020

Собираю GPS спидометр на таких компонентах: Arduino NANO + GPS NEO 6M + LCD 0,94. Есть под это дело скетч, который был разработан под NEO 7. Путём сравнения вычислил что у них рахная максимальная частота работы, что уже исправил но всё равно нормально не работает. Технические или программные подробности дать не могу так как первый раз с ардуино.

Идея и скетч были взяты отсюда: https://www.youtube.com/watch?v=q4ZA6KtYGRg

/*
 Connections:
 GPS TX -> Arduino 0 (disconnect to upload this sketch)
 GPS RX -> Arduino 1
 Screen SDA -> Arduino A4
 Screen SCL -> Arduino A5
*/

#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);	// Fast I2C / TWI 

#define GPS Serial

const unsigned char UBLOX_INIT[] PROGMEM = {
  // Disable NMEA
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x24, // GxGGA off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x2B, // GxGLL off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x32, // GxGSA off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x39, // GxGSV off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x04,0x00,0x00,0x00,0x00,0x00,0x01,0x04,0x40, // GxRMC off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x05,0x00,0x00,0x00,0x00,0x00,0x01,0x05,0x47, // GxVTG off

  // Disable UBX
  0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0xDC, //NAV-PVT off
  0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xB9, //NAV-POSLLH off
  0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0xC0, //NAV-STATUS off

  // Enable UBX
  0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x07,0x00,0x01,0x00,0x00,0x00,0x00,0x18,0xE1, //NAV-PVT on
  //0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x13,0xBE, //NAV-POSLLH on
  //0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x14,0xC5, //NAV-STATUS on

  // Rate
   //0xB5,0x62,0x06,0x08,0x06,0x00,0x64,0x00,0x01,0x00,0x01,0x00,0x7A,0x12, //(10Hz)
   0xB5,0x62,0x06,0x08,0x06,0x00,0xC8,0x00,0x01,0x00,0x01,0x00,0xDE,0x6A, //(5Hz)
  //0xB5,0x62,0x06,0x08,0x06,0x00,0xE8,0x03,0x01,0x00,0x01,0x00,0x01,0x39 //(1Hz)
};

const unsigned char UBX_HEADER[] = { 0xB5, 0x62 };

struct NAV_PVT {
  unsigned char cls;
  unsigned char id;
  unsigned short len;
  unsigned long iTOW;          // GPS time of week of the navigation epoch (ms)

  unsigned short year;         // Year (UTC) 
  unsigned char month;         // Month, range 1..12 (UTC)
  unsigned char day;           // Day of month, range 1..31 (UTC)
  unsigned char hour;          // Hour of day, range 0..23 (UTC)
  unsigned char minute;        // Minute of hour, range 0..59 (UTC)
  unsigned char second;        // Seconds of minute, range 0..60 (UTC)
  char valid;                  // Validity Flags (see graphic below)
  unsigned long tAcc;          // Time accuracy estimate (UTC) (ns)
  long nano;                   // Fraction of second, range -1e9 .. 1e9 (UTC) (ns)
  unsigned char fixType;       // GNSSfix Type, range 0..5
  char flags;                  // Fix Status Flags
  unsigned char reserved1;     // reserved
  unsigned char numSV;         // Number of satellites used in Nav Solution

  long lon;                    // Longitude (deg)
  long lat;                    // Latitude (deg)
  long height;                 // Height above Ellipsoid (mm)
  long hMSL;                   // Height above mean sea level (mm)
  unsigned long hAcc;          // Horizontal Accuracy Estimate (mm)
  unsigned long vAcc;          // Vertical Accuracy Estimate (mm)

  long velN;                   // NED north velocity (mm/s)
  long velE;                   // NED east velocity (mm/s)
  long velD;                   // NED down velocity (mm/s)
  long gSpeed;                 // Ground Speed (2-D) (mm/s)
  long heading;                // Heading of motion 2-D (deg)
  unsigned long sAcc;          // Speed Accuracy Estimate
  unsigned long headingAcc;    // Heading Accuracy Estimate
  unsigned short pDOP;         // Position dilution of precision
  short reserved2;             // Reserved
  unsigned long reserved3;     // Reserved
};

NAV_PVT pvt;

void calcChecksum(unsigned char* CK) {
  memset(CK, 0, 2);
  for (int i = 0; i < (int)sizeof(NAV_PVT); i++) {
    CK[0] += ((unsigned char*)(&pvt))[i];
    CK[1] += CK[0];
  }
}

long numGPSMessagesReceived = 0;

bool processGPS() {
  static int fpos = 0;
  static unsigned char checksum[2];
  const int payloadSize = sizeof(NAV_PVT);

  while ( GPS.available() ) {
    byte c = GPS.read();
    if ( fpos < 2 ) {
      if ( c == UBX_HEADER[fpos] )
        fpos++;
      else
        fpos = 0;
    }
    else {      
      if ( (fpos-2) < payloadSize )
        ((unsigned char*)(&pvt))[fpos-2] = c;

      fpos++;

      if ( fpos == (payloadSize+2) ) {
        calcChecksum(checksum);
      }
      else if ( fpos == (payloadSize+3) ) {
        if ( c != checksum[0] )
          fpos = 0;
      }
      else if ( fpos == (payloadSize+4) ) {
        fpos = 0;
        if ( c == checksum[1] ) {
          return true;
        }
      }
      else if ( fpos > (payloadSize+4) ) {
        fpos = 0;
      }
    }
  }
  return false;
}

void setup() 
{
  GPS.begin(9600);

  u8g.setColorIndex(1);

  // send configuration data in UBX protocol
  for(unsigned int i = 0; i < sizeof(UBLOX_INIT); i++) {                        
    GPS.write( pgm_read_byte(UBLOX_INIT+i) );
    delay(5); // simulating a 38400baud pace (or less), otherwise commands are not accepted by the device.
  }
  
}

long gSpeed = 0;
int numSV = 0;
unsigned long lastScreenUpdate = 0;
char speedBuf[16];
char satsBuf[16];

char* spinner = "/-\\|";
byte screenRefreshSpinnerPos = 0;
byte gpsUpdateSpinnerPos = 0;

void loop() {
  if ( processGPS() ) {
    numSV = pvt.numSV;
    gSpeed = pvt.gSpeed;    
    gpsUpdateSpinnerPos = (gpsUpdateSpinnerPos + 1) % 4;
  }

  unsigned long now = millis();
  if ( now - lastScreenUpdate > 100 ) {
    updateScreen();
    lastScreenUpdate = now;
    screenRefreshSpinnerPos = (screenRefreshSpinnerPos + 1) % 4;
  }
}

void draw() {
  //u8g.setScale2x2(); don't do this!
  u8g.setFont(u8g_font_fur30);
  u8g.drawStr( 60, 55, speedBuf);
  //u8g.undoScale();
  u8g.setFont(u8g_font_fur11);
  u8g.drawStr( 2, 12, satsBuf);
}

void updateScreen() {
  
  int kmh = gSpeed * 0.0036;
  sprintf(speedBuf, "%3d", kmh);
  sprintf(satsBuf, "%c %c %d", spinner[screenRefreshSpinnerPos], spinner[gpsUpdateSpinnerPos], numSV);
  
  u8g.firstPage();
  do {
    draw();
  } while( u8g.nextPage() );
}

 

b707
Offline
Зарегистрирован: 26.05.2017

Предлагаете нам самим собрать вашу схему, чтобы понять, что вы зашифровали под многозначительными словами "код нормально не работает"?:)

Yaroslav575
Offline
Зарегистрирован: 31.07.2020

Конечно же нет. Как мне удалось выяснить, Arduino не получает данные от модуля GPS, хотя модуль заведомо рабочий, также подключен он правильно, и мигает светодиод что сигнализирует о установленном контакте со спутниками.

b707
Offline
Зарегистрирован: 26.05.2017

Так модуль же вроде по обычному Сериалу общается, так что что там выяснять - подключите его к любой терминальной программе и посмотрите, шлет он что-то или нет...

Yaroslav575
Offline
Зарегистрирован: 31.07.2020

Я же говорю, сам модуль работает, с ним всё ок!

b707
Offline
Зарегистрирован: 26.05.2017

Yaroslav575 пишет:

Я же говорю, сам модуль работает, с ним всё ок!

как вы определили, что модуль работает? По светодиоду?:)  Не надо мне писать, что с "модулем все нормально", ценность ваших слов весьма относительна... если бы вы в этом разбирались, вопросы бы не задавали.

Повторяю - вам нужно подключить его к терминалу, чтобы выяснить следующее:

 - что модуль вообще что-то шлет

- что он это делает на правильной скорости

- что он шлет в нужном формате.

У вас в коде, насколько я вижу - идет проверка каждого байта заголовка данных, если что-то не совпадет - программа работать не будет. А есть уверенность, что модем шлет это все в правильном формате? - формат этот не один

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Отлаживать такое на МК с одним UART - извращение. Временно на Мегу всё закиньте и подключите GPS к Serial1, а в Serial печатайте то, что лезет из GPS-приёмника. Может на блохе скорость порта надо установить правильно через u-center.

Но, мне кажется, что processGPS() написан в неустойчивом к неправильным данным стиле.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Yaroslav575 пишет:

Идея и скетч были взяты отсюда: 

Я бы, на Вашем, месте обратился не сюда, а к автору кода.

renoshnik
Offline
Зарегистрирован: 11.04.2013

Вы понимаете что написано в строчках с 15 по 38 ?

Yaroslav575
Offline
Зарегистрирован: 31.07.2020
Залил на ардуино этот код и проверил работает или нет, вот так и получил результат, что модуль заведомо рабочий. Координаты, время, дату определяет корректно.
#include <SoftwareSerial.h>
#include <TinyGPS.h> //подключение необходимых для работы библиотек
TinyGPS gps;
SoftwareSerial gpsSerial(8, 9); //номера пинов, к которым подключен модуль (RX, TX)
bool newdata = false;
unsigned long start;
long lat, lon;
unsigned long time, date;
void setup(){
gpsSerial.begin(9600); // установка скорости обмена с приемником
Serial.begin(9600);
Serial.println("Waiting data of GPS...");
}
void loop(){
if (millis() - start > 1000) //установка задержки в одну секунду между обновлением данных
{
newdata = readgps();
if (newdata)
{
start = millis();
gps.get_position(&lat, &lon);
gps.get_datetime(&date, &time);
Serial.print("Lat: "); Serial.print(lat);
Serial.print(" Long: "); Serial.print(lon);
Serial.print(" Date: "); Serial.print(date);
Serial.print(" Time: "); Serial.println(time);
}}
}
// проверка наличия данных
bool readgps()
{
while (gpsSerial.available())
{
int b = gpsSerial.read();
//в библиотеке TinyGPS имеется ошибка: не обрабатываются данные с \r и \n
if('\r' != b)
{
if (gps.encode(b))
 return true;
}
}
return false;
}

 

Yaroslav575
Offline
Зарегистрирован: 31.07.2020

К сожалению, с ним нет связи