Проблеммы с работой модуля GPS NEO 6M
- Войдите на сайт для отправки комментариев
Пт, 31/07/2020 - 01:07
Собираю 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() );
}
Предлагаете нам самим собрать вашу схему, чтобы понять, что вы зашифровали под многозначительными словами "код нормально не работает"?:)
Конечно же нет. Как мне удалось выяснить, Arduino не получает данные от модуля GPS, хотя модуль заведомо рабочий, также подключен он правильно, и мигает светодиод что сигнализирует о установленном контакте со спутниками.
Так модуль же вроде по обычному Сериалу общается, так что что там выяснять - подключите его к любой терминальной программе и посмотрите, шлет он что-то или нет...
Я же говорю, сам модуль работает, с ним всё ок!
Я же говорю, сам модуль работает, с ним всё ок!
как вы определили, что модуль работает? По светодиоду?:) Не надо мне писать, что с "модулем все нормально", ценность ваших слов весьма относительна... если бы вы в этом разбирались, вопросы бы не задавали.
Повторяю - вам нужно подключить его к терминалу, чтобы выяснить следующее:
- что модуль вообще что-то шлет
- что он это делает на правильной скорости
- что он шлет в нужном формате.
У вас в коде, насколько я вижу - идет проверка каждого байта заголовка данных, если что-то не совпадет - программа работать не будет. А есть уверенность, что модем шлет это все в правильном формате? - формат этот не один
Отлаживать такое на МК с одним UART - извращение. Временно на Мегу всё закиньте и подключите GPS к Serial1, а в Serial печатайте то, что лезет из GPS-приёмника. Может на блохе скорость порта надо установить правильно через u-center.
Но, мне кажется, что processGPS() написан в неустойчивом к неправильным данным стиле.
Идея и скетч были взяты отсюда:
Я бы, на Вашем, месте обратился не сюда, а к автору кода.
Вы понимаете что написано в строчках с 15 по 38 ?
Залил на ардуино этот код и проверил работает или нет, вот так и получил результат, что модуль заведомо рабочий. Координаты, время, дату определяет корректно. #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; }К сожалению, с ним нет связи