首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XBee S2无线传感器网络

XBee S2无线传感器网络
EN

Stack Overflow用户
提问于 2016-05-03 13:52:16
回答 1查看 544关注 0票数 1

我正在开发一个无线传感器网络,其中我有一个协调器路由器(API模式2)连接到Raspberry Pi 2,或者API模式2中的更多路由器。每个路由器都连接到一个Arduino Uno。Unos还安装了不同的传感器(温度、湿度等)。我必须将数据从传感器发送到协调程序并进行处理。我已经使用一个路由器和协调器成功地传输了数据(只有两个XBee S2模块)。在Arduini上,我使用安德鲁的库https://github.com/andrewrapp/xbee-arduino,在Pi上,我使用Python库https://github.com/nioinnovation/python-xbee。对于单个路由器和协调器,我的代码是: Arduino代码(路由器):

代码语言:javascript
复制
#include <XBee.h>
#include <math.h> 
// create the XBee object
XBee xbee = XBee();

int sensor = A5;
uint8_t payload[8] = {0, 0, 0, 0, 0, 0, 0, 0};
// union to convert float to byte string
union u_tag {
    uint8_t b[4];
    float fval;
} u;


// SH + SL Address of receiving XBee
XBeeAddress64 addr64 = XBeeAddress64(0x0013a200, 0x40DC7C90);
ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));
ZBTxStatusResponse txStatus = ZBTxStatusResponse();

int statusLed = 13;
int errorLed = 12;

void flashLed(int pin, int times, int wait) {

  for (int i = 0; i < times; i++) {
    digitalWrite(pin, HIGH);
    delay(wait);
    digitalWrite(pin, LOW);

    if (i + 1 < times) {
      delay(wait);
    }
  }
}

double Thermistor(int RawADC)
{
  double Temp;
  Temp = log(10000.0 * ((1024.0 / RawADC - 1)));
  Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp )) * Temp );
  Temp = Temp - 273.15;            // Convert Kelvin to Celcius
  //Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
  return Temp;
}

void setup() {
  pinMode(statusLed, OUTPUT);
  pinMode(errorLed, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  float rawADC = analogRead(sensor);
  float t = Thermistor (rawADC);

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (!isnan(t)) {

    // convert temperature into a byte array and copy it into the payload array
    u.fval = t;
    for (int i=0;i<4;i++){
      payload[i]=u.b[i];
    }
    u.fval = 100.33;
    for (int i=0;i<4;i++){
      payload[i+4]=u.b[i];
    }

    xbee.send(zbTx);
    flashLed(statusLed, 1, 100);        // flash TX indicator


    // after sending a tx request, we expect a status response, wait up to half second for the status response
    if (xbee.readPacket(500)) {
      // got a response!
      // should be a znet tx status             
      if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
        xbee.getResponse().getZBTxStatusResponse(txStatus);

        // get the delivery status, the fifth byte
        if (txStatus.getDeliveryStatus() == SUCCESS) {
          // success.  time to celebrate
          flashLed(statusLed, 5, 50); 
        } else {
          // the remote XBee did not receive our packet. is it powered on?
          flashLed(errorLed, 3, 500);
        }
      }
    } else if (xbee.getResponse().isError()) {
      //nss.print("Error reading packet.  Error code: ");  
      //nss.println(xbee.getResponse().getErrorCode());
    } else {
      // local XBee did not provide a timely TX Status Response -- should not happen
      flashLed(errorLed, 1, 50);
    }
  }
  delay(2000);
}

树莓Pi码(协调员):

代码语言:javascript
复制
from xbee import ZigBee
import serial
import struct
import datetime

PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600

def hex(bindata):
    return ''.join('%02x' % ord(byte) for byte in bindata)

# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)

# Create API object
xbee = ZigBee(ser,escaped=True)

