【问题标题】:Arduino - Trouble reading sensor data from Venus GPS and MS5803-14BA Pressure Sensor to Arduino UnoArduino - 无法从 Venus GPS 和 MS5803-14BA 压力传感器读取传感器数据到 Arduino Uno
【发布时间】:2016-02-08 07:51:39
【问题描述】:

我正在尝试从我的 Arduino Uno 获取 GPS 和压力读数。但是,当我尝试从压力传感器(下面的代码 sn-p)获取压力/温度读数时,GPS 开始向我的串行监视器发送格式错误的数据包。我希望能够从我的 Arduino 获得良好的 GPS 和压力读数。 (下面提供硬件详细信息)

  float temperature_c, temperature_f;
  double pressure_abs, pressure_relative, altitude_delta, pressure_baseline;

  String dataString = ""; 

  pressure_abs = sensor.getPressure(ADC_4096); //IF THIS LINE REMOVED, GPS SENDS GOOD DATA.
}

这是完整的代码:

#include <SoftwareSerial.h>

//pressure sensor libraries
#include <Wire.h>
#include <SparkFun_MS5803_I2C.h>

//datalogger library
#include <SPI.h>
#include <SD.h>

// set up datalogger
const int chipSelect = 4;

/*-----------GPS-----------*/
SoftwareSerial gpsSerial(10, 11); // RX, TX (TX not used)
const int sentenceSize = 80;

// the $GPGGA, $GPGSA, etc. are sentences and are sent 1 character at a time from the GPS
char sentence[sentenceSize];

/*------------Pressure sensor-------*/
// Begin class with selected address
// available addresses (selected by jumper on board) 
// default is ADDRESS_HIGH

//  ADDRESS_HIGH = 0x76
//  ADDRESS_LOW  = 0x77

MS5803 sensor(ADDRESS_HIGH);

// Create Variable to store altitude in (m) for calculations;
double pressure_baseline;
double base_altitude = 1655.0; // Altitude of SparkFun's HQ in Boulder, CO. in (m)

void setup()
{
  Serial.begin(9600);
  gpsSerial.begin(9600);

  /*----------Pressure sensor stuff----------*/
    Serial.println("\ntemperature (C), temperature (F), pressure (abs), pressure (relative), change in altitude");
    //Retrieve calibration constants for conversion math.
    sensor.reset();
    sensor.begin();

    pressure_baseline = sensor.getPressure(ADC_4096);
    Serial.println(pressure_baseline);
    Serial.println("\n");
}

void loop()
{
  static int i = 0;
  if (gpsSerial.available())
  {
//    Serial.print("GPS Serial is available\n");
    char ch = gpsSerial.read();
    if (ch != '\n' && i < sentenceSize)
    {
      sentence[i] = ch;
      i++;
    }
    else
    {
     sentence[i] = '\0';
     i = 0;
//     Serial.println("\n");
     Serial.println(sentence);
//     Serial.println("\n");
     displayGPS();
    }
  }

  /*----------------------PRESSURE SENSOR-------------------------*/
  float temperature_c, temperature_f;
  double pressure_abs, pressure_relative, altitude_delta, pressure_baseline;

  String dataString = ""; 

  pressure_abs = sensor.getPressure(ADC_4096); //IF THIS LINE REMOVED, GPS SENDS GOOD DATA.
}

/*--------------------------Pressure sensor methods----------------*/
// Thanks to Mike Grusin for letting me borrow the functions below from 
// the BMP180 example code. 

 double sealevel(double P, double A)
// Given a pressure P (mbar) taken at a specific altitude (meters),
// return the equivalent pressure (mbar) at sea level.
// This produces pressure readings that can be used for weather measurements.
{
  return(P/pow(1-(A/44330.0),5.255));
}

double altitude(double P, double P0)
// Given a pressure measurement P (mbar) and the pressure at a baseline P0 (mbar),
// return altitude (meters) above baseline.
{
  return(44330.0*(1-pow(P/P0,1/5.255)));
}

