2014-10-28 123 views
0

我正在嘗試Arduino最終GPS突破,我想從GPS獲取經度和緯度。然後我想通過射頻發送這兩個變量。像下面的圖像中: enter image description hereC中的數據類型的問題

我使用名爲panstamp所述RF模塊庫,以便能夠從阿爾杜伊諾1發送的經度和緯度,以及接收它們的Arduino 2.像在下面的代碼:

發射:

void send_data() { 
    CCPACKET data; 
    data.length=2; 

    float lon=26.533255; 
    float lat=27.533463; 


    data.data[0]=lon; 
    data.data[1]=lat; 
    if(cc1101.sendData(data)){ 
    Serial.println(data.data[0]); 
    Serial.println(data.data[1]); 

    Serial.println(" sent ok "); 
    return true; 
    }else{ 
    Serial.println("sent failed "); 
    return false; 
    } 

} 

接收:

void loop(){ 
     float j = 0; 
     lon = packet.data[j]; 
      Serial.print(lon); 
      Serial.print(" "); 
     float k = 1; 
     lat = packet.data[k]; 
      Serial.print(lat); 
      Serial.println("."); 
} 

發射時它完美和REC eiving :)

問題是,當我收到這兩個變量我剛剛收到LON 26.00和LAT 27.00但不經度緯度26.533255 27.533463如我所料。

我假設的數據類型有一些錯誤。我調查了panstamp庫以找到改變類型但沒有成功的東西。

這裏是CCPACKET頭文件:

#ifndef _CCPACKET_H 
#define _CCPACKET_H 

#include "Arduino.h" 

/** 
* Buffer and data lengths 
*/ 
#define CC1101_BUFFER_LEN  64 
#define CC1101_DATA_LEN   CC1101_BUFFER_LEN - 3 

/** 
* Class: CCPACKET 
* 
* Description: 
* CC1101 data packet class 
*/ 
class CCPACKET 
{ 
    public: 
    /** 
    * Data length 
    */ 
    byte length; 

    /** 
    * Data buffer 
    */ 
    byte data[CC1101_DATA_LEN]; 

    /** 
    * CRC OK flag 
    */ 
    boolean crc_ok; 

    /** 
    * Received Strength Signal Indication 
    */ 
    byte rssi; 

    /** 
    * Link Quality Index 
    */ 
    byte lqi; 
}; 

#endif 

和發送數據的源代碼/接收數據:

boolean CC1101::sendData(CCPACKET packet) 
{ 
    byte marcState; 
    bool res = false; 

    // Declare to be in Tx state. This will avoid receiving packets whilst 
    // transmitting 
    rfState = RFSTATE_TX; 

    // Enter RX state 
    setRxState(); 

    // Check that the RX state has been entered 
    while (((marcState = readStatusReg(CC1101_MARCSTATE)) & 0x1F) != 0x0D) 
    { 
    if (marcState == 0x11)  // RX_OVERFLOW 
     flushRxFifo();    // flush receive queue 
    } 

    delayMicroseconds(500); 

    // Set data length at the first position of the TX FIFO 
    writeReg(CC1101_TXFIFO, packet.length); 
    // Write data into the TX FIFO 
    writeBurstReg(CC1101_TXFIFO, packet.data, packet.length); 

    // CCA enabled: will enter TX state only if the channel is clear 
    setTxState(); 

    // Check that TX state is being entered (state = RXTX_SETTLING) 
    marcState = readStatusReg(CC1101_MARCSTATE) & 0x1F; 
    if((marcState != 0x13) && (marcState != 0x14) && (marcState != 0x15)) 
    { 
    setIdleState();  // Enter IDLE state 
    flushTxFifo();  // Flush Tx FIFO 
    setRxState();   // Back to RX state 

    // Declare to be in Rx state 
    rfState = RFSTATE_RX; 
    return false; 
    } 

    // Wait for the sync word to be transmitted 
    wait_GDO0_high(); 

    // Wait until the end of the packet transmission 
    wait_GDO0_low(); 

    // Check that the TX FIFO is empty 
    if((readStatusReg(CC1101_TXBYTES) & 0x7F) == 0) 
    res = true; 

    setIdleState();  // Enter IDLE state 
    flushTxFifo();  // Flush Tx FIFO 

    // Enter back into RX state 
    setRxState(); 

    // Declare to be in Rx state 
    rfState = RFSTATE_RX; 

    return res; 
} 