# Continuously read and print packets
while True:
    try:
        response = xbee.wait_read_frame()
        sa = hex(response['source_addr_long'])
        rf = hex(response['rf_data'])
        obj = createObject(response)
        obj.createPacket()
        print ("Temperature: %.2f" % obj.packet['temperature'],
        "Humidity: %.2f" % obj.packet['humidity'], 
        "Source Address: 0x%s" % obj.packet['sourceAddressShort'],
        "Timestamp: %s" % obj.packet['timestamp'].isoformat())
    except KeyboardInterrupt:
        break

ser.close()

class createObject:
    def __init__(self, response):
        self.sourceAddrLong = hex(response['source_addr_long'])
        self.rfData = hex(response['rf_data'])
        self.sourceAddrShort = hex(response['source_addr_long'][4:])
        self.options = response.pop('options')
        self.frameType = response['id']
        self.temperature = struct.unpack('f',response['rf_data'][0:4])[0]
        self.humidity = struct.unpack('f',response['rf_data'][4:])[0]
        self.dataLength = len(response['rf_data'])
        self.packet={}
        self.dateNow = datetime.datetime.utcnow()
        self.packetJson=0

    def createPacket(self):
        self.packet.update({
                'timestamp' : self.dateNow,
                'temperature' : self.temperature,
                'humidity' : self.humidity,
                'dataLength' : self.dataLength,
                'sourceAddressLong' : self.sourceAddrLong,
                'sourceAddressShort' : self.sourceAddrShort,
                'options' : self.options,
                'frameType' : self.frameType
                })

我有几个问题我找不到答案。我几乎到处都找过了,但还是有些困惑。

  1. 在Arduino代码中,最后有一部分代码检查状态响应(我没有编写代码,而是在internet上找到的)。当我设置它时,我的errorLED连接到pin 12闪烁一次,查看代码,这意味着“本地XBee没有提供及时的TX状态响应”。我的问题是,我是否必须亲自从python的协调器中发送响应,还是自动生成的?如果我要自己做,我该怎么做?因为现在还没有反应。我的设置工作良好,因为我得到了正确的值,我的Pi。
  2. 当我有多个路由器时,我如何在代码中处理它?我是每隔2秒从arduino发送一次传感器值,然后循环遍历Pi上的地址,还是有另一种通常的方式?我对此很困惑。
  3. 现在,如果我添加更多的路由器,它们将继续发送带有传感器值的帧,协调器在循环中读取它们。如何设置系统,以便协调器向每个路由器发送一个信号并请求数据,然后路由器用数据进行应答?有可能吗?
EN

回答 1

Stack Overflow用户

发布于 2016-05-04 17:02:41

  1. 当本地XBee确认向远程XBee的传递时,传输状态帧将自动发生。这是一种低级的承认。我猜这段代码的逻辑中有一个问题。也许500毫秒后才会有反应。唯一的方法是重构代码,不断轮询本地XBee的帧,每两秒钟发送一次传感器状态帧,并跟踪上次成功传输状态帧出现的时间。我建议在这里也提高波特率,特别是因为现有的Arduino代码没有像它应该的那样频繁地处理字节(例如,在不读取串口的情况下空转2秒)。
  2. 看起来,Raspberry Pi代码已经设置为处理来自“连续读取和打印数据包”循环中的多个设备的数据。我建议将XBee模块配置为115200bps,并使用新值更新Python代码,这样就不会限制数据速率。
  3. 您目前的设计更容易管理--网络上的路由器总是会报告它们的传感器读数。我认为您甚至可以更新代码以使用00000000-00000000作为目标地址,并且路由器将始终发送到协调器。但是您可以修改Raspberry代码,以保留一个路由器MAC地址列表(通过ATND节点发现发现),并根据需要向它们发送请求。您需要修改Arduino代码以监视入站帧,并在请求传入时生成出站帧。

我建议在您的设置中添加第二个路由器,而不需要任何代码更改,然后看看它是如何工作的。据我所知,Raspberry Pi将只打印具有不同源地址的数据包。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37006174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档