void displayGPS()
{
  char field[20];
  getField(field, 0);
  if (strcmp(field, "$GPGGA") == 0)
  {
    Serial.print("Lat: ");
    getField(field, 2);  // number
    Serial.print(field);
    getField(field, 3); // N/S
    Serial.print(field);

    Serial.print(" Long: ");
    getField(field, 4);  // number
    Serial.print(field);
    getField(field, 5);  // E/W
    Serial.println(field);

    Serial.print("Altitude: ");
    getField(field, 9);
    Serial.println(field);

    Serial.print("Number of satellites: ");
    getField(field, 7);
    Serial.println(field);
    Serial.println("-----------------------\n");
  }
}

void getField(char* buffer, int index)
{
  int sentencePos = 0;
  int fieldPos = 0;
  int commaCount = 0;
  while (sentencePos < sentenceSize)
  {
    if (sentence[sentencePos] == ',')
    {
      commaCount ++;
      sentencePos ++;
    }
    if (commaCount == index)
    {
      buffer[fieldPos] = sentence[sentencePos];
      fieldPos ++;
    }
    sentencePos ++;
  }
  buffer[fieldPos] = '\0';
} 

当获得压力的线路被这样评论时......

  float temperature_c, temperature_f;
  double pressure_abs, pressure_relative, altitude_delta, pressure_baseline;

  String dataString = ""; 

  // pressure_abs = sensor.getPressure(ADC_4096); //IF THIS LINE REMOVED, GPS SENDS GOOD DATA.
}

...我的 GPS 给了我正确的数据包:

$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30
$GPRMC,120208.000,V,24006,,,N*71
$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02
$GPGGA,120209.000,2400.0000,N,12100.0000,E,0,00,0.0,0.0,M,0.0,M,,0000*61

Lat: 2400.0000N Long: 12100.0000E
Altitude: 0.0
Number of satellites: 00
-----------------------

$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30
$GPRMC,120209.000,V,24006,,,N*70
$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02
$GPGGA,120210.000,2400.0000,N,12100.0000,E,0,00,0.0,0.0,M,0.0,M,,0000*69

Lat: 2400.0000N Long: 12100.0000E
Altitude: 0.0
Number of satellites: 00
-----------------------

$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30
$GPRMC,120210.000,V,240006,,,N*78
$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02
$GPGGA,120211.000,2400.0000,N,12100.0000,E,0,00,0.0,0.0,M,0.0,M,,0000*68
Lat: 2400.0000N Long: 12100.0000E
Altitude: 0.0
Number of satellites: 00
-----------------------

但是当我的压力线没有注释时......

  float temperature_c, temperature_f;
  double pressure_abs, pressure_relative, altitude_delta, pressure_baseline;

  String dataString = ""; 

  pressure_abs = sensor.getPressure(ADC_4096); //IF THIS LINE REMOVED, GPS SENDS GOOD DATA.
}

我的 GPS 数据包格式错误:

$GPGGA,120125.000,2400.0000,N,12100.0000,E,0,00,0.0,0.0,M,0.0,M,,$0,0T,$GPGGA,12
Lat: 2400.0000N Long: 12100.0000E
Altitude: 0.0
Number of satellites: 00
-----------------------

126.000,2400.0000,N,120,00..
$GPGGA,120127.000,2400.0000,N,100,$GPGGA,120128.000,2400.0000,N,1200,20*0$GPGGA,
Lat: 2400.0000N Long: 100$GPGGA
Altitude: 1200
Number of satellites: 2400.0000
-----------------------

