为什么XBee传输有时会失败?

时间:2013-12-19 16:34:38

标签: arduino xbee

我正在进行Arduino Uno R3和XBee S2传输的项目。我使用了几个传感器,如无线(RF)温度传感器,两个SHT75传感器,一个3轴加速度计和一个照度传感器。收集数据后,我们使用XBee(S2,API模式)将数据发送到网关。每轮大约一秒钟。

  1. 第一个问题是数据大约是16个字节,但数据包每轮都没有成功发送。有时它工作,有时它没有,但XBee的有效载荷在数据表中可以是60或70字节......但是如果我把有效载荷放在一些简单的整数(如1,2,3),而不是来自传感器的数据,传输将是稳定的。

  2. 在遇到上述问题后,我将数据分成两个数据包(每个数据包有8个字节的有效负载),第一个数据包非常稳定,但第二个数据包非常不稳定。如上所述,如果我将一些数字放入第二个数据包而不是传感数据,第二个数据包将变得稳定并且每轮都成功发送。

  3. 所以我认为这是代码问题,但idk问题出在哪里。我尝试改变波特率或增加两个数据包之间的延迟时间。问题出在哪儿?以下是我的代码:

    #include <XBee.h>
    #include <i2cmaster.h>
    #include <string.h>
    #include <ctype.h>
    #include <Sensirion.h>
    #include "Wire.h"
    #include "MMA845XQ.h"
    
    **///////////////////////////// XBee setup //////////////////////////////////**
    XBee xbee = XBee();
    XBeeAddress64 remoteAddress = XBeeAddress64(0x00000000, 0x00000000);
    ZBRxResponse zbRx = ZBRxResponse();
    ZBTxStatusResponse zbTxStus = ZBTxStatusResponse();
    
    uint8_t payload[] = {0,0,0,0,0,0,0,0,0};
    uint8_t payload1[] = {0,0,0,0,0,0,0,0,0};
    
    **///////////////////////////// Accelerometer //////////////////////////////////**
    MMA845XQ accel;
    
    **////////////////////////// SHT1 serial data and clock ////////////////////**
    const byte dataPin = 2;
    const byte sclkPin = 3;
    Sensirion sht = Sensirion(dataPin, sclkPin);
    unsigned int rawData;
    float temperature;
    float humidity;
    byte stat;
    
    **////////////////////////// SHT2 serial data and clock ////////////////////**
    const byte dataPin1 = 4;
    const byte sclkPin1 = 5;
    Sensirion sht1 = Sensirion(dataPin1, sclkPin1);
    unsigned int rawData1;
    float temperature1;
    float humidity1;
    byte stat1;
    
    **//////////////////////////// Illumination sensor ////////////////////////**
    int sensorPin = A0;    // Select the input pin for the potentiometer
    int sensorValue = 0;   // Variable to store the value coming from the sensor
    long int pardata, pardata_low, pardata_hi, real_pardata;
    uint16_t illumindata = 0;
    
    void setup () {
        i2c_init(); //Initialise the I²C bus
        PORTC = (1 << PORTC4) | (1 << PORTC5); //Enable pullups
        Wire.begin();
        accel.begin(false, 2);
        Serial.begin(115200);
        xbee.begin(Serial);
    }
    
    void loop () {
        payload[0] = 10;
        payload1[0] = 11;
    
        **/////////////////////RF temperature sensor/////////////////////////////**
        int dev = 0x5A<<1;
        int data_low = 0;
        int data_high = 0;
        int pec = 0;
        i2c_start_wait(dev + I2C_WRITE);
        i2c_write(0x07);
        i2c_rep_start(dev + I2C_READ);
        data_low = i2c_readAck(); //Read 1 byte and then send ack
        data_high = i2c_readAck(); //Read 1 byte and then send ack
        pec = i2c_readNak();
        i2c_stop();
    
        double tempFactor = 0.02; // 0.02 degrees per LSB (measurement resolution of the MLX90614)
        double tempData = 0x0000; // Zero out the data
        int frac; // Data past the decimal point
    
        // This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
        tempData = (double)(((data_high & 0x007F) << 8) + data_low);
        tempData = (tempData * tempFactor)-0.01;
        float celcius = tempData - 273.15;
        float fahrenheit = (celcius*1.8) + 32;
    
        celcius *= 100;
        int a = int(celcius) + 1;
        payload[1] = a >> 8 & 0xff;
        payload[2] = a & 0xff;
    
        **//////////////////////////// Illumination sensor ////////////////////////////////**
        sensorValue = analogRead(sensorPin);
        TSR(sensorValue);
    
        payload[3] = pardata_low >> 8 & 0xff;
        payload[4] = pardata_low & 0xff;
    
        **//////////////////////////// 3-axis accelemeter sensor ////////////////////////////////**
        accel.update();
        payload[5] = accel.getX()*10;
        payload[6] = accel.getY()*10;
        payload[7] = accel.getZ()*10;
    
        delay(100);
    
        **////////////////////////////// XBee send first packet///////////////////////////////////////////////**
        xbee = XBee();
        xbee.begin(Serial);
        ZBTxRequest zbTx = ZBTxRequest(remoteAddress, payload, sizeof(payload));
        zbTx.setAddress16(0xfffe);
        xbee.send(zbTx);
    
        delay(500);
    
        **//////////////// SHT 1x temperature and humidity sensor /////////////////////////**
        sht.readSR(&stat);                     // Read sensor status register
        sht.writeSR(LOW_RES);                  // Set sensor to low resolution
        sht.readSR(&stat);                     // Read sensor status register again
        sht.measTemp(&rawData);                // sht.meas(TEMP, &rawData, BLOCK)
        sht.meas(TEMP, &rawData, NONBLOCK);
        temperature = sht.calcTemp(rawData);
        sht.measHumi(&rawData);                // sht.meas(HUMI, &rawData, BLOCK)
        humidity = sht.calcHumi(rawData, temperature);
        sht.meas(HUMI, &rawData, NONBLOCK);
        humidity = sht.calcHumi(rawData, temperature);
        temperature *= 100;
        a = int(temperature) + 1;
    
        payload1[1] = a >> 8 & 0xff;
        payload1[2] = a & 0xff;
    
        humidity *= 100;
        a = int(humidity) + 1;
        payload1[3] = a >> 8 & 0xff;
        payload1[4] = a & 0xff;
    
        delay(10);
    
        sht1.readSR(&stat1);
        sht1.writeSR(LOW_RES);                  // Set sensor to low resolution
        sht1.readSR(&stat1);
        sht1.measTemp(&rawData1);                // sht.meas(TEMP, &rawData, BLOCK)
        temperature1 = sht1.calcTemp(rawData1);
        sht1.measHumi(&rawData1);                // sht.meas(HUMI, &rawData, BLOCK)
        humidity1 = sht1.calcHumi(rawData1, temperature1);
    
        delay(10);
    
        temperature1 *= 100;
        a = int(temperature1) + 1;
        payload1[5] = a >> 8 & 0xff;
        payload1[6] = a & 0xff;
    
        humidity1 *= 100;
        a = int(humidity1) + 1;
        payload1[7] = a >> 8 & 0xff;
        payload1[8] = a & 0xff;
    
        **////////////////////////////// XBee send second packet ///////////////////////////////////////////////**
        xbee = XBee();
        xbee.begin(Serial);
        zbTx = ZBTxRequest(remoteAddress,payload1, sizeof(payload1));
        zbTx.setAddress16(0xfffe);
        xbee.send(zbTx);
        delay(500);
    }
    
    void TSR(int sensorValue)
    {
        illumindata = (sensorValue * 4 * 5) / 1.5;
        pardata = 6250/6144*illumindata*10;
    
        if(pardata > 0)
        {
            if(pardata < 11500)
            {
                real_pardata = 0.0000000020561*pardata*pardata*pardata -
                               0.00002255*pardata*pardata +
                               0.25788*pardata -
                               6.481;
                if (real_pardata < 0)
                {
                  real_pardata = 0;
                }
    
                pardata_hi = real_pardata/65535;
                pardata_low = real_pardata%65535;
            }
            else
            {
                real_pardata = 0.0000049204*pardata*pardata*pardata -
                               0.17114*pardata*pardata +
                               1978.7*pardata -
                               7596900;
                if (real_pardata < 0)
                {
                    real_pardata = 0;
                }
                pardata_hi = real_pardata/65535;
                pardata_low = real_pardata%65535;
            }
        }
        else
        {
            pardata_hi = 0;
            pardata_low = 0;
        }
    }
    

