2022-11-02 08:52 AM
Hi,
since some days I try to get a communication between a STM32F030R8 Nucleo and an ESP8266 WIFI module working. Communication between Putty and WIFI module works already. I am stucking at receiving the answers from ESP module. I already tryed it with interrupt or DMA and now simply with polling, but I can not read the answers from the module. I looked at the communication with my logic analyzer and saw, that the module seems to receive the AT command correctly and gives a correct response. All with the baudrate of 115200 wich I set for the interface.
But all I receive, also with simple polling, is a "r", nothing else.
Here is my main.c code:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include <ESP8266.h>
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
uint8_t ESP8266_rxBuffer[12] = {0};
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
// MCU Configuration
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_USART1_UART_Init();
// Initialize ESP8266
init_ESP8266();
while (1)
{
}
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USART1 Initialization Function
* @param None
* @retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
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;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* @brief USART2 Initialization Function
* @param None
* @retval None
*/
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, ESP_Reset_Pin|ESP_PowerDown_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : BlueButton_Pin */
GPIO_InitStruct.Pin = BlueButton_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(BlueButton_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : ESP_Reset_Pin ESP_PowerDown_Pin */
GPIO_InitStruct.Pin = ESP_Reset_Pin|ESP_PowerDown_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : GreenLED_Pin */
GPIO_InitStruct.Pin = GreenLED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GreenLED_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
And here is the init function for the ESP8266, currently reduced to only the AT command. I have set an breakpoint after the receive function to check the buffer contents:
/*
* ESP8266.c
*
* Created on: Nov 1, 2022
* Author: jensk
*/
#include "main.h"
#include "string.h"
#include <ESP8266.h>
void init_ESP8266()
{
HAL_Delay(8000);
HAL_UART_Transmit(&huart1, (uint8_t *) "AT\r\n", 4, 100);
HAL_UART_Receive(&huart1, ESP8266_rxBuffer, 10, 5000);
}
UART1 is the ESP module, UART2 the PC.
2022-11-02 10:26 AM
A usual suspect is RX overflow. Check for it and clean.
2022-11-02 11:15 AM
i needed ESP communication also; problem was: never know, length of string sended.
so i use the callbacks, on received char INT is started and i store new char to an array.
when line end coming, i set a signal -> global var to length of string.
then analyze string in main, IF var > 0 .
not so difficult...but need bigger array, because debug messages can be long...
and dont forget to handle error on receive !
start receiver action:
now always receiving...but need no cpu time, when nothing coming !
with error handling ... kick away.
parser:
...
2022-11-02 12:38 PM
Thank you for the quick help. I've implemented the int with RxCpltCallback function again, this time with the overflow check like you did it.
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include <ESP8266.h>
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
uint8_t ESP8266_rxBuffer[200] = {0};
uint8_t ESP8266_rxCNT = 0;
uint8_t rxDone = 0;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
uint8_t outBuf[200] = {0};
uint8_t i;
// MCU Configuration
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_USART1_UART_Init();
HAL_UART_Transmit(&huart2, "\n\n\r", 3, 1000);
HAL_UART_Receive_IT(&huart1, ESP8266_rxBuffer, 1);
// Initialize ESP8266
init_ESP8266();
while (1)
{
if(rxDone) // Check if message was received completely
{
// Copy contents of receive buffer to output buffer without first char because its always the newest received
for(i = 0; i < 200; i++)
{
outBuf[i] = ESP8266_rxBuffer[i + 1];
}
HAL_UART_Transmit(&huart2, outBuf, sizeof(outBuf), 1000);
rxDone = 0;
}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
ESP8266_rxCNT++;
if(ESP8266_rxCNT > 198) // Catch overflow
{
ESP8266_rxCNT = 1;
}
else if(ESP8266_rxBuffer[0] == 0x0D) // CR detected
{
rxDone = 1;
}
ESP8266_rxBuffer[ESP8266_rxCNT] = ESP8266_rxBuffer[0];
HAL_UART_Receive_IT(&huart1, ESP8266_rxBuffer, 1);
}
Now I can see some answers of the ESP module like in console, but the answer for AT command is still random chars
2022-11-02 12:51 PM
I just saw, that the whole output of the screenshot is dropped when the AT command is transmitted. In logic analyzer I can see, that the other outputs like "ready" or "WIFI GOT IP" are already received much earlier. But the output to console is only when AT command is transmitted
2022-11-02 01:02 PM
Made some changes in main:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include <ESP8266.h>
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
uint8_t ESP8266_rxBuffer[1] = {0};
uint8_t recBuf[200];
uint8_t ESP8266_rxCNT = 0;
uint8_t rxDone = 0;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
// MCU Configuration
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_USART1_UART_Init();
HAL_UART_Transmit(&huart2, "\n\n\r", 3, 1000);
HAL_UART_Receive_IT(&huart1, ESP8266_rxBuffer, 1);
// Initialize ESP8266
init_ESP8266();
while (1)
{
if(rxDone) // Check if message was received completely
{
HAL_UART_Transmit(&huart2, recBuf, sizeof(recBuf), 1000);
rxDone = 0;
}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
ESP8266_rxCNT++;
if(ESP8266_rxCNT > 198) // Catch overflow
{
ESP8266_rxCNT = 1;
}
else if(ESP8266_rxBuffer[0] == 0x0A) // LF detected
{
rxDone = 1;
}
recBuf[ESP8266_rxCNT - 1] = ESP8266_rxBuffer[0];
HAL_UART_Receive_IT(&huart1, ESP8266_rxBuffer, 1);
}
Now output looks like
At least OK is comming through now, but still some random symbols after it
2022-11-02 02:00 PM - edited 2023-11-20 09:03 AM
well, i am tired now and cant see , what you doing wrong...
but:
-- because this random **** is after some wrong reception, so have spikes/stray on cable/line
-- need error treatment , maybe like i did : just wait for next
-- or screen connection , to get no spikes on line
2022-11-02 02:05 PM
Finally fixed it. Speeded up the baudrate to PC from 9600 to 230400 to get the transmission faster and now there are no random chars anymore except for the start of ESP module which is normal (boot output with 74880 baudrate). For normal operation I don't need the PC output, so I think it will be much faster than. Thank you for your good hints.