簡體   English   中英

XBee S2無線傳感器網絡

[英]XBee S2 Wireless Sensor Network

我正在開發一個無線傳感器網絡,其中我有一個協調器路由器(API模式2)連接到Raspberry Pi 2,5或更多路由器的API模式2。 每個路由器都連接到Arduino Uno。 Unos還有不同的傳感器(溫度,濕度等)。 我必須將數據從傳感器發送到協調器並進行處理。 我使用一個路由器和協調器(只有兩個XBee S2模塊)成功傳輸了數據。 在Arduini上我使用的是Andrew的庫https://github.com/andrewrapp/xbee-arduino ,在Pi上我使用的是Python-xbee庫https://github.com/nioinnovation/python-xbee 對於單個路由器和協調器,我的代碼是:Arduino Code(Router):

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

Raspberry Pi Code(協調員):

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代碼中,最后有一部分代碼檢查狀態響應(我沒有編寫代碼,在互聯網上找到它)。 當我進行設置時,連接到引腳12的errorLED閃爍一次並查看代碼,這意味着“本地XBee未提供及時的TX狀態響應”。 我的問題是,我是否必須自己從python中的協調器發送響應,還是自動生成? 如果我必須自己做,我該怎么做? 因為現在沒有回應。 我的設置正常,因為我在我的Pi上獲得了正確的值。

  2. 當我有多個路由器時,如何在代碼中處理它? 我會繼續每隔2秒從arduino發送傳感器值並循環通過Pi上的地址,還是通過另一種方式完成它? 我很困惑。

  3. 現在,如果我添加更多路由器,他們將繼續發送帶有傳感器值的幀,協調器將循環讀取它們。 如何設置系統,使協調器向每個路由器發送信號並詢問數據,然后路由器回復數據? 可能嗎?

  1. 當本地XBee確認傳送到遠程XBee時,發送狀態幀自動發生。 這是一個低級別的確認。 我的猜測是代碼的邏輯存在問題。 也許響應在500ms后回復。 唯一的方法是重構代碼以不斷輪詢本地XBee的幀,每兩秒發送一次傳感器狀態幀,並跟蹤自上次成功發送狀態幀進入以來的時間長度。我d建議在這里增加波特率,特別是因為現有的Arduino代碼不經常處理字節(例如,在沒有讀取串口的情況下2秒空閑)。

  2. 看起來Raspberry Pi代碼已經設置為處理來自“連續讀取和打印數據包”循環內的多個設備的數據。 我建議將XBee模塊配置為115200bps並使用新值更新Python代碼,這樣您就不會限制數據速率。

  3. 您當前的設計更易於管理 - 網絡上的路由器將始終報告其傳感器讀數。 我想你甚至可以更新代碼使用00000000-00000000作為目標地址,路由器將始終發送給協調器。 但您可以修改Raspberry Pi代碼以保留路由器MAC地址列表(通過ATND節點發現發現),並根據需要向它們發送請求。 您需要修改Arduino代碼以監視入站幀,並在請求進入時生成出站幀。

我建議在沒有任何代碼更改的情況下為您的設置添加第二個路由器,然后只看看它是如何工作的。 據我所知,Raspberry Pi只會打印具有不同源地址的數據包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM