Arduino - 故障从维纳斯GPS和MS5803-14BA压力传感器读取传感器数据到Arduino Uno

问题描述:

我试图从我的Arduino Uno获取GPS和压力读数。但是,当我尝试从压力传感器读取压力/温度读数(下面的代码段)时,GPS开始发送格式错误的数据包到我的串行监视器。我希望能够从我的Arduino中获得良好的GPS和压力读数。 (硬件详细信息下面提供)Arduino - 故障从维纳斯GPS和MS5803-14BA压力传感器读取传感器数据到Arduino Uno

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的乌诺R3

GPS:Venus GPS(由Sparkfun制造)

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

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

Setup

是什么导致我的GPS发送错误的数据包?显然,压力传感器会干扰GPS,但它是怎么做到的?我怎样才能避免干扰?

什么导致我的GPS发送坏包?

那么,GPS正在发送数据包好,但Arduino是太忙做其他事情(压库)观看GPS人物进来了。这都是因为SoftwareSerial是CPU猪。其他库,如AltSoftSerial(适用于更少的引脚)或最近的gSoftSerial将是更好的选择。

你真的需要接收GPS 你正在读压力读数吗?为什么不阅读GPS两秒钟以获得修复,然后停下并获取压力读数。停止压力界面并再次启动GPS。冲洗并重复。

我还会为NeoGPS抛出我的义务球场。如果没有其他的例子,这些例子显示了一个不同的程序结构,这将极大地帮助您......您可以在GPS quiet time期间读取压力读数,而无需停止并启动GPS和压力接口。

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

编辑补充:我刚出版NeoSWSerial,以SoftwareSerial的替代方案,是更可靠,使用较少的CPU时间。如果输入捕捉引脚8(用于TX的引脚9)可供您使用,您可以考虑使用NeoICSerial。他们都在NeoGPS附近的github上。