Skip to main content
soumaya BEN MANSOUR
Associate II
May 5, 2017
Solved

Problem using UART

  • May 5, 2017
  • 9 replies
  • 2627 views
Posted on May 05, 2017 at 16:11

Hi community,

I'm using stm32f769i-disco to make a serial communication with a Vacuum Transducer (925 MicroPirani).The 925 transducer can provide pressure mesurement output as RS232 digital value.

Pressure request :

Query: @253PR1?;FF

Query reply: 

@253ACK9.00E+2;FF

The discovery card transmit the request bufftr[30] = @253PR1?;FF via the HAL_UART_Transmit(&UartHandle, bufftr, 30, 100)

and the 925 transducer send the pressure value that is to say that the discovery card receive the reply for her request via HAL_UART_Receive(&UartHandle, buffrec, 30, 100); buffrec[30]=@253ACK9.00E+2;FF 

Then I use double pression to get just the bit 7,12,13 of the buffrec and finally I display this value in the LCD.

Here is my code:

int main(void)

{

  MPU_Config();

CPU_CACHE_Enable();

 HAL_Init();

SystemClock_Config();

/* Enalbe clock for USART6 and GPIOC */

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_USART6_CLK_ENABLE();

__HAL_UART_ENABLE(&UartHandle);

/* Initialize GPIOC */

MX_GPIOC_Init();

/* Initialize USART6 */

MX_USART6_UART_Init();

/*♯♯-2- Configure the LCD peripheral ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

LCD_Config();

uint8_t bufftr[30] = '@253PR1?;FF';

uint8_t buffrec[30];

double pression;

char pressbuf [20];

/* Infinite loop */

while (1)

{

/*Transmitting and receiving data */

HAL_UART_Transmit(&UartHandle, bufftr, 30, 100);

HAL_UART_Receive(&UartHandle, buffrec, 30, 100);

HAL_Delay(1000);

if (buffrec[12]==43)

{

pression = (buffrec[7]-48)*pow(10,(buffrec[13]-48));// buffrec7 en ascii c'est 57 - 48 = 9

}

if (buffrec[12]==45)

{

pression = (buffrec[7]-48)*pow(10,-(buffrec[13]-48));

}

/* Display the Pression Value on the LCD */

snprintf(pressbuf, 17, 'Vacuum : %fmBar',pression);

BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize()/2 + 45, (uint8_t *)pressbuf, CENTER_MODE);

BSP_LCD_ClearStringLine(30);

}

}

Finally I don't get my presion value, I only get Vacuum : 0.00000 mBar.

I tried to understand what is wrong with my code I use breakpoint but when I click in step over my code doesn't respect the steps , it is supposed to transmit the request then receive the reply then get the pression then display it on the lcd. 

Can anyone help me to know what I'm missing?

thanks in advance

#uart #uart-rx #uart-tx #stm32 #debug-mode
This topic has been closed for replies.
Best answer by soumaya BEN MANSOUR
Posted on May 23, 2017 at 14:04

Hi Elkin,

Finally I find the solution and now Ican transmit and receive data from the pc via the hyperterminal.

Thank you very much for your help.

Here is the code:

int main(void)

{

/* Enable GPIO TX/RX clock */

__HAL_RCC_GPIOC_CLK_ENABLE();

__USART6_CLK_ENABLE();

__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);

/* Initialize GPIOC */

MX_GPIOC_Init();

/* Initialize USART6 */

MX_USART6_UART_Init();

/* Buffer used for reception */

uint8_t aRxBuffer[RXBUFFERSIZE] ;

uint8_t bufftr[] = '@253PR1?;FF\n\r';

while (1)

{

HAL_UART_Transmit(&UartHandle, bufftr, (sizeof(bufftr)-1), 100);

HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE);

}

}

void MX_GPIOC_Init(void)

{

GPIO_InitStruct.Pin = USARTx_TX_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

GPIO_InitStruct.Alternate = USARTx_TX_AF;

HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

/* UART RX GPIO pin configuration */

GPIO_InitStruct.Pin = USARTx_RX_PIN;

GPIO_InitStruct.Alternate = USARTx_RX_AF;

HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

/* Configure USARTx Tx as alternate function */

HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);

/* Configure USARTx Rx as alternate function */

HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);

}

void MX_USART6_UART_Init(void)

{

UartHandle.Instance = USARTx;

UartHandle.Init.BaudRate = 115200 ;

UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

UartHandle.Init.StopBits = UART_STOPBITS_1;

UartHandle.Init.Parity = UART_PARITY_NONE;

UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;

UartHandle.Init.Mode = UART_MODE_TX_RX;

if(HAL_UART_DeInit(&UartHandle) != HAL_OK)

{

Error_Handler();

}

if(HAL_UART_Init(&UartHandle) != HAL_OK)

{

Error_Handler();

}

}

9 replies

Elkin Granados
Associate II
May 5, 2017
Posted on May 05, 2017 at 19:52

Hi soumaya BEN MANSOUR,

