简体   繁体   English

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

[英]Arduino - Trouble reading sensor data from Venus GPS and MS5803-14BA Pressure Sensor to Arduino Uno

I'm trying to get GPS and pressure readings from my Arduino Uno. 我正在尝试从Arduino Uno获取GPS和压力读数。 However, when I try to get pressure/temperature readings off of the pressure sensor (code snippet below), the GPS starts sending malformed packets to my serial monitor. 但是,当我尝试从压力传感器获取压力/温度读数时(下面的代码片段),GPS开始向我的串行监视器发送格式错误的数据包。 I'd like to be able to get good GPS and pressure readings from my Arduino. 我希望能够从Arduino获得良好的GPS和压力读数。 (Hardware details provided below) (下面提供了硬件详细信息)

  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.
}

Here's the full code: 这是完整的代码:

#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';
} 

When the line to get pressure is commented like so... 当线受到压力时,评论如下:

  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.
}

...my GPS gives me proper packets of 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
-----------------------

But when my line to get pressure is uncommented... 但是当我承受压力的时候没有评论...

  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.
}

My GPS packets become malformed: 我的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
-----------------------

Hardware: 硬件:

Arduino board: Arduino Uno R3 Arduino开发板:Arduino Uno R3

GPS: Venus GPS (made by Sparkfun) GPS:金星GPS(由Sparkfun制造)

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

Data logger: OpenLog (made by Sparkfun) 数据记录器:OpenLog(Sparkfun制造)

Setup 设定

What's causing my GPS to send bad packets? 是什么导致我的GPS发送错误数据包? Evidently, the pressure sensor is somehow interfering with the GPS, but how is it doing that and how can I avoid interference? 显然,压力传感器在某种程度上干扰了GPS,但是它如何做到这一点,又如何避免干扰呢?

What's causing my GPS to send bad packets? 是什么导致我的GPS发送错误数据包?

Well, the GPS is sending good packets, but the Arduino is too busy doing other things (pressure library) to watch the GPS characters come in. It's all because SoftwareSerial is a CPU hog. 嗯,GPS正在发送良好的数据包,但是Arduino忙于做其他事情(压力库)以至于无法观看GPS字符的出现。这都是因为SoftwareSerial占用了CPU的资源。 Other libraries, like AltSoftSerial (works on fewer pins), or the recent gSoftSerial would be better choices. 其他库,例如AltSoftSerial(在较少的引脚上工作)或最新的gSoftSerial将是更好的选择。

Do you really need to receive GPS while you're getting a pressure reading? 获取压力读数时,您真的需要接收GPS吗? Why not read GPS for two seconds to get a fix, then stop it and get the pressure reading. 为什么不读GPS两秒钟以获取修复,然后停止它并获得压力读数。 Stop the pressure interface and start the GPS again. 停止压力接口,然后再次启动GPS。 Rinse and repeat. 冲洗并重复。

I'll also throw in my obligatory pitch for NeoGPS . 我还将为NeoGPS尽责 If nothing else, the examples show a different program structure that would help immensely... you may be able to take the pressure reading during the GPS quiet time , without stopping and starting the GPS and pressure interfaces. 如果没有其他说明,示例将显示一个不同的程序结构,这将极大地帮助您……您可以在GPS安静时间内获取压力读数,而无需停止和启动GPS和压力接口。

NeoGPS also parses the characters as they are received, so you don't have to buffer the sentence. NeoGPS还会在收到字符时对它们进行解析,因此您不必缓冲句子。 BTW, I recommend staying away from String, like many developers. 顺便说一句,我建议像许多开发人员一样远离String。

Edit to add: I just published NeoSWSerial, an alternative to SoftwareSerial that is much more reliable and uses much less CPU time. 编辑补充:我刚出版NeoSWSerial,以替代SoftwareSerial更为可靠,使用较少的CPU时间。 If the Input Capture pin 8 (and pin 9 for TX) is a possibility for you to use, you might consider NeoICSerial. 如果您可以使用输入捕捉引脚8(TX的引脚9),则可以考虑使用NeoICSerial。 They're both on github near NeoGPS. 它们都在NeoGPS附近的github上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM