cancel
Showing results for 
Search instead for 
Did you mean: 

Problem about creating a state machine for be able to use ESP8266 AT COMMAND

G_A.
Associate II

Hello,

I have struggled to use AT COMMANDs for communication between ESP8266 and STM32F4.

I should use ESP8266 as non blocking mode .Because my main project is FIRMWARE OVER THE AIR.

1)STM32 GETs the datas of new code via ESP8266 using 'AT COMMANDS'.

2)STM writes all data on the another sector.

3)Jumps to this sector and new code start to work.

4)Btw, when new code is working ,there is a control if there is new firmware or not. If there is new firmware, it should turn back to bootloader.(I can use Nvic software reset to turn back to bootloader.

The main problem is How I can understand if there is a new firmware in server . I thought that I can add 'a code part which always connects server and asks for new data to server with AT COMMAND' inside also user code . But to be able to make this I should write a state machine which is consisting of some AT+COMMAND and works always in nonblocking mode.)

But I can only use ESP8266 with the attached code below(file hata).

----->UART RX dma

----->UART TX interrupt

I can send all command with TX int in main.c and receive all data with rx dma in again main.c.

I can use this code inside bootloader to first acception of new code. But I can not add this code inside USER CODE to check for new firmware version. Because it can be block user code.

I tried to use USART_IRQHANDLER and HAL_UART_RxCpltCallback with tx rx uart interrupt.

But after sending first at comment and receiving first response, it did'nt work properly.

I feel really confused. 3 weeks has passed with sending and receiveng AT command for communication between STM and ESP. But still can not find how ı can send all AT command step by step(also it should control the response of all command in every step, And I guess, all of this should be in nonblocking mode. )

If you have any idea, please share with me. Thanks in advance.

10 REPLIES 10
TDK
Guru

HAL_UART_Transmit_IT is a non-blocking transfer. You can't just repeatedly call it without checking that the previous transaction is complete. If you want to use it in blocking mode, which seems fine here, use HAL_UART_Transmit instead.

Might be other issues as well, but that's one of them.

If you feel a post has answered your question, please click "Accept as Solution".
G_A.
Associate II

Thanks for your response! Actually I wanna use it in non blocking mode. Because when communication betweeen stm32 and esp8266 is going on, another process shouldnot be effect of them.

1)Is it possible for code below to work inside main.c?

There is no problem for first receive and transmit it but then other command can not be sent.

2)Besides, Yes, HAL_UART_Transmit_IT and HAL_UART_Receive_IT is a non-blocking transfer. But when I use below code inside main.c file, all delay and case structure can effect the the other process inside int main, can not them?

// small part of code in main.c

int ESP_KULLANIMI = 1;

switch (ESP_KULLANIMI) {

case 1:

strcpy(transmitted_comment, "AT\r\n");     //softAP+station mode

HAL_UART_Transmit_IT(&huart2, transmitted_comment,strlen(transmitted_comment));

HAL_UART_Receive_IT(&huart2, received_comment,strlen(received_comment));

HAL_Delay(20);

if(strstr(received_comment,str_search)!=0) {ESP_KULLANIMI=2; break;} //if we get OK response after sending first ATcommand, pass case 2

case 2:

strcpy(transmitted_comment2, "AT+CWMODE=3\r\n"); //softAP+station mode

HAL_UART_Transmit_IT(&huart2, transmitted_commen2t, strlen(transmitted_comment2));

HAL_UART_Receive_IT(&huart2, received_comment, strlen(received_comment));

HAL_Delay(20);

}

TDK
Guru

Using non-blocking mode and then using HAL_Delay to wait until it finishes is just using blocking mode with extra steps.

If you want to use interrupt mode, you'll need to program logic accordingly. One thing you should be doing is looking at the return value of HAL_UART_* to make sure it's HAL_OK and not an error code. You'll need to probe the peripheral to see if it's busy or not, and adjust your logic accordingly.

If you feel a post has answered your question, please click "Accept as Solution".
G_A.
Associate II

How can I do that ? I mean Should I use RXNE flag or another thing to understand all data has come or not? Because the response of command has not a spesific lenght generally.

If I delete delays from code. transmittted_comment is always sent before receive_commend can not be completed

int ESP_KULLANIMI = 1;

switch (ESP_KULLANIMI) {

case 1:

strcpy(transmitted_comment, "AT\r\n");     //softAP+station mode

HAL_UART_Transmit_IT(&huart2, transmitted_comment,strlen(transmitted_comment));

HAL_UART_Receive_IT(&huart2, received_comment,strlen(received_comment));

if(strstr(received_comment,str_search)!=0) {ESP_KULLANIMI=2; break;} //if we get OK response after sending first ATcommand, pass case 2

case 2:

strcpy(transmitted_comment2, "AT+CWMODE=3\r\n"); //softAP+station mode

HAL_UART_Transmit_IT(&huart2, transmitted_commen2t, strlen(transmitted_comment2));

HAL_UART_Receive_IT(&huart2, received_comment, strlen(received_comment));

}

TDK
Guru

There are several ways. If you want to stick with HAL, take a look at examples in the CubeMX repository.

https://github.com/STMicroelectronics/STM32CubeF4/blob/b5abca20c9676b04f8d2885a668a9b653ee65705/Projects/STM324xG_EVAL/Examples/UART/UART_Hyperterminal_IT/Src/main.c

If you feel a post has answered your question, please click "Accept as Solution".
G_A.
Associate II

I tried to add some part according to your sharing. But I can not get receive data.

TDK
Guru

> I tried to add some part according to your sharing.

But did you? Are you checking the return value of the HAL_UART_* functions? Did you implement logic to prevent calling HAL_UART_Transmit_IT when it's already busy?

If you feel a post has answered your question, please click "Accept as Solution".
G_A.
Associate II

Do you mean received data when saying HAL_UART_* functions?

I add below part to prevent calling HAL_UART_Transmit_IT .Is it not enough?

strcpy(transmitted_comment, "AT\r\n");     //softAP+station mode

HAL_UART_Receive_IT(&huart2, received_comment, 200);

HAL_UART_Transmit_IT(&huart2, transmitted_comment,strlen(transmitted_comment));

 while (HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY &&  strstr(received_comment,str_search) )

 {

 ESP_KULLANIMI=4;break;

 }

TDK
Guru

> Is it not enough?

There are multiple issues with your logic. One, you have the break statement within the loop. Do you know what break does when it's within a while loop? Two, you're not only checking for HAL_UART_STATE_READY, you're also checking for a strstr return. So you don't know which of those is causing it to exit the loop.

Compare your loop to the loop in the example:

  /*##-6- Wait for the end of the transfer ###################################*/  
  while (HAL_UART_GetState(&UartHandle) != HAL_UART_STATE_READY)
  {
  }

If you feel a post has answered your question, please click "Accept as Solution".