i have a mcu application written in C language using IAR compiler, and i encounter some issues with a output variable type.
The PID outputs the result in signed integer, and a variable for controlling a duty cycle register is unsigned int.
Variable initialisation
Code:
int pid =0;
uint16_t duty = 50;
After which the pid function outputs a value which ranges from -400 to 400. If pid is greater than 0, then everything is ok. But if pid goes bellow 0, even with -1 then the duty variable will show something like 65123. Why is this?
Code:
if(pid > 400)
duty = 400; // Runs OK
else if(pid < 0)
duty = duty + pid; // Here is the problem
else
duty = pid;
So for a pid value of -1 and a duty of 50, i would expect 50 + ( -1) to be 49, and not 65123. What i am missing here? I have also tryied duty = uint16_t( duty - pid) and it doesn't help
You did not mention what core is being used; both uint16_t and unsigned int may differ depending on whether data lengh of the CPU is 8 or 16 bits, therefore it is advisable to explicitly set the variable pid lengh to 16 bits, declaring as int16_t, rather than int
As a side remark, truncating the manipulated value output of the PID is probably not a good solution. You rather want anti-windup logic that freezes the integrator when the manipulated value limits are touched.
lets say i have a set point value of 100 (rpm) and a simple P controler like bellow
Code:
int KP = 1
int error = setpoint - actual
int pid = KP * error
lets say the actual speed of the motor is 50, based on this, the error value should be +50, therefore dutyCycle should be +50.
After some time the motor reaches a speed of 110 rpm, this should give a error of 100-110 = -10. Normaly i should apply this negative value do reduce the dutycycle by 10?
I am thinking if the dutycycle is set to 0 could cause some overshoots ?
But the solution makes no sense in terms of control theory. You are creating an integrator that's only active for negative controller output.
It's however necessary to look closer at the implemented controller. In the original post, the variable name pid suggests a PID controller. Now you are discussing a simple P controller.
The main thing is that the controller characteristic has to be designed for useful speed regulation.
I believe that the overflow question has been answered, overall design of the speed controller isn't a problem of C coding.
- - - Updated - - -
Moved the thread to Microcontroller section where it belongs.