一般来说,一个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) 
<uint8_t> Whether or not to form a centralized networ ...
<uint16_t> PanID of the network to be formed
<int8_t> Tx power of the network to be formed
<uint8_t> channel of the network to be formed
plugin network-creator form 1 4 10 13

   上述命令即时,创建一个集中式网络,该网络的信道为13,panid为0x001, 发射功率为10dbm。

       注意,创建一个网络后默认网络处于关闭状态,如果需要让别的节点加入该网络,则必须打开网络允许加入,其中打开网络允许可以直接输入命令实现,也可以在你想要实现的地方调用相关的函数实现,如果想对网络的路由设备打开允许加入网络功能,则可以给路由发送相应的信息,让路由收到后调用打开网络允许加入函数即可,开放时间可以调节0s-255s。

  1. 输入命令允许加入网络及时间

     HA:network pjoin 0xff

     3.0:network-creator-securitplugin y open-network 0xff

  1. 调用函数允许加入网络及时间     
/** @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;

  1. 把这些信息写到模拟的EEPROM里面
#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);
 
}