0av067
asked on
MPLAB simulation time differs from actual execution time.
Hello!
I am using a PIC 18F4431 and MPLAB with C18 as my IDE.
My problem is that a certain while loop takes much longer (100-1000 times longer) to actually run on the micro-controller in circuit than it does in the simulation.
The loop is a PID algorithm that controls the position of a device that is powered by a DC motor. A quadrature encoder gives the position. The PIC that I am using has a quadrature encoder interface built in so I can't imagine that would be the source of delay. Also, there is a built in pulse width wave form generator. Attached is the code. Please let me know how I can clarify the problem. This is driving me nuts! Please help :)
Alex
I am using a PIC 18F4431 and MPLAB with C18 as my IDE.
My problem is that a certain while loop takes much longer (100-1000 times longer) to actually run on the micro-controller in circuit than it does in the simulation.
The loop is a PID algorithm that controls the position of a device that is powered by a DC motor. A quadrature encoder gives the position. The PIC that I am using has a quadrature encoder interface built in so I can't imagine that would be the source of delay. Also, there is a built in pulse width wave form generator. Attached is the code. Please let me know how I can clarify the problem. This is driving me nuts! Please help :)
Alex
while(bControl == 1){
k++;
j++;
position = getQEIPos(); //get encoder position
last_error = error;
error = setpoint - position;
PIDintegral = PIDintegral + (error*Ti)+(output - control)/Tt; //integral with track back to prevent wind up
PIDderivative = (error - last_error)/Td; }
control = (Kp*error)+(Ki*PIDintegral)+(Kd*PIDderivative);
if((error<10) && (error > -10)){ //this is to exit the loop if the error is small
j++;
if(j>157){ //this should take 0.2 seconds
bControl = 0;
}
}
//******** ensure that output does not exceed possibilities of the actuator
output = control;
if(control > motor_limit){
output = motor_limit;
}
if(control < (-100)){
output = (-100);
}
setPDC0(output); //set motor duty cycle
Delay10TCYx(20); //delay 200 instruction cycles (40 uSeconds)
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
They work as you say, but interrupts can make the completion of the loop "delayed" with respect of the expected time. The only way to make it reliable, is to disable all interrupts - but be warned on DMA! - but sometime this is not good.
That's why you can't be assured that a loop is completed in a constant time.
That's why you can't be assured that a loop is completed in a constant time.
ASKER
I see. That was very clarifying... and don't worry, I'm not advanced enough to use DMA yet :) soon enough! Thank you very much.
You're welcome ;-)
ASKER
So in the end, I was telling the SIM that I was using an external oscillator while in practice I was using the much slower internal oscillator. A quick edit of the configuration bits fixed the problem.
Regarding the PID, thank you so much for the advice. I didn't know that delays are unreliable. I thought they simply created a loop that waited a designated number of instruction cycles. I switched to using the timer to handle the delay as per your advice.