Почему передача XBee иногда не работает?

Я делаю проект с Arduino Uno R3 и XBee Передача S2. Я использую пару датчиков, таких как беспроводной (RF) датчик температуры, два датчика SHT75, 3 -осевой акселерометр и датчик освещенности. И после сбора данных мы используем XBee (S2, режим API) для отправки данных на шлюз. Каждый раунд длится около одной секунды.

  1. Первая проблема заключается в том, что данные составляют около 16 байт, но пакет не отправляется успешно каждый раунд. Иногда это работает, а иногда нет, но полезная нагрузка XBee может быть 60 или 70 байт в таблице... данные с датчика, и передача будет стабильной.

  2. Столкнувшись с проблемой выше, я разделил данные на два пакета (каждый с полезной нагрузкой по восемь байт), и первый пакет очень стабилен, а второй очень нестабилен. Как упоминалось выше, если я помещу во вторые пакеты какое-то число вместо данных зондирования, второй пакет станет стабильным и будет успешно отправляться каждый раунд.

Так что я думаю, что это проблема с кодом, но не знаю, где проблема. Я пытаюсь изменить скорость передачи данных или увеличить время задержки между двумя пакетами. В чем проблема? Ниже приведен мой код:

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

person user3033238    schedule 19.12.2013    source источник


Ответы (1)


Пока я пишу это, я решил ту же проблему, что и вы, но с аналогичной настройкой оборудования. Я использовал голый avr atxmega128a3u (поэтому нет платы arduino) и Xbee S1, обменивающийся данными со скоростью 115200 бод. После нескольких дней попыток выяснить это я пришел к выводу, что если ваш avr не работает с точными часами (внешний xtal) и вы используете немного «более быструю» скорость передачи данных (>= 115200). Последовательное оборудование Xbee, вероятно, имеет проблемы с восстановлением тактового сигнала, что приводит к ошибкам при передаче. (Возможно, у Xbee медленная частота дискретизации).

В любом случае, убедившись, что ваш микропроцессор работает со стабильной тактовой частотой (здесь вы должны быть в безопасности, потому что у arduino есть внешний xtal) и используя более низкую скорость передачи данных (попробуйте 57600, 19200 или 9600), вы должны решить вашу проблему. Я надеюсь, что это так. :) ...И не забудьте перенастроить скорость передачи данных Xbee в XCTU.

А также может помочь, если вы инициализируете xbee только один раз. Переместите эти строки в функцию setup():

 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

person Tomas Stibrany    schedule 11.03.2014
comment
Спасибо! Я попробую это! - person user3033238; 16.10.2014