1 个答案:

答案 0 :(得分:1)

正如我写的那样,我已经解决了你遇到的同样问题,尽管有类似的硬件设置。我使用了裸avr atxmega128a3u(所以没有arduino板)和Xbee S1以波特率115200进行通信。经过几天试图解决这个问题后,我得出结论,如果你的avr没有以精确时钟运行(外部xtal)并且你会稍微使用&#34;更快&#34;波特率(&gt; = 115200)Xbee的串行硬件可能无法恢复时钟信号,从而导致传输错误。 (也许Xbee的比特采样率很慢)。

无论如何,通过确保您的微处理器以稳定的时钟运行(这里应该是安全的,因为arduino有一个外部的xtal)并且使用较慢的波特率(尝试57600,19200或9600)应该可以解决您的问题。希望如此。 :) ...别忘了在XCTU中重新配置Xbee的波特率。

如果你只启动xbee一次也可能会有所帮助。将这些行移到setup()函数中:

 setup(){
    // This is changed
    Serial.begin(9600);
    // This is new
    xbee = XBee();
    xbee.begin(Serial);
    // ...
  }

编辑:您也可能对此网站感兴趣,您可以在其中查看给定时钟频率和波特率的错误百分比(以及如果您使用裸avr设置的直接寄存器值){{3} }