Nextion HMI UART Issue
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-10-11 09:55 AM - edited ‎2024-10-11 09:59 AM
Hi,
I am using an STM32F407 Evaluation Board in my project, along with a Nextion HMI Display that communicates with the MCU over UART.
In this project, I send data every 1 second using a TIM interrupt with UART Polling Mode, and I receive data from the Nextion HMI using UART in interrupt mode (UART IT).
The issue arises when both transmit (TX) and receive (RX) operations happen simultaneously. The reception completes successfully, but the transmitted data from the Nextion HMI behaves incorrectly. However, if I perform only the receive or only the transmit operation, everything works fine.
I suspect that the problem occurs because the transmit and receive operations are colliding or overlapping.
I am attaching screenshots that show how the system should work and the problems I am encountering.
Could you help me identify where I might be making a mistake?
I am also struggling to find a way to transmit data using UART in interrupt mode (UART IT). I could use some help with that part as well.
/* USER CODE BEGIN 0 */
int a=0, b=0,c=0;
uint8_t RX_Data[5];
uint8_t end_Command[3] = {0xFF, 0xFF, 0xFF};
char nextion_Buffer[512];
void nextion_Send_String(char *ID, char *string)
{
int len=0;
len = sprintf(nextion_Buffer, "%s.txt=\"%s\"", ID, string);
HAL_UART_Transmit(&huart3, (uint8_t*)nextion_Buffer, len, 1000);
HAL_UART_Transmit(&huart3, end_Command, 3, 100);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART3)
{
if(RX_Data[1] == 0x31)
{
a=1;
}
else if(RX_Data[1] == 0x32)
{
a=2;
}
else if(RX_Data[1] == 0x33)
{
a=3;
}
else if(RX_Data[1] == 0x34)
{
a=4;
}
else if(RX_Data[1] == 0x30 || 0xFF)
{
a=0;
}
if(RX_Data[2] == 0x03)
{
b=3;
}
else if(RX_Data[2] == 0x04)
{
b=4;
}
else if(RX_Data[2] == 0x05)
{
b=5;
}
else if(RX_Data[2] == 0x06)
{
b=6;
}
if(RX_Data[3] == 0x30)
{
c=30;
}
else if(RX_Data[3] == 0x31)
{
c=31;
}
}
HAL_UART_Receive_IT(&huart3,RX_Data, sizeof(RX_Data));
}
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim8);
HAL_UART_Receive_IT(&huart3,RX_Data, sizeof(RX_Data));
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM8)
{
nextion_Send_String("t01","hello");
}
}
/* USER CODE END 4 */
- Labels:
-
STM32F4 Series
-
UART-USART
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-10-11 10:25 AM - edited ‎2024-10-11 10:27 AM
Function nextion_Send_String is called from HAL_TIM_PeriodElapsedCallback which is called from a timer interrupt handler. With unfortunate choice of interrupt priorities, send_string() can block (delay) UART RX and timer interrupts.
> I could use some help
Here you are. Help with any aspect of your STM32 project. Software, electronics and more.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-10-11 06:54 PM
In the timer interrupt, set a flag and exit. Then in main while loop check flag and then send.
In the Rx interrupt, though there doesn't seem to be much processing, it's better to save the data in another buffer, set a flag. Then in the main while loop check the flag and then do your processing on the other buffer while your RX_Data is still receiving new data.
Also you have no mechanism if the data gets out of sync, to get the received data properly aligned and back in sync with the array. Though not necessary to have a start byte, since you're working with only 5 bytes, but have a start byte and a checksum wrapped around your data. It's easier to figure out if your data is in sync and if it's a valid packet.
If you find my solution useful, please click the Accept as Solution so others see the solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-10-27 06:48 AM
Hi,
I figured out the problem. I was trying to send data to other pages while on a specific page. Basically, what happens is that the Nextion HMI gives an error code if I try to send data when I'm not on the correct page. So, I classified the transmitted data according to the page data received. Here is the code that works fine.
while (1)
{
if(u_Flag==OK){
if (RX_Data[1] == 0x31) {
nextion_Send_String("t11", "hello");
}
else if (RX_Data[1] == 0x32) {
nextion_Send_String("t21", "hello");
}
else if (RX_Data[1] == 0x33) {
nextion_Send_String("t31", "hello");
}
else if (RX_Data[1] == 0x34) {
nextion_Send_String("t41", "hello");
}
else if (RX_Data[1] == 0x30 || RX_Data[1] == 0x80) {
nextion_Send_String("t01", "hello");
}
u_Flag=NOK;
}
if(Flag==OKI){
if (RX_Data[1] == 0x31) {
a = 1;
}
else if (RX_Data[1] == 0x32) {
a = 2;
}
else if (RX_Data[1] == 0x33) {
a = 3;
}
else if (RX_Data[1] == 0x34) {
a = 4;
}
else if (RX_Data[1] == 0x30 || RX_Data[1] == 0x80) {
a = 0;
}
if (RX_Data[2] == 0x03) {
b = 3;
}
else if (RX_Data[2] == 0x04) {
b = 4;
}
else if (RX_Data[2] == 0x05) {
b = 5;
}
else if (RX_Data[2] == 0x06) {
b = 6;
}
if (RX_Data[3] == 0x30) {
c = 30;
}
else if (RX_Data[3] == 0x31) {
c = 31;
}
Flag=NOKI;
}