Arduino - 无法从Venus GPS和MS5803-14BA压力传感器读取传感器数据到Arduino Uno

时间:2015-11-07 04:25:20

标签: gps arduino sensor arduino-uno

我试图从我的Arduino Uno获取GPS和压力读数。但是,当我试图从压力传感器(下面的代码片段)中获取压力/温度读数时,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,但它是如何做到这一点的,我该如何避免干扰呢?

1 个答案:

答案 0 :(得分:0)

  

导致我的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上。