samu1214
Newbie
I'm relatively new in C program ( I'm using MPLAB X IDE XC8 ), and first time trying to make a PID control, using a PIC16F15223
This is what I want to make:
The PWM duty cycle can be calculated as:
Where in PWM3DCL store the 2 less significative bits and PWM3DCH the remaining ones.
I'm using PR2=155.
This is what I want to make:
- The pic has an analog input that reads a SHUNT resistor. This will oscillate between 0-3V, so in the code between 0-615.
- The pic has a PWM output with a fixed frequency of 100hz, the duty cycle will oscillate between 0% and 100%.
- This is for controlling the current charge of a battery ( lead-acid ). The control is made with two SCRs making a full bridge rectifier ( with the transformer with a center tap ), the gate of the SCRs its controlled by a MOC3021 ( optocoupler ), and the MOC3021 its controlled by the PWM output of the PIC16F15223.
- I'm having troubles with the code in C. Firstly because I never made a PID control, and then because I search some of them in the internet but I dont know how to implement them.
- I read the current and store it in an INT variable called measured_current. Then I put it in the calculate_PID program, and that return's me a value. So that value it's the current that I will have to send as a PWM signal until it reaches a SET POINT, and then it will maintain this current to work as a constant current charge. The problem it's that I don't know how to turn this output value of the pid as a pwm duty cycle. In fact I'm not sure that the PID code its ok, because it was taked from a general PID code from internet...
- I know that its not necessary a PID control for my case, but i dont know another one, maybie you can help me with that to...
- I let you the code and schematic:
Code:
current_pid = calculatePID(measured_current);
if (current_pid>0)
{
}
else if (current_pid<0)
{
}
else if (current_pid==0)
{
}
The PID control:
#include <stdint.h>
// Variables del control PID
double kp = 1.0; // Ganancia proporcional
double ki = 0.5; // Ganancia integral
double kd = 0.2; // Ganancia derivada
double setPoint = 0; // Valor deseado
double error = 0.0;
double prevError = 0.0;
double integral = 0.0;
double derivative = 0.0;
double calculatePID(double inputValue) {
error = setPoint - inputValue;
double proportional = kp * error;
integral += ki * error;
derivative = kd * (error - prevError);
prevError = error;
double output = proportional + integral + derivative;
return output;
}
The PWM duty cycle can be calculated as:
Where in PWM3DCL store the 2 less significative bits and PWM3DCH the remaining ones.
I'm using PR2=155.