byte CC1101::receiveData(CCPACKET * packet) 
{ 
    byte val; 
    byte rxBytes = readStatusReg(CC1101_RXBYTES); 

    // Any byte waiting to be read and no overflow? 
    if (rxBytes & 0x7F && !(rxBytes & 0x80)) 
    { 
    // Read data length 
    packet->length = readConfigReg(CC1101_RXFIFO); 
    // If packet is too long 
    if (packet->length > CC1101_DATA_LEN) 
     packet->length = 0; // Discard packet 
    else 
    { 
     // Read data packet 
     readBurstReg(packet->data, CC1101_RXFIFO, packet->length); 
     // Read RSSI 
     packet->rssi = readConfigReg(CC1101_RXFIFO); 
     // Read LQI and CRC_OK 
     val = readConfigReg(CC1101_RXFIFO); 
     packet->lqi = val & 0x7F; 
     packet->crc_ok = bitRead(val, 7); 
    } 
    } 
    else 
    packet->length = 0; 

    setIdleState();  // Enter IDLE state 
    flushRxFifo();  // Flush Rx FIFO 
    //cmdStrobe(CC1101_SCAL); 

    // Back to RX state 
    setRxState(); 

    return packet->length; 
} 

請幫助我的人:)

的鏈接在Panstamp庫:PanStamp Library

+0

爲什麼你不能收到雙打?你正在失去精確度,這就是問題所在?此外,你已經指出,庫代碼可能有錯誤 – ha9u63ar 2014-10-28 11:12:41

+0

這是我失去了精度的問題。但我能做些什麼來接收雙打或浮標?這是我的問題。 – AdiT 2014-10-28 11:17:35

+0

可能是這個賦值工作不正常,data.data [0] = lon; data.data [1] = lat,在這裏您將float轉換爲字節類型 – 2014-10-28 11:30:09

回答

1

據我看到它,你失去了你的presicion這裏:

float lon=26.533255; 
float lat=27.533463; 
data.data[0]=lon; 
data.data[1]=lat; 

,因爲數據是根據這樣的一個字節數組:

/** 
* Data buffer 
*/ 
byte data[CC1101_DATA_LEN]; 

您需要正確bufferise數據。

+0

嗯,但如何正確地緩衝他們?正如我所說,我試過但沒有成功。你有任何想法可以幫助我嗎? – AdiT 2014-10-28 11:31:51

+0

@AdiT,看看這個:http://stackoverflow.com/questions/24420246/c-function-to-convert-float-to-byte-array – HighPredator 2014-10-28 11:34:04

0

float lon = 26.533255; 字節* P =(字節*)&lon;

對(INT I = 0;我<的sizeof(LON);我++){ data.data [I] = P [I]; }

做到這樣,如果它的工作原理進行相同與緯度或作出這樣floattobyte和使用功能。

+0

嗯,不幸的是它不工作,我只是隨機接收數字。 – AdiT 2014-10-28 12:36:41

+0

我可以這樣打印:Serial.println(data.data [i]) – AdiT 2014-10-28 17:01:12

+0

這是將float轉換爲字節....您需要處理字節以在接收器端浮動..... – 2014-10-30 10:35:57

0

HighPredator是對的!

從panstamp lib中我們看到,CCPACKET ::數據字段是一個uint8_t數組: https://github.com/panStamp/panstamp/wiki/CCPACKET#data

基本上當你寫:

float lon=26.533255; 
float lat=27.533463; 
data.data[0]=lon; 
data.data[1]=lat; 

編譯器基本上是這樣做的:

data.data[0]=uint8_t(lon); // So 26.533255f just becomes 26 
data.data[1]=uint8_t(lat); // So 27.533463just becomes 27 

您需要了解float類型,長度爲4個字節,因此您需要將數據包長度爲8個字節並傳輸像這樣的原始字節:

data.length = 8; 
data.data[0] = ((uint8_t*)(&lon))[0]; // Transfer first byte of the float 
data.data[1] = ((uint8_t*)(&lon))[1]; 
data.data[2] = ((uint8_t*)(&lon))[2]; 
data.data[3] = ((uint8_t*)(&lon))[3]; // Transfer last byte of the float 

data.data[4] = ((uint8_t*)(&lat))[0]; // Transfer first byte of the float 
data.data[5] = ((uint8_t*)(&lat))[1]; 
data.data[6] = ((uint8_t*)(&lat))[2]; 
data.data[7] = ((uint8_t*)(&lat))[3]; // Transfer last byte of the float 

在接收端,你可以重新構圖彩車是這樣的:

float lon, lat; 
((uint8_t*)(&lon))[0] = data.data[0]; // Place first byte 
((uint8_t*)(&lon))[1] = data.data[1]; 
((uint8_t*)(&lon))[2] = data.data[2]; 
((uint8_t*)(&lon))[3] = data.data[3]; // Place last byte 

((uint8_t*)(&lat))[0] = data.data[4]; // Place first byte 
((uint8_t*)(&lat))[1] = data.data[5]; 
((uint8_t*)(&lat))[2] = data.data[6]; 
((uint8_t*)(&lat))[3] = data.data[7]; // Place last byte 

希望有所幫助。