0

我目前正在构建一个小型 GPS 盒,它应该可以跟踪我的位置并将完整的 NMEA 语句写入 SD 卡。
(我想在我的电脑上解析它)
我正在使用 Arduino Nano 和NEO-6M GPS 模块来获取数据。

工作原理:从模块中获取 NMEA 数据,写入 SD 卡。
通过 Serial.write 将数据输出到串行输出可以正常工作。

现在我遇到的问题是 Arduino 无法将数据足够快地写入 SD 卡并且与 GPS 模块不同步。这偶尔会产生这样的事情:$G3,3,09,32,20,248,*4D

我对如何解决这个问题有一些想法:
1. 更快地写入数据
2. 始终等到数据完全写入后再获取下一个定位
点 3. 每隔一秒写入一次 GPS 定位点
4. 首先,写入缓冲区,然后写入一去SD卡

我试图实现这些,但每次都失败了(对不起,我是新手)。

这是我当前的代码:

#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>

SoftwareSerial GPS_Serial(4, 3); // GPS Module’s TX to D4 & RX to D3
File GPS_File;
int NBR = 1;  //file number

void setup() {
  Serial.begin(9600);
  GPS_Serial.begin(9600);
  SD.begin(5);

  //write data to a new file
  bool rn = false;
  while (rn == false) {
    if (SD.exists(String(NBR) + ".txt")) {
      NBR = NBR + 1;
    }
    else {
      GPS_File = SD.open(String(NBR) + ".txt", FILE_WRITE);
      GPS_File.write("START\n");
      GPS_File.close();
      rn = true;
    }
  }
}

void loop() {                                               
  GPS_File = SD.open(String(NBR) + ".txt", FILE_WRITE);

  while (GPS_Serial.available() > 0) {
    GPS_File.write((byte)GPS_Serial.read());
  }
  GPS_File.close();
}
4

1 回答 1

0

在尝试了不同的方法后,我决定将其简化为最基本的水平。
没有任何花哨的编码或缓冲区,我现在只是将数据直接写入 SD 卡并每 15 秒刷新一次,这有可能在切割时丢失多达 15 秒的数据,即 15 个 GPS 修复(每秒 1 个)关闭电源。

当程序将累积的数据刷新到 SD 时,会观察到可能发生潜在数据丢失的唯一其他时间。不过,这并不是每次都会发生。

为了将 NMEA 句子解析为可用数据,我使用 GPSBabel。它会自动忽略虚线。转换为 .gpx 后,我使用 Google 地球查看它。

这是“完成”的代码:

#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>

SoftwareSerial GPS_Serial(4, 3);  // GPS Module’s TX to D4 & RX to D3
File GPS_File;
int NBR = 1;                      //file number

unsigned long TimerA;             //save timer
bool sw = false;                  //save timer switch

void setup() {
  Serial.begin(9600);
  GPS_Serial.begin(9600);
  SD.begin(5);                    //SD Pin

  //write data to a new file
  bool rn = false;
  while (rn == false) {
    if (SD.exists(String(NBR) + ".txt")) {
      NBR = NBR + 1;
    }
    else {
      GPS_File = SD.open(String(NBR) + ".txt", FILE_WRITE);
      GPS_File.write("START\n");
      rn = true;
    }
  }
}

void loop() {
  while (GPS_Serial.available() > 0) {
    GPS_File.write(GPS_Serial.read());
  }

  //set up timer
  if ( sw == false) {
    TimerA = millis();
    sw = true;
  }

  //save every 15 seconds
  if (millis() - TimerA >= 15000UL) {
    GPS_File.flush();
    sw = false;
  }
}
于 2020-01-13T18:35:58.183 回答