hadrizx:
thanks for ur reply sir, i have read all your post and watch two of your videos about balancing robot.
im not a control engineer so i dont really familiar with something like deadband, so can you assist me how to get a deadband for balancing robot, im sorry if that was a stupid question.
what is the different of 0 degree and 1 degree setpoint?
this is for starting the robot right? dont start balancing until it get the right angle?
i already follow your instruction sir trying to tuning it from P until it get good enough to balance but when i add d D term its always jitter and balance and wandering around just for about 10 second until its fall to the ground
PS: if i use D term like in your video sir its not affect anything until i use around 60 D term
Thanks,
Hadri
Everyone’s program responds differently and we are somewhat relying on your observations to get an idea as to what you are struggling with
You have given me several clues as to what your challenges are as well as I can help answer your questions. So don’t get discouraged if your bot doesn’t react exactly like mine with the values I show.
so can you assist me how to get a deadband for balancing robot
// NORMALISASI HASIL PWM NEGATIF
if (MotorKiri < 35) {
MotorKiri=35;
}
if (MotorKanan < 35) {
MotorKanan=35;
}
Am I correct that at the analogWrite(ENA,35) is where your motor start to move?
What happens while the PID loop is transitioning from -35 to 0 and again from 0 to +35?
Answer: Nothing and so your PID loop can’t provide any reaction to needed control requests during this transition
The simplest change would be to Add 35 before sending it to the motors
Suggested change:
MotorKiri = PID;
MotorKanan = PID;
// NORMALISASI HASIL PWM NEGATIF
MotorKanan=abs(MotorKanan);
MotorKiri=abs(MotorKiri);
// This will work to allow instant shifting in direction
MotorKiri += 35;
MotorKanan += 35;
if (MotorKiri > 255) {
MotorKiri=255;
}
if (MotorKanan > 255) {
MotorKanan=255;
}
// or this would work also with a little different reaction curve
MotorKiri = map(MotorKiri ,0,255,35,255);
MotorKanan = map(MotorKanan,0,255,35,255);
// Try either of the above options:
analogWrite(ENA, MotorKanan);
analogWrite(ENB, MotorKiri);
The other quick observation I spotted was that you D term is higher than mine
if i use D term like in your video sir its not affect anything until i use around 60 D term
The cause of this is that you Change in Error is small because your sample rate is much higher delay(2); and you are not converting it to a known time interval as I did. Is this a problem Not at all
yours should work fine and your Kd will represent your timing. I used a 1 second interval to reference my Ki and Kd terms My actual sample rate is 10 Milliseconds and so everything is calculated with this in mind.
My PID Code 
unsigned long Now;
if ( (unsigned long)((Now = micros()) - lastTime) >= (SampleTime)) {
unsigned long DeltaTuS = (Now - lastTime);
lastTime = Now;
double Input = *myInput;
double Setpoint = *mySetpoint;
double error = Setpoint - Input;// Calculate error
double PTerm = kp * error;// Proportional term
double DeltaTS = ((double)DeltaTuS * 0.000001);//
if(ki){
ITerm += error * DeltaTS * ki; // Integral term
ITerm = (ITerm <outMin )? outMin:((ITerm > outMax)? outMax : ITerm); // Prevemts Windup
}
double DTerm = 0;
if(kd){
//Derivative term using error change (Possible infinity errors could occure)
//DTerm = kd * ((error - pre_error) / DeltaTS); //Derivative term
//pre_error = error;
/********************************************************************************************************************************
Kd*derror(temperature)/dtime = -Kd*dangle(temperature)/dttime // The two equations are equal Second one avoids infinity errors
*********************************************************************************************************************************/
// Derivative term using angle change
DTerm = -kd * ((Input - lastInput) / DeltaTS); //Derivative term avoid infinity errors
lastInput = Input;
}
double Output = PTerm + ITerm + DTerm; //Compute PID Output
Output = (Output <outMin )? outMin:((Output > outMax)? outMax : Output); // Limits Output
*myOutput = Output;
I will look over your code more and comment as I see other differences or suggestions
Let me know if this helps.
Z