cancel
Showing results for 
Search instead for 
Did you mean: 

Update parameters with UART

AE104
Senior

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);

 

12 REPLIES 12
Karl Yamashita
Lead III

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

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

>>..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?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

"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?

 

AE104
Senior

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. 

AE104
Senior

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

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.

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 

I just realized that the program enters to the callback function and get a response like that when I place a breakpoint in callback function "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"

Callback function UART3 since it receives the measurements.

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);
}

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.