STM32 Extra - redwolf-digital/ENE_Embedded_Lab GitHub Wiki

We call it multitasking?

This method requires a "timer interrupt".

This is another method that allows the code to run without being blocked by delay functions. It works by comparing the current time with the timer to check if it exceeds the specified value. This is useful for tasks that rely on timing but where the code cannot be blocked.

uint32_t count;
uint32_t lastTime_1;
uint32_t Settime_1 = 200000;

uint32_t lastTime_2;
uint32_t Settime_2 = 15000;


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) {
	if(htim -> Instance == TIM3) {
		count++;
	}
}


int main(void) {
    HAL_TIM_Base_Start_IT(&htim3);

    while(1) {
        // Task 1
        if((count - lastTime_1) >= Settime_1) {
            // Your program task
            lastTime_1 = count;
	    }

        // Task 2
        if((count - lastTime_2) >= Settime_2) {
            // Your program task
            lastTime_2 = count;
	    }
    }
}

Moving average

requires "ADC".

A Moving Average Filter is a basic technique used in signal processing. The idea is to take several consecutive data points and average them to:

  • Reduce noise

  • Smooth the signal

It moves a "window" across the data step by step, calculating the average at each position.

#include "main.h"

#define SAMPLE_SIZE		1024
#define WINDOWS_SIZE 	8

uint16_t ADC_samp[SAMPLE_SIZE];
uint16_t Filter_samp[SAMPLE_SIZE];

uint32_t temp;

uint16_t k, i, j;

ADC_HandleTypeDef hadc1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);


int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();

    
    HAL_ADC_Start(&hadc1);


    for(j = 0; j <= SAMPLE_SIZE - 1; j++) {
        HAL_ADC_Start(&hadc1);
        ADC_samp[j] = HAL_ADC_GetValue(&hadc1);
        HAL_Delay(1);
    }


    for(k = 0; k <= SAMPLE_SIZE - 1 - WINDOWS_SIZE; k++) {

        temp = 0;

        for(i = k; i <= k + WINDOWS_SIZE - 1; i++) {
            temp = temp + ADC_samp[i];
        }

        Filter_samp[k] = temp/WINDOWS_SIZE;

    }
    

    while(1) {

    }
}

Explanation

for(k = 0; k <= SAMPLE_SIZE - 1 - WINDOWS_SIZE; k++) {

k is the starting index of the moving window. The loop runs from k = 0 to SAMPLE_SIZE - WINDOWS_SIZE to make sure the window does not exceed the array boundary

temp = 0;

temp in this case meaning temporary used for buffer of sum value

for(i = k; i <= k + WINDOWS_SIZE - 1; i++) {
    temp = temp + ADC_samp[i];
}

A nested loop over the elements inside the current window and adds up all values from ADC_samp[k] to ADC_samp[k + WINDOWS_SIZE - 1].

Filter_samp[k] = temp / WINDOWS_SIZE;

Calculates the average by dividing the sum by the number of samples (WINDOWS_SIZE) and stores the result into Filter_samp[k].