Ненормальное поведение tinygps с GPS EM408
У меня есть Arduino Duemilanove и em408.
Мой код таков:
#include <TinyGPS.h>
#include <SoftwareSerial.h>
#define GPS_RX_PIN 2
#define GPS_TX_PIN 3
TinyGPS gps;
SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);
void setup()
{
Serial.begin(9600);
ss.begin(4800);
}
void loop()
{
while (ss.available())
{
char c = byte(ss.read());
// Здесь я попробовал Serial.write(c); и я успешно увидел данные NMEA в моем последовательном мониторе
if (gps.encode(c))
{
long lat, lon;
unsigned long fix_age;
gps.get_position(&lat, &lon, &fix_age);
if (fix_age == TinyGPS::GPS_INVALID_AGE )
Serial.println("No fix ever detected!");
else if (fix_age > 2000)
Serial.println("Data is getting STALE!");
else
Serial.println("Latitude and longitude valid!");
Serial.print("Lat: ");
Serial.print(lat);
Serial.print(" Lon: ");
Serial.println(lon);
}
else Serial.println("No data!");
}
}
Мой вывод таков:
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
Latitude and longitude valid!
Lat: 32758239
Lon: 15637489
No data!
No data!
No data!
No data!
No data!
No data!
No data!
И затем я продолжаю получать Нет данных! навсегда...
Итак...
Почему функция gps.encode() возвращает значение true только один раз? Я получил исходные данные от GPS (прокомментированный код в моем фрагменте кода), и все в порядке. Почему он возвращает true только один раз?
Почему данные о долготе и широте такие? Насколько я знаю, это неверно, верно?
ИЗМЕНИТЬ: Также пробовал с TinyGPS++.. но тоже не повезло с кодировкой...
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define GPS_RX_PIN 2
#define GPS_TX_PIN 3
TinyGPSPlus gps;
SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);
void setup()
{
Serial.begin(9600);
ss.begin(4800);
}
void loop()
{
while (ss.available()>0)
{
char c = byte(ss.read());
// Здесь я попробовал Serial.write(c); и я успешно увидел данные NMEA в моем последовательном мониторе
if (gps.encode(c)) //я ранее использовал if(gps.encode(ss.read())); но тогда не повезло
{
Serial.print(F("Location: "));
if (gps.location.isValid())
{
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" Date/Time: "));
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print(F("/"));
Serial.print(gps.date.day());
Serial.print(F("/"));
Serial.print(gps.date.year());
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" "));
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print(F("0"));
Serial.print(gps.time.hour());
Serial.print(F(":"));
if (gps.time.minute() < 10) Serial.print(F("0"));
Serial.print(gps.time.minute());
Serial.print(F(":"));
if (gps.time.second() < 10) Serial.print(F("0"));
Serial.print(gps.time.second());
Serial.print(F("."));
if (gps.time.centisecond() < 10) Serial.print(F("0"));
Serial.print(gps.time.centisecond());
}
else
{
Serial.print(F("INVALID"));
}
Serial.println();
}
else Serial.println("No data!");
}
}
Новый код:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define GPS_RX_PIN 2
#define GPS_TX_PIN 3
TinyGPSPlus gps;
SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);
void setup()
{
Serial.begin(9600);
ss.begin(4800);
}
char clat[11];
char clng[11];
void loop()
{
//если (кнопки || наклон) {
//если (кнопки и BUTTON_SELECT) {
bool isGpsLocationValid = false;
do
{
while (ss.available()>0)
{
char c = byte(ss.read());
if (gps.encode(c)) //я ранее использовал if(gps.encode(ss.read())); но тогда не повезло
{
if (gps.location.isValid())
{
dtostrf(gps.location.lat(), 11, 6, clat);
dtostrf(gps.location.lng(), 11, 6, clng);
//отправить-печатать
// задержка (на всякий случай несколько ударов)
isGpsLocationValid = true;
}
}
}
} while (isGpsLocationValid == false);
Serial.write(clat);
Serial.println();
Serial.write(clng);
//}
//}
}
EDIT: самый новый код, который я разместил, работает на 100%! Так что, если у вас есть подобные проблемы с этим ужасным GPS, используйте это!
Видимо, TinyGPS и TinyGPS++ плохо работают с этим GPS. Если быть точным, проблема с функцией gps.encode(c).
Поэтому использование if (gps.encode(c))
в большинстве случаев возвращает false, за исключением некоторых редких случаев, когда возвращается true, и тогда вы можете выполнить некоторую обработку...
Мой последний код решает эту проблему путем непрерывной проверки с использованием цикла do...while.
Если if (gps.location.isValid())
возвращает true, что означает, что у меня есть достоверные данные, тогда я выполняю требуемую обработку и завершаю цикл do...while.
@user1584421, 👍-1
Обсуждение2 ответа
Лучший ответ:
Последний код, который я разместил, работает на 100%! Так что, если у вас есть подобные проблемы с этим ужасным GPS, используйте это!
Видимо, TinyGPS и TinyGPS++ плохо работают с этим GPS. Если быть точным, проблема с функцией gps.encode(c).
Поэтому использование if (gps.encode(c))
в большинстве случаев возвращает false, за исключением некоторых редких случаев, когда возвращается true, и тогда вы можете выполнить некоторую обработку...
Мой последний код решает эту проблему путем непрерывной проверки с использованием цикла do...while. Если if (gps.location.isValid())
возвращает true, что означает, что у меня есть достоверные данные, тогда я выполняю требуемую обработку и завершаю цикл do...while.
ПРИМЕЧАНИЕ. Этот код предназначен для библиотеки TinyGPS++. Та же теория, конечно, работает и для TinyGPS...
Вот оно:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#define GPS_RX_PIN 2
#define GPS_TX_PIN 3
TinyGPSPlus gps;
SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);
void setup()
{
Serial.begin(9600);
ss.begin(4800);
}
char clat[11];
char clng[11];
void loop()
{
bool isGpsLocationValid = false;
do
{
while (ss.available()>0)
{
char c = byte(ss.read());
if (gps.encode(c)) //я ранее использовал if(gps.encode(ss.read())); но тогда не повезло
{
if (gps.location.isValid())
{
dtostrf(gps.location.lat(), 11, 6, clat);
dtostrf(gps.location.lng(), 11, 6, clng);
isGpsLocationValid = true;
}
}
}
} while (isGpsLocationValid == false);
Serial.write(clat);
Serial.println();
Serial.write(clng);
}
Вы уверены насчет «пока (isGpsLocationValid = false)»? Это должно быть `в то время как (isGpsLocationValid == false)], иначе вы никогда не выйдете из этого цикла!, @jfpoilpret
ой, хорошее наблюдение, @user1584421
Большое спасибо!!! Вы уже дали мне решение моей проблемы, я пытался получить эти данные в течение 3 дней!! Когда я использовал только модуль GPS, все было в порядке, я мог получать данные, но когда я пытался использовать модуль GSM + GPS, я не мог получить данные от GPS! Ты дал мне решение
bool isGpsLocationValid = false;
do
{
while (ss.available()>0)
{
char c = byte(ss.read());
if (gps.encode(c)) //я ранее использовал if(gps.encode(ss.read())); но тогда не повезло
{
if (gps.location.isValid())
{
dtostrf(gps.location.lat(), 11, 6, clat);
dtostrf(gps.location.lng(), 11, 6, clng);
isGpsLocationValid = true;
}
}
}
} while (isGpsLocationValid == false);
Serial.write(clat);
Serial.println();
Serial.write(clng);
Поздравляем!! бразильские объятия для вас; )
Нет проблем... Просто проголосуйте за мой пост, если вы нашли его полезным (потому что на данный момент его -3), @user1584421
Преобразование в байт решает проблему? Потому что в противном случае не имеет смысла, что это будет работать, а старый код — нет, поскольку вам все еще нужно пройти через кодировку, чтобы выполнить тело IF., @rbaleksandar
- Отправка команд PUBX на плату GPS (Ublox NEO-6M) через SoftwareSerial
- последовательная передача данных на GPS-экране duinopeak
- Дата и время GPS не отображаются правильно в Arduino Uno,NEO6M GPS модуль
- Нет данных GPS Neo 6M DFRduino Nano
- GPS-модуль uBlox Neo 6M не отвечает
- AT-команда не отвечает на последовательный монитор
- Получить данные с сайта с помощью ESP8266 с помощью AT-команд
- Как отправить команду AT на sim800l с помощью SoftwareSerial
Ваш код, похоже, никогда не выводит
"Нет данных!"
. Это должно быть"Не закодированные данные!"
?, @Peter BloomfieldХорошо, да. я изменил код, @user1584421
Попробуйте изменить скорость передачи Serial.begin() на 4800 и в последовательном мониторе измените то же самое., @Manihatty
Вы делаете это в помещении? Вы уверены, что у вас есть блокировка GPS? Вы получаете данные NMEA даже без блокировки, но это пустые кадры данных NMEA., @Connor Wolf
Мужик, я знаю. Я использую его у нас дома. Получите действительные данные NMEA (увидел координаты на необработанных данных). Пробовал все комбинации скорости передачи. Пробовал разные перестановки, например char c = байт (ss.read()); char c = сс.read(); int c = байт (ss.read()); int c = ss.read(); //лучший байт c = байт (ss.read()); байт c = ss.read(); Никто не может дать мне ответ, это смешно. Попробовал на официальном форуме arduino, написал письмо создателю TinyGPS и TinyGPS++..., @user1584421
Если вы получаете правильные заблокированные данные GPS при выводе необработанного потока NMEA, очевидно, в библиотеке TinyGPS есть проблема, возможно, в результате взаимодействия с вашим конкретным GPS. Добро пожаловать в мир открытого исходного кода. Библиотека TinyGPS — это проект, созданный кем-то в свободное время и выпущенный **бесплатно**. Им *не* нужно вообще заботиться о его поддержке. Поскольку [источник доступен](https://github.com/mikalhart/TinyGPS), почему бы вам не попробовать исправить это самостоятельно?, @Connor Wolf
Попробуйте заставить tinyGPS проанализировать последовательные сообщения с ПК, а затем самостоятельно отправить действительную строку NMEA в последовательный монитор. Таким образом, вы можете быть уверены, что проблема связана с библиотекой или с GPS., @BrettAM
Если вы решили проблему, не могли бы вы опубликовать решение в качестве ответа? Это облегчит поиск для будущих посетителей. Спасибо!, @Peter Bloomfield