2015-11-07 99 views
0

我試圖從我的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,但它是怎麼做到的?我怎樣才能避免干擾?

回答

0

什麼導致我的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上。