Skip to main content
Visitor II
May 10, 2024
Question

Update parameters with UART

  • May 10, 2024
  • 5 replies
  • 2721 views

Hello,

Currently, I command the sensor with "SendScriptToDevice(Linear_Sweep);" function like that. 

 

char const * Linear_Sweep= "e\n"
 "var c\n"
 "var p\n"
 "set_pgstat_mode 3\n"
 "set_max_bandwidth 200\n"
 "set_range ba 500u\n"
 "set_e -500m\n"
 "cell_on\n"
 "wait 1\n"
 "meas_loop_lsv p c -500m 500m 50m 100m\n"
 "pck_start\n"
 "pck_add p\n"
 "pck_add c\n"
 "pck_end\n"
 "endloop\n"
 "cell_off\n"
 "\n";

int main(void)
{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_USART3_UART_Init();
 MX_USART2_UART_Init();

 /* Initialize interrupts */
 MX_NVIC_Init();
 /* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&huart3, RX_Data, 1);
 SendScriptToDevice(Linear_Sweep);

 

But now, I want to updated certain numbers in Linear_Sweep with UART receiving. To implement this idea, I wrote the codes like that but it didn't work. Do you have a suggestion about the problem?

 

 

 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
	 	HAL_StatusTypeDef usart2_status; // Bluetooth control USART port
	 	usart2_status = HAL_UART_Receive(&huart2, Rx_mux, 58, 50); //receive 58 bytes (0-58) of data from MATLAB off laptop, 60 sec timeout
	 	HAL_Delay(500);

	 	if (usart2_status != HAL_TIMEOUT)
	 	{
	 		HAL_Delay(250);
	 		technique = (Rx_mux[17]<<8) | Rx_mux[16];
	 	 pa100_16 = (Rx_mux[19]<<8) | Rx_mux[18];
	 	 na1_16 = (Rx_mux[21]<<8) | Rx_mux[20];
	 	 na10_16 = (Rx_mux[23]<<8) | Rx_mux[22];
	 	 na100_16 = (Rx_mux[25]<<8) | Rx_mux[24];
	 	 ua1_16 = (Rx_mux[27]<<8) | Rx_mux[26];
	 	 ua10_16 = (Rx_mux[29]<<8) | Rx_mux[28];
	 	 ua100_16 = (Rx_mux[31]<<8) | Rx_mux[30];
	 	 ma1_16 = (Rx_mux[33]<<8) | Rx_mux[32];
	 	 ma10_16 = (Rx_mux[35]<<8) | Rx_mux[34];
	 	 ma100_16 = (Rx_mux[37]<<8) | Rx_mux[36];
	 	 tequil16 = (Rx_mux[39]<<8) | Rx_mux[38];
	 	 Ebegin16 = (Rx_mux[41]<<8) | Rx_mux[40];
	 	 Eend16 = (Rx_mux[43]<<8) | Rx_mux[42];
	 	 Estep16 = (Rx_mux[45]<<8) | Rx_mux[44];
	 	 Scanrate16 = (Rx_mux[47]<<8) | Rx_mux[46];
	 	 AmplitudeSWV = (Rx_mux[49]<<8) | Rx_mux[48];
	 	 FrequencySWV = (Rx_mux[51]<<8) | Rx_mux[50];
	 	 EdcChro = (Rx_mux[53]<<8) | Rx_mux[52];
	 	 tintervalChro = (Rx_mux[55]<<8) | Rx_mux[54];
	 	 trunChro = (Rx_mux[57]<<8) | Rx_mux[56];

	 	 if (pa100_16 == 1){
	 	 	Current_range = 100;
	 	 	Current_unit = 'p';
	 	 }
	 	 else if (na1_16 == 1){
	 	 	Current_range = 1;
	 	 	Current_unit = 'n';
	 	 }
	 	 else if (na10_16 == 1){
	 			Current_range = 10;
	 			Current_unit = 'n';
	 	 }
	 	 else if (na100_16 == 1){
	 			Current_range = 100;
	 			Current_unit = 'n';
	 		}
	 	 else if (ua1_16 == 1){
	 			Current_range = 1;
	 			Current_unit = 'u';
	 		}
	 	 else if (ua10_16 == 1){
	 			Current_range = 10;
	 			Current_unit = 'u';
	 		}
	 	 else if (ua100_16 == 1){
	 			Current_range = 100;
	 			Current_unit = 'u';
	 		}
	 	 else if (ma1_16 == 1){
	 			Current_range = 1;
	 			Current_unit = 'm';
	 		}
	 	 else if (ma10_16 == 1){
	 			Current_range = 10;
	 			Current_unit = 'm';
	 		}
	 	 else {
	 			Current_range = 100;
	 			Current_unit = 'm';
	 		}

	 	 if(isFirstRun) {

	 	 	Linear_Sweep = malloc(200);

				sprintf(Linear_Sweep,"e\n "
									 "var c\n"
									 "var p\n"
									 "set_pgstat_mode 3\n"
									 "set_max_bandwidth 200\n"
									 "set_range ba %d\%c\n"
									 "set_e -500m\n"
									 "cell_on\n"
									 "wait %d\n"
									 "meas_loop_lsv p c %d\m %d\m %d\m %d\m\n"
									 "pck_start\n"
									 "pck_add p\n"
									 "pck_add c\n"
									 "pck_end\n"
									 "endloop\n"
									 "cell_off\n"
									 "\n\0",
									 Current_range,
									 Current_unit,
									 tequil16,
									 Ebegin16,
									 Eend16,
									 Estep16,
									 Scanrate16);

				SendScriptToDevice(Linear_Sweep);

				// Set the flag to 0 so this block won't be executed again
				isFirstRun = 0;
	 	 }
	 	}


	 	// Free the memory allocated to Linear_Sweep
	 	free(Linear_Sweep);

 

    This topic has been closed for replies.

    5 replies

    Graduate II
    May 10, 2024

    You have to be more clear in what you mean by "it didn't work"?

    Graduate II
    May 10, 2024

    >>..but it didn't work

    Did work because why? You couldn't receive 58 bytes in the 50ms window? The data was never completely received? The data wasn't correctly synchronized?

    You're passing the data as ASCII? Receiving with some fixed position binary bytes you're converting to words?

    If doing as ASCII, via a terminal, and you're interacting with it, do it line-by-line. Recognize the line/parameter, extract the value.

    If a binary blob/packet why not use a packed structure?

    Visitor II
    May 11, 2024

    "yeah": 58 bytes in 50 ms (TimeOut) needs: 58 * 10 bits (with start and stop) and a baudrate at least as 11,600.
    What is your baudrate?

    Why are all these HAL_Delay()? (why?)

    What does not work?
    You check for HAL_TIMEOUT: so, if not, you assume all the data is there. But what is not working?

     

    AE104Author
    Visitor II
    May 15, 2024

    Thank you @Karl Yamashita @Tesla DeLorean and @tjaekel for your responses!

    Rx_mux buffer is correctly filled out based on my settings. The Linear_Sweep is also updated based on the receiving parameters. I have following code that is for sending measurements back to the PC. I placed a break point at the line of "if (RX_Counter > 0 && RX_Buffer[RX_Counter - 1] == '\n') {" . The program checks this condition and then go back to  "usart2_status = HAL_UART_Receive(&huart2, Rx_mux, 58, 50);" line then it follows the line of the codes in _uart.c file. Then come back to the "if (RX_Counter > 0 && RX_Buffer[RX_Counter - 1] == '\n') {" line and repeat same thing over and over. The question is why the program keeps checking "usart2_status = HAL_UART_Receive(&huart2, Rx_mux, 58, 50);" line. I expect that whenever parameters are received, the function of the line of code is supposed to done. 

    Graduate II
    May 15, 2024

    You're in a while loop so you keep calling HAL_UART_Receive

     

    You need to use HAL_UART_Receive_IT and HAL_UART_RxCpltCallback so that you only update your data structure when you get new data. Set a flag when you receive your 58 bytes. Then in the while loop you can check the flag and then parse the data. See example below.

     

    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file : main.c
     * @brief : Main program body
     ******************************************************************************
     * @attention
     *
     * Copyright (c) 2024 STMicroelectronics.
     * All rights reserved.
     *
     * This software is licensed under terms that can be found in the LICENSE file
     * in the root directory of this software component.
     * If no LICENSE file comes with this software, it is provided AS-IS.
     *
     ******************************************************************************
     */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    UART_HandleTypeDef huart2;
    
    /* USER CODE BEGIN PV */
    bool dataRdy = false;
    uint8_t Rx_mux[58] = {0};
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_USART2_UART_Init(void);
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /**
     * @brief The application entry point.
     * @retval int
     */
    int main(void)
    {
    
     /* USER CODE BEGIN 1 */
    
     /* USER CODE END 1 */
    
     /* MCU Configuration--------------------------------------------------------*/
    
     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
     HAL_Init();
    
     /* USER CODE BEGIN Init */
    
     /* USER CODE END Init */
    
     /* Configure the system clock */
     SystemClock_Config();
    
     /* USER CODE BEGIN SysInit */
    
     /* USER CODE END SysInit */
    
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     MX_USART2_UART_Init();
     /* USER CODE BEGIN 2 */
     UART_EnableInterrupt(); // enable UART interrupt prior to entering while loop.
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
    	if (dataRdy)
    	{
    		dataRdy = false;
    		
    		HAL_Delay(250);
    		technique = (Rx_mux[17]<<8) | Rx_mux[16];
    		pa100_16 = (Rx_mux[19]<<8) | Rx_mux[18];
    		na1_16 = (Rx_mux[21]<<8) | Rx_mux[20];
    		na10_16 = (Rx_mux[23]<<8) | Rx_mux[22];
    		na100_16 = (Rx_mux[25]<<8) | Rx_mux[24];
    		ua1_16 = (Rx_mux[27]<<8) | Rx_mux[26];
    		ua10_16 = (Rx_mux[29]<<8) | Rx_mux[28];
    		ua100_16 = (Rx_mux[31]<<8) | Rx_mux[30];
    		ma1_16 = (Rx_mux[33]<<8) | Rx_mux[32];
    		ma10_16 = (Rx_mux[35]<<8) | Rx_mux[34];
    		ma100_16 = (Rx_mux[37]<<8) | Rx_mux[36];
    		tequil16 = (Rx_mux[39]<<8) | Rx_mux[38];
    		Ebegin16 = (Rx_mux[41]<<8) | Rx_mux[40];
    		Eend16 = (Rx_mux[43]<<8) | Rx_mux[42];
    		Estep16 = (Rx_mux[45]<<8) | Rx_mux[44];
    		Scanrate16 = (Rx_mux[47]<<8) | Rx_mux[46];
    		AmplitudeSWV = (Rx_mux[49]<<8) | Rx_mux[48];
    		FrequencySWV = (Rx_mux[51]<<8) | Rx_mux[50];
    		EdcChro = (Rx_mux[53]<<8) | Rx_mux[52];
    		tintervalChro = (Rx_mux[55]<<8) | Rx_mux[54];
    		trunChro = (Rx_mux[57]<<8) | Rx_mux[56];
    		
    		if (pa100_16 == 1){
    	 	 	Current_range = 100;
    	 	 	Current_unit = 'p';
    	 	 }
    	 	 else if (na1_16 == 1){
    	 	 	Current_range = 1;
    	 	 	Current_unit = 'n';
    	 	 }
    	 	 else if (na10_16 == 1){
    	 			Current_range = 10;
    	 			Current_unit = 'n';
    	 	 }
    	 	 else if (na100_16 == 1){
    	 			Current_range = 100;
    	 			Current_unit = 'n';
    	 		}
    	 	 else if (ua1_16 == 1){
    	 			Current_range = 1;
    	 			Current_unit = 'u';
    	 		}
    	 	 else if (ua10_16 == 1){
    	 			Current_range = 10;
    	 			Current_unit = 'u';
    	 		}
    	 	 else if (ua100_16 == 1){
    	 			Current_range = 100;
    	 			Current_unit = 'u';
    	 		}
    	 	 else if (ma1_16 == 1){
    	 			Current_range = 1;
    	 			Current_unit = 'm';
    	 		}
    	 	 else if (ma10_16 == 1){
    	 			Current_range = 10;
    	 			Current_unit = 'm';
    	 		}
    	 	 else {
    	 			Current_range = 100;
    	 			Current_unit = 'm';
    	 		}
    
    	 	 if(isFirstRun) {
    
    	 	 	Linear_Sweep = malloc(200);
    
    				sprintf(Linear_Sweep,"e\n "
    									 "var c\n"
    									 "var p\n"
    									 "set_pgstat_mode 3\n"
    									 "set_max_bandwidth 200\n"
    									 "set_range ba %d\%c\n"
    									 "set_e -500m\n"
    									 "cell_on\n"
    									 "wait %d\n"
    									 "meas_loop_lsv p c %d\m %d\m %d\m %d\m\n"
    									 "pck_start\n"
    									 "pck_add p\n"
    									 "pck_add c\n"
    									 "pck_end\n"
    									 "endloop\n"
    									 "cell_off\n"
    									 "\n\0",
    									 Current_range,
    									 Current_unit,
    									 tequil16,
    									 Ebegin16,
    									 Eend16,
    									 Estep16,
    									 Scanrate16);
    
    				SendScriptToDevice(Linear_Sweep);
    
    				// Set the flag to 0 so this block won't be executed again
    				isFirstRun = 0;
    	 	 }
    	 	}
    
    
    	 	// Free the memory allocated to Linear_Sweep
    	 	free(Linear_Sweep);
    	 	
    
    	}
    
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
     }
     /* USER CODE END 3 */
    }
    
    /* USER CODE BEGIN 4 */
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
    	if(huart == &huart2)
    	{
    		dataRdy = true;
    		UART_EnableInterrupt(); // enable interrupt again
    	}
    }
    
    void UART_EnableInterrupt(void)
    {
    	HAL_UART_Receive_IT(&huart2, Rx_mux, 58);
    }
    

     

    AE104Author
    Visitor II
    May 16, 2024

    I have another callback to receive the measurements of data:

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
    
     if (huart->Instance == USART3) // check if it's USART3 interrupt
     {
     RX_Buffer[RX_Counter++] = RX_Data[0]; // Store received data in buffer
     HAL_UART_Receive_IT(huart, RX_Data, 1); // Ready to receive next byte
     }
    
    }

    Because of that I got an error message : error: redefinition of 'HAL_UART_RxCpltCallback' @Karl Yamashita 

    AE104Author
    Visitor II
    May 15, 2024

    I recognized that the program didn't go tot the callback function. Because RX_Buffer is filling in the callback function.

    Visitor II
    May 15, 2024

    If you do not use UART in Interrupt mode (_IT) or with DMA - there is not a callback function called (even you would provide one).
    I think you use UART in polling mode:

    usart2_status = HAL_UART_Receive(&huart2, Rx_mux, 58, 50);

     So, no callback involved.

    All your code is in a while(1) block, so you should come back all the time again to this UART receive line. And due to fact using a timeout - if nothing received - you keep going to check (for TIMEOUT). Makes sense to me.

    AE104Author
    Visitor II
    May 15, 2024

    Actually USART2 receives the user settings. USART3 sends Linear_Sweep to a sensor. UART3 receives the measurements data. Then USART2 sends to the PC of the measurements data. Now I placed a breakpoint in the callback function, I recognized that the program goes in the callback function and RX_Buffer (which strores measurements) have these contents :
    Name : RX_Buffer
    Details:"e!a!r!t!t!t!t!l!i!a!k!k!k!k!d!l", '\0' <repeats 3968 times>
    Default:0x2000066c <RX_Buffer>
    Decimal:536872556
    Hex:0x2000066c
    Binary:100000000000000000011001101100
    Octal:04000003154

    @tjaekel 

    AE104Author
    Visitor II
    May 16, 2024

    Sorry the system didn't allow to send more messages @Karl Yamashita 

    I use Putty and this is the settings:

    AE104_0-1715889836749.png

    I use "\t" so there is a tab space between measurement.