2013-12-19 106 views
0

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

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

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

所以我认为这是代码问题,但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

正如我正在写这个我已经解决了你有同样的问题,虽然有类似的硬件设置。我已经使用裸avr atxmega128a3u(所以没有arduino板)和波特率115200通信的Xbee S1。几天后,我得出结论,如果你的AVR没有在精确的时钟(外部xtal)运行,并且使用稍微“更快”的波特率(> = 115200)Xbee的串行硬件可能无法恢复时钟信号,导致传输错误。 (也许Xbee具有较慢的比特采样率)。

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

而且,如果你还initliaze的XBee只once.Move这些线路进入设置(它可能会帮助)功能:

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

编辑:您可能也有兴趣在这个网站上,你可以看到什么是%对于给定的时钟频率和波特率(以及如果您使用裸avr时设置的直接寄存器值)的误差。http://www.wormfood.net/avrbaudcalc.php?postbitrate=9600&postclock=16&hidetables=1

+0

谢谢!我会试试这个! – user3033238

相关问题