20129.000,2400.0000,N,120G.4,,*$GPGGA,120130.000,2400.0000,N,1060$GPGGA,120131.0
0,2400.0000,N,12,*..E
0$GPGGA,120132.000,2400.0000,N,120A00.0
$GPGGA,120133.000,2400.0000,N,1M,
0,,$GPGGA,120134.000,2400.0000,N,1200,1070$GPGGA,120135.000,2400.0000,N,10,,,0,0
GPGGA,120136.000,2400.0000,N,120G0,0V,$GPGGA,120137.000,2400.0000,N,1,,30000
$GP
GA,120138.000,2400.0000,N,0G00V0VK$GPGGA,120139.000,2400.0000,N1,,VP,6,$GPGGA,12
140.000,2400.0000,N,1.,0*.0.
$GPGGA,120141.000,2400.0000,N,0A*00*N$GPGGA,120142.000,2400.0000,N,.,,110,0$GPGG
Lat: 2400.0000N Long: 0A*00*N$GPGGA120142.000
Altitude: ,110
Number of satellites: N
-----------------------

,120143.000,2400.0000,N,1,,P$02,$GPGGA,120144.000,2400.0000,N,10.0$GPGGA,120145.
00,2400.0000,N,10A*00000$GPGGA,120146.000,2400.0000,N,0G.020,*$GPGGA,120147.000,
400.0000,N0,,20,0$GPGGA,120148.000,2400.0000,N,120P,,0P,$GPGGA,120149.000,2400.0
00,N,1.S0000*$GPGGA,120150.000,2400.0000,N,1.,,,0,0$GPGGA,120151.000,2400.0000,N
100,50E,$GPGGA,120152.000,2400.0000,N,120S.00,N$GPGGA,120153.000,2400.0000,N,1.A
0002$GPGGA,120154.000,2400.0000,N,1.,,00N,$GPGGA,120155.000,2400.0000,N,1E*..0A0
GPGGA,120156.000,2400.0000,N,120S0400N$GPGGA,120157.000,2400.0000,N,1.A0.000$GPG
A,120158.000,2400.0000,N,100,2.N.$GPGGA,120159.000,2400.0000,N,100,906,$GPGGA,12
200.000,2400.0000,N,120,*000*$GPGGA,120201.000,2400.0000,N,10,,,.GN$GPGGA,120202
000,2400.0000,N,11,,C160$GPGGA,120203.000,2400.0000,N,12,6.00
,$GPGGA,120204.000
2400.0000,N,100,00*,$GPGGA,120205.000,2400.0000,N,120,300.
$GPGGA,120206.000,2400.0000,N,1.,R,0M$GPGGA,120207.000,2400.0000,N,12,00007N$GPG
Lat: 2400.0000N Long: 1.R
Altitude: N
Number of satellites: 120207.000
-----------------------

