C dagi ma'lumotlar turlari bilan bog'liq muammolar

I'm trying out The Arduino ultimate GPS breakout, where I want to get the Longitude and Latitude from the GPS. Then I want to send those two variables wireless via RF. like in the image below: enter image description here

Arduino-1dan Longitude va Latitude-ni yuborish va ularni Arduino-2da quyidagi kodga o'xshash qilib yuborish uchun Panstamp nomli chastotali-modul uchun kutubxonadan foydalanaman:

Tarqatish:

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

 }

Qabul qilish:

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

Transmitting va qabul qilishda juda yaxshi ishlaydi :)

lon 26.00 va 27.00 ni olgan ikkita parametrni olganimda muammo emas, balki lon 26.533255 lat 27.533463 Men kutganimdek.

Men taxmin qiladigan ma'lumot turi bilan bog'liq ba'zi xatolar bor. Panstamp kutubxonasini turini o'zgartiradigan, ammo muvaffaqiyatsiz bo'lgan narsalarni topish uchun tekshirdim.

CCPACKET uchun sarlavhali fayl:

#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

va ma'lumotlarni yuborish/qabul qilish uchun manba kodi:

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

Iltimos, menga yordam bering :)

The link to the Panstamp library: PanStamp Library

0
Nima uchun ikkilanishni olmaysiz? Siz aniqlikni yo'qotyapsizmi, bu muammomi? Bundan tashqari, siz kutubxona kodining bugunda xato bo'lishi mumkinligini ta'kidlaysiz
qo'shib qo'ydi muallif ha9u63ar, manba
Sizga kerak bo'lgan yagona narsa (agar sizning ishingiz bo'yicha ruxsat berilsa) bayt ma'lumotlar [...] ni o'zgartirish uchun Ikkita ma'lumot [...] yoki float data [...] . Shu tarzda siz uzatadigan va qabul qilgan ma'lumotni saqlaysiz.
qo'shib qo'ydi muallif ha9u63ar, manba
Ehtimol bu vazifa to'g'ri ishlamayotgan bo'lsa, data.data [0] = lon; data.data [1] = lat, bu erda siz floatni bayt turiga o'zgartirasiz
qo'shib qo'ydi muallif Abhishek Chandel, manba
Ehtimol bu vazifa to'g'ri ishlamayotgan bo'lsa, data.data [0] = lon; data.data [1] = lat, bu erda siz floatni bayt turiga o'zgartirasiz
qo'shib qo'ydi muallif Abhishek Chandel, manba
Bu aniqlik yo'qotadigan muammodir. Ikkita juftlikni olish uchun nima qilishim mumkin? Bu mening savolim.
qo'shib qo'ydi muallif AdiT, manba
Uni nom faylida o'zgartirishni xohlaysizmi?
qo'shib qo'ydi muallif AdiT, manba
Uni nom faylida o'zgartirishni xohlaysizmi?
qo'shib qo'ydi muallif AdiT, manba
Bu aniqlik yo'qotadigan muammodir. Ikkita juftlikni olish uchun nima qilishim mumkin? Bu mening savolim.
qo'shib qo'ydi muallif AdiT, manba

6 javoblar

Ko'rib turganimdek, siz bu yerda sizning tanlovingizni yo'qotdingiz:

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

chunki ma'lumotlar baytlarning bir qatoriga bog'liq:

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

Ma'lumotlarni to'g'ri bufer qilishingiz kerak.

1
qo'shib qo'ydi
Hmm, lekin qanday qilib bularni to'g'ri saqlash kerak? Men aytib o'tganimdek, men muvaffaqiyatli harakat qildim. Menga yordam beradigan biror fikringiz bormi?
qo'shib qo'ydi muallif AdiT, manba
@AdiT, bunga bir ko'z tashlang: stackoverflow.com/questions/24420246/…
qo'shib qo'ydi muallif HighPredator, manba

Ko'rib turganimdek, siz bu yerda sizning tanlovingizni yo'qotdingiz:

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

chunki ma'lumotlar baytlarning bir qatoriga bog'liq:

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

Ma'lumotlarni to'g'ri bufer qilishingiz kerak.

1
qo'shib qo'ydi
Hmm, lekin qanday qilib bularni to'g'ri saqlash kerak? Men aytib o'tganimdek, men muvaffaqiyatli harakat qildim. Menga yordam beradigan biror fikringiz bormi?
qo'shib qo'ydi muallif AdiT, manba
@AdiT, bunga bir ko'z tashlang: stackoverflow.com/questions/24420246/…
qo'shib qo'ydi muallif HighPredator, manba

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

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

agar u ishlayotgan bo'lsa, xuddi shu tarzda harakat qilinsa yoki floattobyte va foydalanish kabi funktsiyani amalga oshirsa.

0
qo'shib qo'ydi
float f; memcpy (& f, & data.data, sizeof (f)); Serial.println (f);
qo'shib qo'ydi muallif Nagaraju Badaeni, manba
bu baytlarga bayroqni aylantirishdir .... Siz baytni qabul qilgichda suzish uchun qo'llashingiz kerak .....
qo'shib qo'ydi muallif Nagaraju Badaeni, manba
Buni shunday chop eta olamanmi: Serial.println (data.data [i])
qo'shib qo'ydi muallif AdiT, manba
Hmm afsuski, u ishlamayapti, men faqat tasodifiy raqamlarni oldim.
qo'shib qo'ydi muallif AdiT, manba

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

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

agar u ishlayotgan bo'lsa, xuddi shu tarzda harakat qilinsa yoki floattobyte va foydalanish kabi funktsiyani amalga oshirsa.

0
qo'shib qo'ydi
float f; memcpy (& f, & data.data, sizeof (f)); Serial.println (f);
qo'shib qo'ydi muallif Nagaraju Badaeni, manba
bu baytlarga bayroqni aylantirishdir .... Siz baytni qabul qilgichda suzish uchun qo'llashingiz kerak .....
qo'shib qo'ydi muallif Nagaraju Badaeni, manba
Buni shunday chop eta olamanmi: Serial.println (data.data [i])
qo'shib qo'ydi muallif AdiT, manba
Hmm afsuski, u ishlamayapti, men faqat tasodifiy raqamlarni oldim.
qo'shib qo'ydi muallif AdiT, manba

HighPredator to'g'ri!

From the panstamp lib we see that the CCPACKET::data field is a uint8_t array: https://github.com/panStamp/panstamp/wiki/CCPACKET#data

Asosan yozganingizda:

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

Derleyici aslida quyidagilarni amalga oshiradi:

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

4-bayt uzunlikdagi float turini tushunishingiz kerak, shuning uchun paketingizni 8 bayt uzunlashtirishingiz va shunday xom baytlarni shunday qilishingiz kerak:

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

Qabul qilish oxirida quyidagi kabi suzish mumkin:

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

Bu yordamga umid qilaman.

0
qo'shib qo'ydi

HighPredator to'g'ri!

From the panstamp lib we see that the CCPACKET::data field is a uint8_t array: https://github.com/panStamp/panstamp/wiki/CCPACKET#data

Asosan yozganingizda:

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

Derleyici aslida quyidagilarni amalga oshiradi:

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

4-bayt uzunlikdagi float turini tushunishingiz kerak, shuning uchun paketingizni 8 bayt uzunlashtirishingiz va shunday xom baytlarni shunday qilishingiz kerak:

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

Qabul qilish oxirida quyidagi kabi suzish mumkin:

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

Bu yordamga umid qilaman.

0
qo'shib qo'ydi