#include <XBee.h> #include "XnorBeeSlave.h" byte shared_memory[4]; XBee xbee = XBee(); XnorBeeSlave xbs(&xbee, shared_memory); // pass xbee obj by reference to xbs + shared_memory array.
Example code above creates a shared_memory byte array that is 4 bytes long.
Secondary an XBee object is instantiated, then the XnorBeeSlave object.
At initialization of the XnorBeeSlave object we pass the XBee object by reference combined with the shared_bus memory byte array.
Based on what serialport that is used, the correct serialEvent configuration has to be set.
In this example serial3 is used for the xbee device on an atmega2560, so serialEvent3() has to be un-commented.
//void serialEvent0(){xbs.SerialEventProc();} //void serialEvent1(){xbs.SerialEventProc();} //void serialEvent2(){xbs.SerialEventProc();} void serialEvent3(){xbs.SerialEventProc();}
In the setup function we have to start the serial communication on the serial port where the XBee is connected to, by using the begin function. In this example Serial3 was used.
Secondary we have to set the serial for the xbee object using xbee.setSerial(Serial3).
Serial3.begin(9600); // start serial port where xbee is connected to xbee.setSerial(Serial3); // pass this serial port to xbee object.
<WRAP center round important 90%> Keep in mind that the whole shared byte array is read/write accessible for the entire XBee network! </WRAP>
Download full slaves library code + example: xnorbeeslave.rar
Dependencies: install 'xbee-arduino library' by Andrew Rapp (tested with v0.6.0) using the library manager.
None
<WRAP center round info 60%>
28/05/2020:
Line 71 in library file payload[i] –> change to: –> payload[i-startindex]
Corrected version:
// Set payload data: byte payload[byteCount]; for(int i=startIndex; i < (startIndex+byteCount); i++) payload[i-startIndex] = _bus_memory[i];
</WRAP>
The master has to send data following the correct protocol to read/write data from a slave XnorBee device.
The data to send exists out of minimum 2 bytes, for a read request. More than 2 bytes defaults to a write request.
To read data from the slave device the master has to send 2 bytes. Those 2 bytes configure the start index and amount of data we request from the slaves 'shared' byte array.
To write data to the slave device, the master just has to send more than 2 bytes. The first 2 bytes keep the same logic as in read mode, following bytes are written to the 'shared' byte array.
Reading and/or writing data to the slave device can be done from the XCTU software inside the console mode.
Create a frame using the 'Frame Generator' tool inside XCTU.
<WRAP center round info 50%>
In the print-screen we notice a write request using '03 01 00'.
This writes the value '00' of length '01' to index '03'.
</WRAP>
<WRAP center round important 50%>
Keep in mind that XCTU has to be set in “HEX” mode/tab to work!
And always use double digits !!!
</WRAP>
XCTU software download:
https://www.digi.com/products/embedded-systems/digi-xbee/digi-xbee-tools/xctu#productsupport-utilities
Using the custom created python XnorBee and XnorBeeMaster class makes reading or writing data to slave devices quite easy. Before you can use those classes, you need to import the correct modules:
from XnorBee.XnorBee import XnorBee from XnorBee.XnorBeeMaster import XnorBeeMaster
The XnorBee class contains the lower level functions using the Digi.XBee API.
This class can be used to:
xbe = XnorBee("COM13", 9600) # Add the local devices communication port and bautrate. rZBid = xbe.SetRemoteZigbeeDevice("0013A200409A0EA8") # Set remote device MAC. Returns easy numeric ID for further usage.
Note that multiple remote devices can be set to the XnorBee class. Each remote device gets an unique ID as return value.
state = xbe.SendData(rZBid, "blub" , pMode="DEC") # Write strings to an remote device on the network. state = xbe.SendData(rZBid, ["\x03", "\x01"] , pMode="HEX") # Write bytes in hexadecimal format to remote device on the network. print(state) # Prints complex to use status output containing execution information. time.sleep(1) # Timing before receiving data has to be manually estimated and added. xbee_message = xbe.ReceiveData() # Receives data in an complex to use dict layout. print(xbee_message) # Prints barely readable dict layout.
Note that the returned values inside 'state' and 'xbee_message' contain rather difficult to read dictionary and object data. For easy data access combine this class with the XnorBeeMaster class.
If you need to read or set an IOLine in/out-put, this can be done as follow.
from XnorBee.XnorBee import XnorBee from digi.xbee.devices import IOMode from digi.xbee.io import IOLine # Get the basic functionality using the XnorBee class: xbe = XnorBee("COM13", 9600) rZBid = xbe.SetRemoteZigbeeDevice("0013A20041AE5856") # PIN / IOLine interactions: rZBDEV = xbe.GetRemoteZigbeeDevice(rZBid) # Get the remote device object from the xbe object using the remote devices ID. rZBDEV.set_io_configuration(IOLine.DIO10_PWM0, IOMode.DIGITAL_IN) # Configure the pin as an input. io_state = rZBDEV.get_dio_value(IOLine.DIO10_PWM0) # Read the pin state HIGH or LOW print(io_state)
The XnorBeeMaster class contains the higher level functions for the XnorBee class.
This class can be used to:
xbm = XnorBeeMaster(xbe) # Init XnorBeeMaster, pass XnorBee object to it. Required as the Master class uses functions from the XnorBee class. # Read requests: answ = xbm.ReadRequest(rZBid, 3,1) # Read 1 byte from the array at position 3. answ = xbm.ReadRequest(rZBid, 9,4) # Read 4 bytes from the array, starting from position 9. Read 9, 10, 11 and 12. answ = xbm.ReadRequest(rZBid, 0,16) # Read the whole memory array of 16 bytes long. print(answ) # Prints the whole easy to use dictionary. print(answ["data"]) # Prints the data parameter from this dictionary. Shows all requested data in an easy to use byte / int array. # Write requests: state = xbm.WriteRequest(rZBid, 3, [0]) # Write value 0 to index 3 in the slaves memory. state = xbm.WriteRequest(rZBid, 9, [40,50,60,70,80]) # Write the byte array to the slaves memory, starting at position 9. # Slaves memory at index 9 will contain 40 after execution. print(state) # Prints True or False based on how execution went.
Download full Masters library code + example: xnorbeemaster.rar
dependencies: https://xbplib.readthedocs.io/en/latest/getting_started_with_xbee_python_library.html
<WRAP center round important 60%> Due to delayed response from remote nodes data can be intercepted at later request to another node. This causes data to be shuffled inside the gateway/receivers array. Data should be checked for integrity using the sending-nodes mac address to prevent issues like this. ReceiveData function should be updated to hold an timeout delay in the future! </WRAP>