Some times when I'm working with devices with RS232 interface the first thing that I do is to test it with an USB-RS232 DB9 serial adapter and a terminal program (I'm using Hercules), in the terminal you can check if the sensor is working right sending the query and waiting that the sensor query reply appear in the terminal (just for be sure!).

I check transducer datasheet, by default comes with a serial baudrate of 9600, are you setting the right baudrate of the uart port in you discovery board?

In the code, when you declare an char array, for me, the best way to do it is:

uint8_t bufftr[] = '@253PR1?;FF';

Keep the 

[] in blank, so the array will have a size of the number of characters plus one (the last position of the array when you declare it on this way is a null or 0x00). Declaring the buffer on this way you assure that won't send useless characters to the transducer, and the best way to me for using the transmit function is the following:

HAL_UART_Transmit(&UartHandle, bufftr, (sizeof(bufftr)-1), 100);

sizeof returns array size then subtracts 1 to avoid send the null char.

If in the argument of the buffer size you put 30, you will send the characters and the data that is stored in the followings array positions, may be the transducer is affected for this.

To receive the data, if the query reply have always the same size, is better to declare the array with the fixed size, I see that have 17 characters, so I suggest to declare:

uint8_t buffrec[17];

and call the receive function:

HAL_UART_Receive(&UartHandle, buffrec, sizeof(buffrec), 100);

Another thing that you could use is to declare a Hal Status variable, I usually call it error:

HAL_StatusTypeDef error;

And equal this variable to the received and maybe also to the transmit function, is the functions returs HAL_OK means that the data have been send or received well, doing that maybe allows to you also make a better debug (sometimes have worked to me), and example code could be:

error = HAL_UART_Receive(&UartHandle, buffrec,

sizeof(

buffrec)

, 100);

if(error == HAL_OK){

   //write LCD

}

else{

   //i.e. toogle a led to indicate that the data wasn't received

}

When you debug, put the breakpoint in the if line, so you can check the function return status.

To finish, I have never used the snprintf function, instead I use the sprintf and have worked well to me. Hope to be useful, have a nice day!

soumaya BEN MANSOUR
Associate II
May 9, 2017
Posted on May 09, 2017 at 18:00

Hi Elkin Grandos,

Thank you very much for your response.

I tested the sensor with an hyperterminal, I send my request

@253PR1?;FF and I receive correctly the reply so the sensor is woring right.

I make some changes in my code, here is the new code :

HAL_StatusTypeDef error_transmission;

HAL_StatusTypeDef error_reception;

uint8_t bufftr[] = '@253PR1?;FF';

uint8_t buffrec[17];

double pression;

char pressbuf [20];

/* Infinite loop */

while (1)

error_transmission = HAL_UART_Transmit(&UartHandle, bufftr, (sizeof(bufftr)-1), 100);

if(error_transmission == HAL_OK){

error_reception = HAL_UART_Receive(&UartHandle, buffrec, sizeof(buffrec), 100);

}

else{

//i.e. toogle a led to indicate that the data wasn't transmitted

BSP_LED_Toggle(LED1);

}

if(error_reception == HAL_OK){

if (buffrec[12]=='+')

{

pression = (buffrec[7]-48)*pow(10,(buffrec[13]-48));// buffrec7 en ascii c'est 57 - 48 = 9

}

else if (buffrec[12]=='-')

{

pression = (buffrec[7]-48)*pow(10,-(buffrec[13]-48));

}

 /* Display the Pression Value on the LCD */

snprintf(pressbuf, 17, 'Vacuum : %fmBar',pression);

BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize()/2 + 45, (uint8_t *)pressbuf, CENTER_MODE);

BSP_LCD_ClearStringLine(30);

}

else{

//i.e. toogle a led to indicate that the data wasn't received

BSP_LED_Toggle(LED2);

}

}

Finally the Led 2 toggle so I have a problem in the reception of the pression from the 

Vacuum Transducer (925 MicroPirani); 

Can you help me to know what I'm missing exactly?

Can you explain me why my function 

HAL_UART_Receive(&UartHandle, buffrec, sizeof(buffrec), 100) doesn't work correctly?

Thanks in advance

Elkin Granados
Associate II
May 10, 2017
Posted on May 10, 2017 at 16:19

Hi soumaya BEN MANSOUR,

Hi have just check the code and I didn't see anything wrong except for the missing { in while(1) line, just a couple of questions, what IDE are you using?, are you using CubeMX to generate the peripheral inicialization? Could you post your peripheral 

inicialization code?

, again just for be sure, remember that the uart must be configurated to 9600 bps, no parity and one stop bit. Another thing, how do you have the hardware interface between the nucleo board and the sensor? could you post an image of the scheme. Hope to keep helping you, have a nice day!
raptorhal2
Lead
May 10, 2017
Posted on May 11, 2017 at 01:41

The sensor's RS232 output is compatible with your PC RS232 port, but not compatible with the mcu's UART peripheral which has TTL logic levels. You need to use a converter chip such as a Maxim 232, or an RS232 to TTL UART adapter cable.

Cheers, Hal