Estoy trabajando en una red de sensores inalámbricos en la que tengo un enrutador coordinador (modo API 2) conectado a una Raspberry Pi 2, 5 o más enrutadores en el modo API 2 también. Cada enrutador está conectado a un Arduino Uno. Los Unos también tienen diferentes sensores conectados (temperatura, humedad, etc.). Tengo que enviar los datos de los sensores al coordinador y procesarlos. He transferido datos con éxito utilizando un enrutador y un coordinador (solo dos módulos XBee S2). En el Arduini estoy usando la biblioteca de Andrew enlace y en la Pi estoy usando una biblioteca Python-xbee enlace . Para un solo enrutador y coordinador mis códigos son: Código Arduino (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);
}
Código de Raspberry Pi (Coordinador):
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
})
Tengo algunas preguntas a las que no puedo encontrar respuestas. He mirado casi por todas partes pero todavía tengo algunas confusiones.
1) En el código de Arduino, hay una parte del código al final donde se comprueba la respuesta del estado (no escribí el código, lo encontré en Internet). Cuando lo configuré, mi error LED conectado al pin 12 parpadea una vez y al buscar en el código significa que "el XBee local no proporcionó una Respuesta de Estado de TX a tiempo". Mi pregunta es: ¿tengo que enviar una respuesta del coordinador en Python o se genera automáticamente? Si tengo que hacerlo yo mismo, ¿cómo lo haría? Porque en este momento, no hay respuesta. Mi configuración funciona bien ya que estoy obteniendo los valores correctos en mi Pi.
2) Cuando tengo más de un enrutador, ¿cómo lo manejaría en el código? ¿Seguiré enviando valores del sensor cada 2 segundos desde el arduino y recorreré la dirección en Pi o hay alguna otra forma de hacerlo? Estoy muy confundido al respecto.
3) Ahora mismo, si agrego más enrutadores, seguirán enviando marcos con valores de sensores y el coordinador los leerá en un bucle. ¿Cómo puedo configurar el sistema para que el coordinador envíe una señal a cada enrutador y pida los datos y luego el enrutador responda con los datos? ¿Es posible?
Cualquier ayuda sería realmente apreciada. Gracias de antemano :)