Project 03- STM32F4xx PID controller

CMSIS files from ARM provides ARM Math functions. There are also PID controller functions in different formats for f32, q31 and q7. This tutorial/project will talk about how to implement PID controller on STM32F4xx using PID functions from ARM.

PID Controller

Fast about PID controller. PID stands for Proportional-Integral-Derivative controller. This is a control loop feedback mechanism widely used in industrial control systems. It calculates the error between measured value and the desired setpoint value. According to the error, it then calculates output value to minimize this error.

PID Controller block diagram

PID Controller block diagram

I will not go step-by-step on how PID works. More you can look on the sites below:

ARM PID library

ARM company provides 3 different PID controller functions:

  • f32: float
  • q31: integer
  • q7: char

For each of the three types, you have three functions:

  • f32
    • arm_pid_init_f32
    • arm_pid_reset_f32
    • arm_pid_f32
  • q31
    • arm_pid_init_q31
    • arm_pid_reset_q31
    • arm_pid_q31
  • q7
    • arm_pid_init_q7
    • arm_pid_reset_q7
    • arm_pid_q7

There are also ARM PID structure, where you pass PID parameters. More in project example below. If you need additional info about these functions, you have detailed manual here.

PID Sample project

In the project, 2 DS18B20 temperature sensors are used. They are configured in 12bit resolution, so delay between 2 calculations is about ~750ms. If you read about PID controller, you realize that you cannot calculate PID controller results every x microcontroller, because it has integral part which is used to sum all the errors in period. More calculations you have, more integral error you have.

We have one device connected as “reference” temperature. Second sensor is placed near DC FAN, so when DC fan is turned ON, it is cooling the second DS18B20. The goal is, that both temperatures are the same.

In my case, it was about 23°C on the reference sensor. Then, I touched the second DS18B20 near DC fan and I heated them. DC fan was turned on. Everything is displayed via USART to computer. FAN is controlled via 1kHz PWM output. According to the error between both sensors, more error, more duty cycle to DC fan.

This is just a sample project, so PID parameters are not set optimal. For every project you have to set parameters for specific project.

This example successfully works on all STM32F4xx development board such as Discovery and Nucleo.

In the example, 1 PID controller is used. If you need to control more than just one thing, you can add additional ARM PID instances and you can use more than just one PID controller at a time.


  • Both DS18B20 sensors are connected to the same pin: PA6
  • DC fan PWM pin (controlled via transistor): PA5
  • USART output: PB6, 115200baud


STM32F4 PID controller project setup

STM32F4 PID controller project setup

Download entire project with libraries and USART output log below.

Project 03- STM32F4 PID Controller


Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Saqib Ashraf

    How to define the pid parameters ?
    Is there any scale ?

    • Depends on your needs.
      I’ve chosen the same values I have on my 3D printer 😀


        我想用 duty = arm_pid_q31(&PID, pid_error); 不用float类型的,控制直流电机PWM输出的

  • erkan

    How to calculate pid parameters ?

  • mdk

    Where set you dt parameter for numerical integration/differentiation?

    • Nowhere.
      Dt paraneter in this case is time between 2 function calls for PID calculation.

  • João Vene

    If I wanted to use something else besides DS18B20 sensors would I need to change the code?
    For example, if I wanted to control a DC motor using a tacometer, would I need to chage how it’s reading the pins?
    Also, great site, wish I had found it sooner.

    • Well, you need some “input” method where you get your desired value. My was reading sensor and comparing to another, your will be tacometer which will be compared to some constant or something else.

      For output pin, I used PWM with selectable duty cycle.

  • h.mehrabian

    I have read the CMSIS from ARM. It says, in choosing PID controller parameters, we just have single precision floating-point. If we need more precision (like Kp=0.0004,Ki=0.02), what should we do?

    • FPU has 7 decimal places.

      • h.mehrabian

        but according to below link:

        in CMSIS’s PID controller which is used CMSIS DSP Software Library, there is just single precision and it means that we can use one decimal in DSP Library.

        Have u ever use PID controller with more than one decimal?

        • Well, you have to clarify yourself what is single precision. This is float value, so 7 decimal places can be used.
          0.0000001 can work without problems.

          Double precision is 15 decimal places.

          • h.mehrabian

            I got wrong meaning from the passage.

  • h.mehrabian

    I will design a controller with high order(more than 2).

    I’m looking forward to understand C file of arm_pid_init_f32.

    but, it goes hard. For example, the following phrase is hard for me to understand.
    S->A0 = S->Kp + S->Ki + S->Kd;

    Where can find the meaning of them?

    • Don’t worry about that.
      Just make sure, you have correct values for P I and D parameters.

      • h.mehrabian

        I can handle with conventional PID but, I want to design a new controller that is totally different form PID.
        CMSIS library can help?

        • Then this is not PID and you have nothing to do here.

  • mahmud istiaq

    hey, what about sampling time. Does it do the sampling time calculation by itself or I have to do this. Thank you.

  • kamiltbg

    Hi, I’m usind Coocox CoIDE 1.7.8 and still getting “redeclaration of enumerator” errors. How can I fix it?

    • I’m sure you also get exactly which enumeration goes wrong.

      • kamiltbg

        enum IRQn

        • What are you doing? This should never happen.

          • kamiltbg

            I have program with simple PWM from your tutorial and USART printing, but I’m getting errors even when I’m using example you posted here.

          • So you have some problems with configuring project.


    HI, Using with KEIL-MDK5. Just started the program with this PID controller library. I have an unknown error that is shown in the attached image.

    As of my understanding,
    The error message: ARMCM4.h under arm_math.h file cannot be opened.

    Is there any header file under this name “ARMCM4.h” that must include with my program ? . I also couldn’t find such file with your project 03.

    Kindly help!!! THANKS A LOT …..

    • Check one line below for warning. Define proper value.

      • FELIX

        If I am not wrong, the value ARM_MATH_CM4 or ARM_MATH_CM3 must set under “option for target -> tab C/C++ -> Define”. Right?

        what do you mean ?

  • wildan

    HI, Using with KEIL-MDK5. Just started the program with this PID
    controller library. I have an unknown error that is shown in the
    attached image.In left image is not error but when I try to conjuction with other program lot of error ??

    • Error told you what to do. Double click on error to see where it happen. You need a define to make in options for target /C/C++

  • Flora

    Hi, I’m beginner in coding, I’m using STM32F407G Discovery with HAL library and I want to implement PI controller.
    I tried the code mentioned above but it works only for P (proportional) for ki=0.
    Maybe it’s problem of setting time, I don’t know how to fix it.
    I need help please

  • karlis77

    Hi Tilen.I really appriciate your work!
    Can you please advice me what could be the reason of this error?

    Error undefined reference to `arm_pid_init_q31′

    I included the and arm_pid_init_q31 is locate is declared there, why am I getting this error?