Получение данных с GPS (GY-NEO-6M)
GPS-модуль NEO-6M даёт:
координаты (широта, долгота);
высоту над уровнем моря;
UTC-время и дату;
количество спутников и качество приёма (HDOP).
Это самый «капризный» из всех модулей кубсата — его нужно правильно подключить, дождаться холодного старта и понимать особенности прошивки. Прочитайте раздел «Важно» ниже до того, как приступать к тесту.
Важно: GPS «съедает» Serial Monitor
В кубсате GPS подключён к D0 (RX0) — это аппаратный UART
Arduino. На этой же линии работает и USB-канал общения Nano с
компьютером (Serial Monitor). Из этого следуют три практически важных
последствия:
Скорость UART жёстко 9600 бод. Это естественная скорость NEO-6M (NMEA по умолчанию). И
main_full, иgps_sd_loggerиспользуютSerial.begin(9600).Скетчи с GPS почти не пишут в Serial Monitor. Шина занята входящим потоком NMEA — если параллельно выводить отладку, она будет смешиваться с RAW-строками от GPS. Поэтому
gps_sd_logger.inoсделан «молчащим»: проверка результата = вынуть SD-карту и прочитатьGPSLOG.CSV.При прошивке нужно физически отсоединять TX-провод GPS от ``D0``. Иначе компьютер и GPS оба пытаются говорить в
RX0Nano —avrdudeне может синхронизироваться, выдаётstk500_getsync().
Примечание
Почему так сделано? SoftwareSerial на Arduino Nano работает, но
занимает ~1.5 КБ Flash и съедает прерывания. main_full уже
близок к лимиту памяти Nano, и каждый килобайт на счету.
Жертвуем удобной отладкой ради того, что сборка вообще помещается.
Workflow перепрошивки
Каждый раз когда вы хотите залить новый скетч на Nano, в котором работает GPS:
Отсоедините белый/жёлтый провод TX модуля GPS от пина
D0Nano. Достаточно вытянуть один провод.Sketch → Upload.Дождитесь сообщения
Done uploading.Подключите TX-провод GPS обратно в
D0.Нажмите
Resetна Nano (или просто переподключите USB) — скетч стартует заново и GPS начнёт отдавать NMEA.
Если попытаться залить с подключённым GPS — почти всегда получите
avrdude: stk500_getsync(): not in sync: resp=0x00.
Необходимые библиотеки
TinyGPSPlus(Mikal Hart) — парсинг NMEA;SD(встроена в Arduino IDE).
Тестовый скетч: GPS → SD логгер
#include <SPI.h>
#include <SD.h>
#include <TinyGPS++.h>
// ВАЖНО: на Nano GPS TX -> D0 (RX0), поэтому Serial занят GPS.
// Во время прошивки лучше отключать TX GPS от D0.
const uint8_t SD_CS = 4;
const char* LOG_FILE = "GPSLOG.CSV";
const unsigned long LOG_PERIOD_MS = 1000;
TinyGPSPlus gps;
unsigned long lastLogMs = 0;
void writeHeaderIfNeeded() {
if (SD.exists(LOG_FILE)) return;
File f = SD.open(LOG_FILE, FILE_WRITE);
if (!f) return;
f.println("ms,fix,sats,hdop,lat,lon,alt_m,utc_hhmmss,date_ddmmyyyy,chars,crc_ok,crc_bad");
f.close();
}
void logRow() {
File f = SD.open(LOG_FILE, FILE_WRITE);
if (!f) return;
f.print(millis());
f.print(',');
f.print(gps.location.isValid() ? 1 : 0);
f.print(',');
f.print(gps.satellites.isValid() ? (int)gps.satellites.value() : 0);
f.print(',');
if (gps.hdop.isValid()) f.print(gps.hdop.hdop(), 1); else f.print('0');
f.print(',');
if (gps.location.isValid()) f.print(gps.location.lat(), 6); else f.print('0');
f.print(',');
if (gps.location.isValid()) f.print(gps.location.lng(), 6); else f.print('0');
f.print(',');
if (gps.altitude.isValid()) f.print(gps.altitude.meters(), 1); else f.print('0');
f.print(',');
if (gps.time.isValid()) {
unsigned long t = gps.time.hour() * 10000UL + gps.time.minute() * 100UL + gps.time.second();
f.print(t);
} else {
f.print('0');
}
f.print(',');
if (gps.date.isValid()) {
unsigned long d = gps.date.day() * 1000000UL + gps.date.month() * 10000UL + gps.date.year();
f.print(d);
} else {
f.print('0');
}
f.print(',');
f.print((unsigned long)gps.charsProcessed());
f.print(',');
f.print((unsigned long)gps.passedChecksum());
f.print(',');
f.print((unsigned long)gps.failedChecksum());
f.println();
f.close();
}
void setup() {
// Serial используется только как вход GPS @9600
Serial.begin(9600);
SD.begin(SD_CS);
writeHeaderIfNeeded();
lastLogMs = millis();
}
void loop() {
while (Serial.available()) {
gps.encode(Serial.read());
}
unsigned long now = millis();
if (now - lastLogMs >= LOG_PERIOD_MS) {
lastLogMs = now;
logRow();
}
}
Что он делает:
читает поток NMEA с
Serial(= с GPS);раз в секунду пишет на microSD строку CSV в файл
GPSLOG.CSV.
В Serial Monitor скетч ничего не печатает — Serial занят GPS. Это нормально.
Как запустить и проверить
Соберите кубсат / положите его на улицу или у окна с открытым видом на небо. NEO-6M практически не ловит спутники в помещении.
Залейте
gps_sd_logger.ino(не забудьте отключить TX GPS на время заливки!).Подключите TX GPS обратно. Reset.
Подождите 30 секунд - 5 минут — это «холодный старт» NEO-6M. Если это первое включение модуля или после долгого простоя — могут потребоваться все 5 минут на улице.
Извлеките microSD, вставьте в компьютер, откройте
GPSLOG.CSV.
Что должно быть в GPSLOG.CSV
Заголовок и строки лога раз в секунду. Первые секунды (нет fix’а):
ms,fix,sats,hdop,lat,lon,alt_m,utc_hhmmss,date_ddmmyyyy,chars,crc_ok,crc_bad
1010,0,0,0,0,0,0,0,0,1234,15,0
2010,0,0,0,0,0,0,0,0,2456,32,0
3010,0,1,0,0,0,0,0,0,3678,48,0
После того как пойман сигнал (fix=1 и заполнились координаты):
62015,1,7,1.2,52.456789,4.123456,12.5,143012,8052026,205314,1812,3
63015,1,7,1.1,52.456789,4.123456,12.6,143013,8052026,208645,1839,3
Колонки:
fix— есть позиционирование (0/1);sats— спутников в решении;hdop— горизонтальная погрешность (меньше = лучше;< 2— отлично,> 5— плохо);lat/lon/alt_m— координаты и высота;utc_hhmmss/date_ddmmyyyy— UTC время и дата;chars— сколько байт NMEA скетч получил с модуля (растёт всегда);crc_ok/crc_bad— целостность NMEA-предложений.
Если chars=0 и crc_ok=0
GPS вообще не передаёт ничего на Nano:
проверьте, что TX модуля GPS подключён к ``D0`` Nano (после заливки часто забывают воткнуть обратно);
индикатор на модуле должен моргать (когда есть связь со спутниками — раз в секунду);
проверьте питание
5VиGNDмодуля.
Если chars растёт, но fix=0 много минут
Антенна не на открытом небе — занесите кубсат к окну, ещё лучше на балкон/улицу;
Холодный старт после долгого хранения — дайте до 15 минут;
Многоэтажки/металлические балконы экранируют сигнал — попробуйте открытое место.