I have been working on this code for some time now. The Scan_Network macro takes a parameter that dictates the way it functions. If a 0 is passed in then the macro attempts to save the Node Names as stored in the "NI" field on the Zigbee and if a 1 is passed in then the 64 bit unique addresses of the online nodes are stored in two 32 bit chunks. The way the Node Discovery is performed is by the issuance of an AT command in the following form: "ATND<CR>". The Zigbee module then responds to this command and returns the details of all nodes that it currently sees in the following form:
"MY" (16 bit network address) <CR>
"SH" (32 bit Serial High address) <CR>
"SL" (32 bit Serial Low Address) <CR>
Signal Strength of the above node on the last received transmission <CR>
"NI" (8 byte node identifier of above node) <CR>
<CR>
<CR>
If more than 1 node is detected then each block (as shown above) is separated by a <CR> and the end of transmission of data by the Zigbee is distinguished by 2 consecutive <CR>s. The Scan_Network macro works OK if you choose to store the addresses so long as nothing else is going on on your network as any transmissions during this period would have been lost as there were unnecessary Get_AT_Reponse() calls at the end of this macro which effectively clears the UART of received data and the zigbee module would have sent an ACK to the sender as confirmation of message delivery.
I have shown the code snippet as it appears in the current FC5_PIC_Zigbee.c below:
Code: Select all
//mode = 0 - Store Names
//mode = 1 - Store Addresses
MX_UINT8 num_devices = 0;
MX_UINT8 i, j;
MX_UINT8 length;
for(i=0;i<64;i++) //Initialise Buffer
{
%a_ID_AddH[i] = 0; //Store High Bytes of Address
%a_ID_name[i] = 0; //Store Low Bytes of address
}
Enter_Command_Mode(); //Initiate Command Mode
Send_AT_Command("ATND",4); //Performs node discovery
Wdt_Delay_Ms(200);
for(i=0;i<MX_ZIG_MAX_DEV;i++)
{
length = Get_AT_Response(0); //Collect 16 bit network address
if (length <= 2 || length == 255) //If length <= 2 then device listing has finished, 255 then no data being received.
break;
if (mode)
{
length = Get_AT_Response(1); //Collect 64 bit device address
for (j=0;j<8;j++)
{
%a_ID_AddH[j+(num_devices*8)] = %a_In_Buff[j]; //Store High Bytes of Address
}
length = Get_AT_Response(1); //Collect 64 bit device address
for (j=0;j<8;j++)
{
%a_ID_name[j+(num_devices*8)] = %a_In_Buff[j]; //Store Low Bytes of address
}
Get_AT_Response(0); //Collect device identifier name
}
else
{
Get_AT_Response(0); //Collect 1st half of 64 bit device address
Get_AT_Response(0); //Collect 2nd half of 64 bit device address
length = Get_AT_Response(1); //Collect device identifier name
for (j=0;j<8;j++)
{
if (j > length - 1)
%a_ID_name[j+(num_devices*8)] = 0; //Terminate the end of the name string
else
%a_ID_name[j+(num_devices*8)] = %a_In_Buff[j];//Collect the name string
}
}
Get_AT_Response(0); //Collect FFFF, FFFE
Get_AT_Response(0); //Collect 00, 01
Get_AT_Response(0); //Collect 00, 00
Get_AT_Response(0); //Collect C105
Get_AT_Response(0); //Collect 101E
//Get_AT_Response(0); //Collect spacer carrage return
%a_UART_Receive(200); //Receive Character
num_devices = num_devices + 1; //Increment number of devices
}
Exit_Command_Mode();
return (num_devices);
The above if changed to the following makes the code work as I imagine it was originally intended to:
Code: Select all
//mode = 0 - Store Names
//mode = 1 - Store Addresses
MX_UINT8 num_devices = 0;
MX_UINT8 i, j;
MX_UINT8 length;
for(i=0;i<64;i++) //Initialise Buffer
{
%a_ID_AddH[i] = 0; //Store High Bytes of Address
%a_ID_name[i] = 0; //Store Low Bytes of address
%a_ID_Address[i] = 0; //short address
}
Enter_Command_Mode(); //Initiate Command Mode
Send_AT_Command("ATND",4); //Performs node discovery
Wdt_Delay_Ms(400);
for(i=0;i<MX_ZIG_MAX_DEV;i++)
{
length = Get_AT_Response(0); //Collect 16 bit network address
if (length <= 2 || length == 255) //If length <= 2 then device listing has finished, 255 then no data being received.
break;
if (mode)
{
length = Get_AT_Response(1); //Collect 64 bit device address
for (j=0;j<8;j++)
{
%a_ID_AddH[j+(num_devices*8)] = %a_In_Buff[j]; //Store High Bytes of Address
}
length = Get_AT_Response(1); //Collect 64 bit device address
for (j=0;j<8;j++)
{
%a_ID_name[j+(num_devices*8)] = %a_In_Buff[j]; //Store Low Bytes of address
}
Get_AT_Response(0); //Collect signal strength
Get_AT_Response(0); //Collect node name
}
else
{
Get_AT_Response(0); //Collect 1st half of 64 bit device address
Get_AT_Response(0); //Collect 2nd half of 64 bit device address
length = Get_AT_Response(1); //Collect signal strength
length = Get_AT_Response(1); //Collect the name of the node
for (j=0;j<8;j++)
{
if (j > length - 1)
%a_ID_name[j+(num_devices*8)] = 0; //Terminate the end of the name string
else
%a_ID_name[j+(num_devices*8)] = %a_In_Buff[j];//Collect the name string
}
}
Get_AT_Response(0); //Collect the last 0D
num_devices = num_devices + 1; //Increment number of devices
}
Exit_Command_Mode();
return (num_devices);
many thanks
Sefi