2024-12-18 04:10 AM
I have a STM32F411 board connected with a GPS module connected onto USART2
I also have Tim1 and Tim3 configured for PWM generation on their channels respectively.
I am running a list of commands (from an array) to execute line for line.
Most of the execution is in the form of assigning new values to the Timer channels
Eg: __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, motor1_speed); Motor speed is a variable assigned from the list. As the program executes the list (by iterating line for line, these variables get assigned those values.)
The GPS on the other hand is being polled via USART2
The problem is that I need both the execution of the array as well as the GPS to continue running.
However, the array execution is causing a "blocking issue". I have about 15 lines of instructions in the executing array. The GPS will only work AFTER ALL the commands of the array has been executed due to its blocking issue.
I investigated from many sources who advised:
Any assistance here?
Solved! Go to Solution.
2024-12-18 09:00 AM
@Andrew Neil wrote:It's still not at all clear what all this "execution of the Array" stuff is about, and why your code to do it is "blocking"
@techdesk so in this:
MotorInstruction instructions[] = {
{'F', {900, 900}, 10}, // Move forward at speed 900 for 10 seconds
{'F', {100, 600}, 3}, // Turn with speeds 500 and 600 for 3 seconds
{'F', {600, 600}, 10}, // Move forward at speed 600 for 10 seconds
{'F', {700, 700}, 3}, // Move forward at speed 1000 for 3 seconds
{'F', {900, 900}, 3},
// etc etc.....
};
are those timings all done with blocking delays?
If so, then you need to make that non-blocking.
You could use the same principle as here:
https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay/
HAL_GetTick() is equivalent to the Arduino millis() ...
2024-12-18 09:06 AM - edited 2024-12-18 09:10 AM
@techdesk wrote:Blocking can be understood as...
Yes, we know what the term means.
What's unclear is how/why your code is blocking.
Remember: we can't see your code!
"executing" an array doesn't really mean anything.
While I was typing, @Tesla DeLorean wrote:Perhap use HAL_GetTick(), leave, and then delta the time difference at the next iteration,
@techdesk - That's essentially what the Arduino example I pointed to does.
2024-12-18 10:04 AM - edited 2024-12-18 10:06 AM
@Andrew Neil wrote:You could use the same principle as here:
https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay/
HAL_GetTick() is equivalent to the Arduino millis() ...
Here you go - blinking two LEDs with unrelated periods:
/* Infinite loop */
/* USER CODE BEGIN WHILE */
uint32_t ld4_blu_interval = 2000;
uint32_t ld3_grn_interval = 3000;
uint32_t ld4_blu_previous_tick = 0;
uint32_t ld3_grn_previous_tick = 0;
while (1)
{
uint32_t current_tick = HAL_GetTick();
if( current_tick - ld4_blu_previous_tick >= ld4_blu_interval )
{
ld4_blu_previous_tick = current_tick;
HAL_GPIO_TogglePin( ld4_blu_GPIO_Port, ld4_blu_Pin );
}
if( current_tick - ld3_grn_previous_tick >= ld3_grn_interval )
{
ld3_grn_previous_tick = current_tick;
HAL_GPIO_TogglePin( ld3_grn_GPIO_Port, ld3_grn_Pin );
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
(Tested on an F0-DISCOVERY board, with User LEDs LD3 Green and LD4 Blue)
I've just duplicated everything for the 2 LEDs there; more generally, it'd be better to factor that into a function (or functions) ...
#NonBlockingDelay #NonBlockingBlinky #NoDelayBlinky
2024-12-18 10:12 AM
> Many responders to this thread give advice, but no sample code to test. Best not to respond rather than give fresh air code
You haven't presented any code which blocks or illustrates the issue. This forum is not a code writing service.
The air of entitlement in this post is offputting.
2024-12-18 12:15 PM
Like I said, I finally manged to:
1. Read GPS via USART2,
2. Send/Receive text commands via USART1.
3. Execute a list of commands in the Main()
ALL simultaneously!
I. I enabled Interrupts for both USARTs
2. added this also in the Main() (just an example of my code)
HAL_UART_Receive_IT(&huart1, (uint8_t *)&received_char, 1);
HAL_UART_Receive_IT(&huart2, (uint8_t *)&received_char, 1);
Without these lines in the Main(), it will NEVER work
This is a super feat especially for projects requiring autonomous mode.
If anyone needs further details, I will provide.
In any case, thank you all for your helping attempts
2024-12-18 01:04 PM
@techdesk wrote:Like I said, I finally manged to:
1. Read GPS via USART2,
2. Send/Receive text commands via USART1.
3. Execute a list of commands in the Main()
ALL simultaneously!
I. I enabled Interrupts for both USARTs
2. added this also in the Main() (just an example of my code)HAL_UART_Receive_IT(&huart1, (uint8_t *)&received_char, 1);
HAL_UART_Receive_IT(&huart2, (uint8_t *)&received_char, 1);
Without these lines in the Main(), it will NEVER work
This is a super feat especially for projects requiring autonomous mode.
If anyone needs further details, I will provide.
In any case, thank you all for your helping attempts
You say you added HAL_UART_Receive_IT to main. But you don't say where in main.
Show MORE of your complete code so we can see the bigger picture, not just snippets
2024-12-19 02:12 AM
@techdesk wrote:3. Execute a list of commands in the Main()
So is that your "execute an array" part?
And that's the part that was "blocking" originally?
@techdesk wrote:Like I said, I finally manged to:
So you've now solved the issue? If so, please mark the actual solution.
It would be helpful for future readers if you would describe what, exactly, was causing the "blocking" originally, and how you solved that.
2024-12-19 02:48 AM - edited 2024-12-19 02:50 AM
Basically as you know sometime a simple overlooked code causes tons of headaches.
My program flow
Int Main ()
.....
......
instructionsexecute(): //This function used to run and complete then only other functions used to run. This was causing the blocking
HAL_UART_Receive_IT(&huart1, (uint8_t *)&received_char, 1);
HAL_UART_Receive_IT(&huart2, (uint8_t *)&received_char, 1);
Then I enabled the USART1 and 2 global interrupts and ran the functions in the automatic
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
My initial mistake was that I mistakenly unchecked the global Interrupt for USART2
Thus the solution is very simple.
However, it took me me hours to discover that these two lines had to be placed in the Int Main() otherwise it will NEVER work
HAL_UART_Receive_IT(&huart1, (uint8_t *)&received_char, 1);
HAL_UART_Receive_IT(&huart2, (uint8_t *)&received_char, 1);
Did I clarify myself well??
2024-12-19 03:00 AM
2024-12-19 03:40 AM
"What was it doing? Why was it blocking?"
To answer this question:
The program wasn't doing anything unusual—it was simply executing the function as written. By default, all programming languages, including those used for STM32, operate sequentially unless explicitly programmed for concurrency.
For example, in C++ or Delphi, programs execute instructions sequentially. To allow other tasks to run concurrently, you might add a command like Application.ProcessMessages (in Delphi) or similar constructs in other languages.
In my case, the instructionsexecute() function was running sequentially, and so was my USART polling. Both were handled in a linear, step-by-step manner.
To achieve concurrency—allowing something like GPS polling to run in parallel with instructionsexecute()—you need to enable global interrupts for the USART. This lets the processor handle incoming USART data (like GPS polling) while continuing to execute the main instructionsexecute() function.