一般来说,一个ZigBee网络都会有一个协调器(这里协调器是一个集中式网络,这里不讨论分布式网络,分布式网络可以有路由器生成),这个协调器的作用就是管理整个网络的设备信息等。在很多的项目当中都把协调器当做一个中心节点去去收集、管理整个网路的信息,在协调器中,形成网络后与路由没有什么大的区别,只是网路地址为0X0000以此来识别协调器与路由器。协调器网络会嵌入到网关当中,并和网关一起管理数据信息,有必要时还要上传相关的信息到后台服务器中。对于协调器设备来说,掌握这些就算是入门了,其他的话很多都是数据处理。
1、创建一个网络(集中式网路)
1.1、输入命令创建一个网络
1.1.1、输入命令创建指定的网络
HA:Network form channel power panid
例如创建一个网络为,12信道,0x01234为panid 发射功率为8dbm
Network form 12 8 0x1234
Zigbee 3.0:
plugin network-creator form (args)
plugin network-creator form 1 4 10 13
上述命令即时,创建一个集中式网络,该网络的信道为13,panid为0x001, 发射功率为10dbm。
注意,创建一个网络后默认网络处于关闭状态,如果需要让别的节点加入该网络,则必须打开网络允许加入,其中打开网络允许可以直接输入命令实现,也可以在你想要实现的地方调用相关的函数实现,如果想对网络的路由设备打开允许加入网络功能,则可以给路由发送相应的信息,让路由收到后调用打开网络允许加入函数即可,开放时间可以调节0s-255s。
HA:network pjoin 0xff
3.0:network-creator-securitplugin y open-network 0xff
/** @brief Tells the stack to allow other nodes to join the network
* with this node as their parent. Joining is initially disabled by default.
* This function may only be called after the node is part of a network
* and the stack is up.
*
* @param duration A value of 0x00 disables joining. A value of 0xFF
* enables joining. Any other value enables joining for that number of
* seconds.
*/
EmberStatus emberPermitJoining(int8u duration);
1.1.2、输入命令随机创建一个网络
HA:network find unused
3.0:plugin network-creator start 1(1为集中式网络,0为分布式网络)
1.2、调用相关函数创建一个网络
1.2.1、调用函数创建指定的网络
/** @brief Forms a new network by becoming the coordinator.
*
* @note If using security, the application must call
* ::emberSetInitialSecurityState() prior to joining the network. This also
* applies when a device leaves a network and wants to form another one.
* @param parameters Specification of the new network.
*
* @return An ::EmberStatus value that indicates either the successful formation
* of the new network, or the reason that the network formation failed.
*/
Parameters.panid=0x1234;
Parameters.channels=12;
networkParams.radioTxPower = 8;
networkFormMethod = SINK_FORM_NEW_NETWORK;
EmberStatus emberFormNetwork(EmberNetworkParameters *parameters);
1.2.2、调用函数随机创建一个网络
// Finding unused PAN ids.
networkFormMethod = SINK_USE_SCAN_UTILS;
EmberStatus emberScanForUnusedPanId(int32u channelMask, int8u duration)
{
if (setup(FORM_AND_JOIN_ENERGY_SCAN)) {
MEMSET(channelEnergies, 0xFF, EMBER_NUM_802_15_4_CHANNELS);
startScan(EMBER_ENERGY_SCAN, channelMask, duration);
}
return EMBER_SUCCESS;
}
特别提醒:
#define SINK_FORM_NEW_NETWORK 1 //创建一个新的网络
#define SINK_USE_NETWORK_INIT 2 //使用上一次的网络
#define SINK_USE_SCAN_UTILS 3 //创建一个随机的网路
int8u networkFormMethod = SINK_FORM_NEW_NETWORK;
如果之前节点是建立过网络了,当networkFormMethod =SINK_USE_NETWORK_INIT 时,调用emberNetworkInit()时返回时成功的。
小结,创建指定网络和创建随机网络有什么作用,其实还是非常有必要的,特别是在大型网络的环境下布局,这显得非常有必要。在更改建网模式时需要复位一下。
2、调用函数查看自己的网络信息
2.1、查看PANID
EmberStatus emberGetNetworkParameters(EmberNetworkParameters *parameters);
parameters.panId;
2.2、查看64位EUI地址
emberGetEui64();
3、路由更新
广播或者组播出去,子节点会有相应从而达到更新路由效果。
4、读取路由路径
1)通过设备ID获取网络ID,并且获取地址表的索引号。
2)通过这个索引号获取EUI地址。
void emberGetAddressTableRemoteEui64(int8u addressTableIndex,
EmberEUI64 eui64);
3)通过EUI地址查看是否为自己的子节点,如果不是就直接结束,如果是,则继续。
EmberStatus emberGetChildData(int8u index,
EmberEUI64 childEui64Return,
EmberNodeType *childTypeReturn);
4)通过网络地址寻找源路由索引
// Return the index of the entry with the specified destination.
int8u sourceRouteFindIndex(EmberNodeId id)
{
int8u i;
for (i = 0; i < entryCount; i++) {
if (sourceRouteTable[i].destination == id) {
return i;
}
}
return NULL_INDEX;
}
5)以此读取目标的源路由表信息即可。
6)完成以上步骤实现的效果就是,通过你想要查询的设备ID可以找到它路径是怎么走的,这个是非常直接重要的实现,有很好的用户体验效果。
5、保存自己的网络信息,重新上电信息不变
1)定义一个结构体
typedef struct {
int8u mode;
int8u Channel;
int16u panid;
} NodeAttributeStructure;
NodeAttributeStructure netParameter;
2)填写结构体的内容
netParameter.Channel=Channel;
netParameter.panid=Panid;
#define CREATOR_STACK_NODE_ATTRIBUTE 0xe500
DEFINE_BASIC_TOKEN(STACK_NODE_ATTRIBUTE,
NodeAttributeStructure,
{0,11,0x0123})
EmberStatus emberGetNetworkParameters(EmberNetworkParameters *parameters);
SimEEWrite(CREATOR_STACK_NODE_ATTRIBUTE,0x7F,&netParameter);
void SimEERead( int16u creator,int8u index,void * data)
{
int8u size;
int16u address;
size = getTokenSize(creator);
address = getTokenAddress(creator);
if (size == 0 || address == 0xFFFF) {
emberSerialPrintf(APP_SERIAL, "token1 not found\r\n");
return;
}
halInternalGetTokenData(data, address, index, size);
}