A,120208.000,2400.0000,N,12,A*000
$GPGGA,120209.000,2400.0000,N,007,$GPGGA,12021
.000,2400.0000,N,12,A*.00
$GPGGA,120211.000,2400.0000,N,10,,20N2$GPGGA,120212.00
,2400.0000,N,100,20N0$GPGGA,120213.000,2400.0000,N,120G040GN$GPGGA,120214.000,24
0.0000,N,1,,3.002$GPGGA,120215.000,2400.0000,N,1.,,,160$GPGGA,120216.000,2400.00
0,N,100,2.N,$GPGGA,120217.000,2400.0000,N,12,G0V.TK$GPGGA,120218.000,2400.0000,N
10G04,,0$GPGGA,120219.000,2400.0000,N,10,,10,0$GPGGA,120220.000,2400.0000,N,1,*,
0BN$GPGGA,120221.000,2400.0000,N,120S00002$GPGGA,120222.000,2400.0000,N,1M,
0,T$GPGGA,120223.000,2400.0000,N,1200,208N$GPGGA,120224.000,2400.0000,N,100,2.N,
GPGGA,120225.000,2400.0000,N,120G02.TN$GPGGA,120226.000,2400.0000,N,10,0000*$GPG
A,120227.000,2400.0000,N,1.,,00,,$GPGGA,120228.000,2400.0000,N,1E6..03,$GPGGA,12
229.000,2400.0000,N,12,,*0000$GPGGA,120230.000,2400.0000,N,1.,,0000$GPGGA,120231
000,2400.0000,N,100,2.,0$GPGGA,120232.000,2400.0000,N,12.S0000*$GPGGA,120233.000
2400.0000,N,1.S.20TK$GPGGA,120234.000,2400.0000,N,12M,$N0M$GPGGA,120235.000,2400
0000,N,10M,C160$GPGGA,120236.000,2400.0000,N,12,$.,0G0$GPGGA,120237.000,2400.000
,N,1,P,,0G,$GPGGA,120238.000,2400.0000,N,10,,C100$GPGGA,120239.000,2400.0000,N,1
,,C1,0$GPGGA,120240.000,2400.0000,N,12,G,2.G,$GPGGA,120241.000,2400.0000,N,10A00
0
$GPGGA,120242.000,2400.0000,N,1.,,00*N$GPGGA,120243.000,2400.0000,N,1,*0.,
0$G
GGA,120244.000,2400.0000,N,120A00000$GPGGA,120245.000,2400.0000,N,10,
0,,$GPGGA,120246.000,2400.0000,N,1200,407N$GPGGA,120247.000,2400.0000,N,12,,R16M
GPGGA,120248.000,2400.0000,N,1200,80
0$GPGGA,120249.000,2400.0000,N,10
,00,$.$GP
GA,120250.000,2400.0000,N,0,,1C1,0$GPGGA,120251.000,2400.0000,N,.S0,4,,*$GPGGA,1
0252.000,2400.0000,N,0
000,G0$GPGGA,120253.000,2400.0000,N,00,,.0.
$GPGGA,120254.000,2400.0000,N,,A*00002$GPGGA,120255.000,2400.0000,N,0A*00002$GPG
Lat: 2400.0000N Long: ,A*00002$GPGGA120255.000
Altitude: 
Number of satellites: N
-----------------------

硬件:

Arduino 板:Arduino Uno R3

GPS:Venus GPS(由 Sparkfun 制造)

压力传感器:Ms5803-14BA Breakout(Sparkfun 制造)

数据记录器:OpenLog(由 Sparkfun 制造)

Setup

是什么导致我的 GPS 发送错误数据包?显然,压力传感器以某种方式干扰了 GPS,但它是如何做到的,如何避免干扰?

【问题讨论】:

    标签: gps arduino sensors arduino-uno


    【解决方案1】:

    是什么导致我的 GPS 发送错误数据包?

    好吧,GPS 正在发送良好的数据包,但 Arduino 正忙于做其他事情(压力库)而无法看到 GPS 字符进来。这完全是因为 SoftwareSerial 占用了 CPU。其他库,如 AltSoftSerial(在更少的引脚上工作)或最近的 gSoftSerial 会是更好的选择。

    您真的需要在获得压力读数的同时接收 GPS 吗?为什么不读取 GPS 两秒钟以获得修复,然后停止它并获取压力读数。停止压力接口,重新启动 GPS。冲洗并重复。

    我还将为NeoGPS 进行必修课。如果不出意外,这些示例显示了一个不同的程序结构,这将非常有帮助......您可以在GPS quiet time 期间读取压力读数,而无需停止和启动 GPS 和压力接口。

    NeoGPS 还会在收到字符时对其进行解析,因此您不必缓冲句子。顺便说一句,我建议像许多开发人员一样远离 String。

    编辑添加:我刚刚发布了 NeoSWSerial,它是SoftwareSerial 的替代品,它更加更可靠并且使用的 CPU 时间更少。如果您可以使用输入捕获引脚 8(以及用于 TX 的引脚 9),您可以考虑使用 NeoICSerial。他们都在 NeoGPS 附近的 github 上。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多