Reputation: 51
I am using a STM32F411RE NUCLEO board to create a Zigbee mesh-network. I purchased a Zigbee Dev. Kit to understand the devices.
At the beginning i used the XCTU software from Digi to configure the devices. After all that worked fine for me, i tried to communicate with my NUCLEO board over UART with the Zigbee device.
To enter the AT command mode i have to send "+++" over the UART.
This is how CUBEMX generated my UART initialisation
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
I Wrote the first function to enter the AT command mode. In main.c i included my Header where my function is stored.
#include <XBEE_AT_CMD.h>
Inside the while loop i call my function like this, passing huart1.
while (1)
{
if( AT_enter_CMDmode(&huart1) == 1 )
{
printf("OK \n");
}
else
{
printf("failed entering CMD mode \n");
}
HAL_Delay(1000);
}
The Function it self looks like this. It simply sends "+++" to the Zigbee. After that i am receiving the answer.
int AT_enter_CMDmode(UART_HandleTypeDef *huart)
{
char receive[3];
HAL_UART_Transmit(huart,(uint8_t*)"+++", 3, 100);
HAL_UART_Receive(huart, (uint8_t*)receive, 3, 100);
if( strcmp(receive,OK) == 0 )
{
return 1;
}
else
{
return 0;
}
}
After i enter the AT command mode by sending "+++" the device is answering with an "OK". But this just works sometimes. I tried to apply some delays because in the Datasheet it says you should implement a guard time before and after entering the command mode. Sometimes i get an answer which is similar to the expectet "OK" but without an Carriage return at the end or two "O" and one "K". When i put a Breakpoint after HAL_UART_Receive(huart, (uint8_t*)receive, 3, 100);
I see different answers from the device.
Answer 1: "\rOK"
Answer 2: "\r"
Answer 3: "O"
Answer 4: "OOK"
the answer i am looking for is "OK\r"
It looks like there is an issue with the UART timing maybe? Did i passed the UART handler in the right way to the function? It feels like i am not reading the UART properly, but not sure.
Upvotes: 0
Views: 633
Reputation: 28238
You are on the right track with your parsing, but your main problem is that you need to do proper framing in order to get consistent answers with "OK\r\n" every single time.
And you need to change your code to handle all possible Final result codes. As your code is now you only expect OK
so if the modem returns ERROR
your code would get out of sync/possibly hang when you expand your code to do something more useful than the test loop you currently have.
Upvotes: 0
Reputation: 11694
To enter command mode, you actually (by default) need 1 second of "quiet time" (no bytes sent), followed by "+++" and then another second of quiet time. So you need to wait at least a second before you'll see the "OK" response.
You should also be coding your handler to read as many bytes as available so you don't end up with buffered data.
I would highly recommend designing your code around API mode instead of transparent mode. API mode sends frames of data that include AT commands (so you don't need to enter command mode) and allows sending data to multiple nodes on a network (transparent mode uses registers to set a single destination).
Digi provides an Open Source host library in C (among other languages) that you should be able to integrate into your hardware. You can test and prototype in Windows or Linux/macOS.
Upvotes: 0