Pivprocan
Student
- Jun 14, 2021
- 1
I have been trying to implement this project using Tinkercad, but wasn't able to get a proper output and after troubleshooting the code and trying a couple of other options, I can't seem to be able to accurately detect the PWM voltage as feedback.
Currently, pwm output is connected to an analog input through a voltage divider circuit.
Attached below is the code I'm using for the project.
#include <SPI.h>
#include <Wire.h>
#include <SoftwareSerial.h>
int R = 2;
int avgPower; // set initial power- upto 12.5
int avgVoltage;
double control_signal;
double powersetpoint = 5;// give setpoint upto 12.5 as that is max power
double setpoint;
double Kp = 0.5; //proportional gain
double Ki = 1; //integral gain
double Kd = 0; //derivative gain
int T = 1000; //sample time
unsigned long last_time;
double total_error, last_error;
int max_control=255;
int min_control=-255;
double sensed_output;
const int pwm = 9;
void setup(){
Serial.begin(9600);
pinMode(pwm, OUTPUT);
pinMode(A0, INPUT);
//initialization
avgPower = 10;
int avgVoltageD = sqrt(R * avgPower) * 256/5;
analogWrite(pwm, avgVoltageD);
}
void loop()
{
int CS;
double sense = analogRead(A0);
double s = sense*256/1024; // 0 to 1023 to 0 to 255 conversion
//Serial.println(s);
setpoint= sqrt(R *powersetpoint) * 256/5;
CS = PID_Control(s); // control signal
int avgVoltageD = CS;
avgPower= ((CS*5/1024)^2)/R; // V^2/R formula
analogWrite(pwm, avgVoltageD); // writes output from controller
//Serial.println(avgPower);
delay(1000);
// analog write to pwm- 0 to 255 and anaog read - 0 to 1023
}
double PID_Control(double sensed_output){
unsigned long current_time = millis(); // reads current time
int delta_time = current_time - last_time;
if (delta_time >= T){
double error = setpoint - sensed_output;
//Serial.println(error);
total_error += error; //accumalates the error - integral term
if (total_error >= max_control) total_error = max_control;
else if (total_error <= min_control) total_error = min_control;
double delta_error = error - last_error; //difference of error for derivative term
control_signal = Kp*error + (Ki*T)*total_error + (Kd/T)*delta_error; //PID control compute
//Serial.println(error);
if (control_signal >= max_control) control_signal = max_control;
else if (control_signal <= min_control) control_signal = min_control;
last_error = error;
last_time = current_time;
return control_signal;
}
Currently, pwm output is connected to an analog input through a voltage divider circuit.
Attached below is the code I'm using for the project.
#include <SPI.h>
#include <Wire.h>
#include <SoftwareSerial.h>
int R = 2;
int avgPower; // set initial power- upto 12.5
int avgVoltage;
double control_signal;
double powersetpoint = 5;// give setpoint upto 12.5 as that is max power
double setpoint;
double Kp = 0.5; //proportional gain
double Ki = 1; //integral gain
double Kd = 0; //derivative gain
int T = 1000; //sample time
unsigned long last_time;
double total_error, last_error;
int max_control=255;
int min_control=-255;
double sensed_output;
const int pwm = 9;
void setup(){
Serial.begin(9600);
pinMode(pwm, OUTPUT);
pinMode(A0, INPUT);
//initialization
avgPower = 10;
int avgVoltageD = sqrt(R * avgPower) * 256/5;
analogWrite(pwm, avgVoltageD);
}
void loop()
{
int CS;
double sense = analogRead(A0);
double s = sense*256/1024; // 0 to 1023 to 0 to 255 conversion
//Serial.println(s);
setpoint= sqrt(R *powersetpoint) * 256/5;
CS = PID_Control(s); // control signal
int avgVoltageD = CS;
avgPower= ((CS*5/1024)^2)/R; // V^2/R formula
analogWrite(pwm, avgVoltageD); // writes output from controller
//Serial.println(avgPower);
delay(1000);
// analog write to pwm- 0 to 255 and anaog read - 0 to 1023
}
double PID_Control(double sensed_output){
unsigned long current_time = millis(); // reads current time
int delta_time = current_time - last_time;
if (delta_time >= T){
double error = setpoint - sensed_output;
//Serial.println(error);
total_error += error; //accumalates the error - integral term
if (total_error >= max_control) total_error = max_control;
else if (total_error <= min_control) total_error = min_control;
double delta_error = error - last_error; //difference of error for derivative term
control_signal = Kp*error + (Ki*T)*total_error + (Kd/T)*delta_error; //PID control compute
//Serial.println(error);
if (control_signal >= max_control) control_signal = max_control;
else if (control_signal <= min_control) control_signal = min_control;
last_error = error;
last_time = current_time;
return control_signal;
}
