Cのデータ型に関する問題

GPSから経度と緯度を取得したい、Arduinoの究極のGPSブレークアウトを試しています。それから私はこれらの2つの変数をRFで無線で送りたいです。下の画像のように: ここに画像の説明を入力してください

以下のコードのように、Arduino 1から経度と緯度を送信し、Arduino 2で受信するためにpanstampという名前のRFモジュール用のライブラリを使用します。

送信中:

    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(".");
}

送受信時には完璧に動作します:)

問題は、 lon 26.00とlat 27.00 で、 lon 26.533255 lat 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;
}

誰かが私を助けてください:)

The link to the Panstamp library: PanStamp Library

0
なぜあなたはダブルスを受け取れないのですか?あなたは精度を失っています、それは問題ですか?また、ライブラリコードにバグがある可能性があることを指摘しました。
追加された 著者 ha9u63ar,
(自分の仕事の範囲で許可されている場合)必要なのは byte data [...]Double data [...] または float dataに変更することだけです。 [...] このようにして、あなたはあなたが送受信する情報を保存しています。
追加された 著者 ha9u63ar,
おそらく、この割り当ては正しく機能していません。data.data [0] = lon; data.data [1] = lat、ここでfloat型をbyte型に変換しています
追加された 著者 Abhishek Chandel,
おそらく、この割り当ては正しく機能していません。data.data [0] = lon; data.data [1] = lat、ここでfloat型をbyte型に変換しています
追加された 著者 Abhishek Chandel,
それが精度を失う問題です。しかし、私はダブルスやフロートを受け取るために何ができますか?それが私の質問です。
追加された 著者 AdiT,
あなたはヘッダファイルでそれを変更するつもりですか?
追加された 著者 AdiT,
あなたはヘッダファイルでそれを変更するつもりですか?
追加された 著者 AdiT,
それが精度を失う問題です。しかし、私はダブルスやフロートを受け取るために何ができますか?それが私の質問です。
追加された 著者 AdiT,

6 答え

私の知る限りでは、あなたはここであなたの思いを失いました:

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

データはこれに従ったバイトの配列だからです。

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

データを正しくバッファリングする必要があります。

1
追加された
うーん、しかしそれらを正しくバッファリングする方法?私が述べたように私は試したが成功しなかった。あなたは私を助ける何か考えがありますか?
追加された 著者 AdiT,
@AdiT、これを見てみましょう。バイト配列へ "> stackoverflow.com/questions/24420246/…
追加された 著者 HighPredator,

私の知る限りでは、あなたはここであなたの思いを失いました:

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

データはこれに従ったバイトの配列だからです。

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

データを正しくバッファリングする必要があります。

1
追加された
うーん、しかしそれらを正しくバッファリングする方法?私が述べたように私は試したが成功しなかった。あなたは私を助ける何か考えがありますか?
追加された 著者 AdiT,
@AdiT、これを見てみましょう。バイト配列へ "> stackoverflow.com/questions/24420246/…
追加された 著者 HighPredator,

float lon=26.533255; byte *p = (byte *)&lon;

for (int i = 0; i < sizeof(lon); i++){ data.data[i]= p[i]; }

もしそれがlatで同じように動くか、あるいはfloattobyteのような機能を作って使うならば、このようにしなさい。

0
追加された
float f; memcpy(&f、&data.data、sizeof(f)); Serial.println(f);
追加された 著者 Nagaraju Badaeni,
これはfloatをbyteに変換しています....受信側でbyteをfloatに変換する必要があります.....
追加された 著者 Nagaraju Badaeni,
このように印刷できますか?Serial.println(data.data [i])
追加された 著者 AdiT,
うーん、残念ながらうまくいきません。乱数を受け取っただけです。
追加された 著者 AdiT,

float lon=26.533255; byte *p = (byte *)&lon;

for (int i = 0; i < sizeof(lon); i++){ data.data[i]= p[i]; }

もしそれがlatで同じように動くか、あるいはfloattobyteのような機能を作って使うならば、このようにしなさい。

0
追加された
float f; memcpy(&f、&data.data、sizeof(f)); Serial.println(f);
追加された 著者 Nagaraju Badaeni,
これはfloatをbyteに変換しています....受信側でbyteをfloatに変換する必要があります.....
追加された 著者 Nagaraju Badaeni,
このように印刷できますか?Serial.println(data.data [i])
追加された 著者 AdiT,
うーん、残念ながらうまくいきません。乱数を受け取っただけです。
追加された 著者 AdiT,

HighPredatorは正しいです。

From the panstamp lib we see that the CCPACKET::data field is a uint8_t array: 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

4バイトのfloat型を理解する必要があるので、パケットを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

それが役立つことを願っています。

0
追加された

HighPredatorは正しいです。

From the panstamp lib we see that the CCPACKET::data field is a uint8_t array: 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

4バイトのfloat型を理解する必要があるので、パケットを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

それが役立つことを願っています。

0
追加された