I want to ask about the arduino pid control setpoint value. If my system output > 100, then the motor will start running. So my pid setpoint must be exactly same with 100 or must over than 100 ?
The value of setpoint is arbitrary in a PID controller.
It is the system value you want the controller to maintain, by adjusting the output value.
The Input and Setpoint must be in the same units. Either define Setpoint in terms of whatever Input measures or re-scale Input to whatever values you choose for specifying Setpoint.
The Output units are completely arbitrary. You can set whatever range you like. The tuning values take care of the mapping between Input/Setpoint values and Output values.
so, it will be like this ?
#include "HX711.h"
#include <Servo.h>
#define DOUT 3
#define CLK 2
unsigned long currentTime, previousTime;
double elapsedTime;
double error;
double lastError;
double input, output;
double cumError, rateError;
// 0.9999818, 0.000000296425, 0.00005195
double kp = 1.043;
double ki = 0.000000000000001;
double kd = 0.00000000000001;
double setPoint = 100;
Servo myservo;
float calibration_factor = 458;
float weight = 692;
float ounces;
int levelvalue = 80;
int pos = 0;
HX711 scale;
void setup() {
Serial.begin(9600);
scale.begin(DOUT, CLK);
scale.set_scale(calibration_factor); // this value is obtained by calibrating the scale with known weights; see the README for details
scale.tare(); // reset the scale to 0
myservo.attach(9);
myservo.write(pos);
}
void loop() {
weight = scale.get_units(), 10;
ounces = weight * 0.035274;
// Serial.print(weight);
// Serial.print(" grams ");
// Serial.println(pos);
Serial.println(output);
// Serial.print(" ");
// Serial.println();
input = weight;
output = computePID(input);
//output = weight;
//Serial.println((String)pos);
level();
if (output < -levelvalue)
{
pos -= 1;
if (pos <= 0)pos = 0;
myservo.write(pos);
}
else if (output >= levelvalue)
{
pos += 1;
if (pos >= 90)pos = 90;
myservo.write(pos);
}
}
void level() {
if (Serial.available() > 0) //check if there is available serial port
{
byte game = Serial.read(); //Read the data and stores in variable
switch (game)
{
case 'E': // easy level
levelvalue = 100;
setPoint = 100;
kp = 1.033;
ki = 0.000000000000003;
kd = 0.00000000000001;
break;
case 'N': // normal level
levelvalue = 200;
setPoint = 200;
kp = 1.011;
ki = 0.00000000000000001;
kd = 0.00000000000001;
break;
case 'H': // hard level
levelvalue = 300;
setPoint = 300;
kp = 1.033;
ki = 0.000000000000003;
kd = 0.00000000000001;
break;
}
}
}
double computePID(double inp) {
currentTime = millis(); //get current time
elapsedTime = (double)(currentTime - previousTime); //compute time elapsed from previous computation
error = setPoint - abs( inp); // determine error
cumError += error * elapsedTime; // compute integral
rateError = (error - lastError) / elapsedTime; // compute derivative
double out = kp * error + ki * cumError + kd * rateError; //PID output
lastError = error; //remember current error
previousTime = currentTime; //remember current time
return out;
}
The ", 10" does nothing. Get rid of it.
Your 'setpoint' is 100 grams? Why calculate ounces?
It's a little hard to see how the 'output' is changing the system so that the scale measures 100 grams.
i just set the double setpoint = 100grams as initial int levelvalue = 80 for the before i switch into the other condition E, N, H
No, it's really not! The setpoint is in the units of the parameter being controlled. If it's a position PID, then setpoint will be in position units, typically encoder counts or similar. It is the current target position. If it's a temperature PID, then setpoint is the target temperture, in degrees. If it;s a pressure PID, then setpoint will be in pressure units, like PSI, Pa, Bar, etc. The input is typically the CURRENT value of the parameter being controlled, in the SAME units as the setpoint, so the current position, current temperature, current pressure, etc.
The setpoint is arbitrary.