1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  3. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  4. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

Implementing PID control in Microcontroller

Discussion in 'Miscellaneous' started by tronicgr, Jun 30, 2008.

  1. tronicgr

    tronicgr

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
    Here is a simple example (made in basic language for BASIC STAMP2 microcontroller) of implementing PID control of an actuator:

    PidBlockDiagram.jpg


    SetPoint CON 0 ' Set point
    Kp CON 10 ' Proportionality constant
    Ki CON 10 ' Integral constant
    Kd CON 10 ' Derivative constant


    Current CON 0 ' Array index - current error
    Accumulator CON 1 ' Array index - accumulated error
    Previous CON 2 ' Array index - previous error
    Delta CON 3 ' Array index - change in error

    sensorInput VAR Word ' Sensor input variable
    error VAR Word(4) ' Four different types of errors
    p VAR Word ' Proportional term
    i VAR Word ' Integral term
    d VAR Word ' Derivative term
    drive VAR Word ' Output


    DO
    DEBUG Enter sensor input value:
    DEBUGIN SDEC sensorInput

    ' Calculate error.
    error(Current) = SetPoint - sensorInput

    ' Calculate proportional term.
    p = Kp * error(current)

    ' Calculate integral term.
    error(Accumulator) = error(Accumulator) + error(Current)
    i = Ki * error(Accumulator)

    ' Calculate derivative term.
    error(Delta) = error(Current) - error(Previous)
    d = Kd * error(delta)

    ' Calculate output.
    drive = p + i + d

    ' Display values.
    DEBUG CR, CR, ERROR, CR,
    SDEC ? SetPoint, SDEC ? sensorInput, SDEC ? error(Current), CR,
    PROPORTIONAL, CR,
    SDEC ? Kp, SDEC ? error(Current), SDEC ? p, CR,
    INTEGRAL, CR,
    SDEC ? Ki, SDEC ? error(accumulator), SDEC ? i, CR,
    DERIVATIVE, CR,
    SDEC ? Kd, SDEC ? error(Delta), SDEC ? d, CR,
    OUTPUT, CR,
    SDEC ? p, SDEC ? i, SDEC ? d, SDEC ? drive, CR, CR


    ' Save current error to previous error before next iteration.
    error(Previous) = error(Current)

    LOOP


    More analysis on what each term does in graphics representations:


    The Proportional Control Loop

    Proportional control is sufficient for some systems. A block diagram for proportional control is shown in next Figure. The circle on the left is called a summing junction, and it shows how the measured sensor value is subtracted from the desired sensor value (the set point) to calculate the error. This is the error that needs to be corrected by the control system. Proportional control attempts to correct this error by multiplying it by some constant value (Kp). The resulting actuator output exerts a correcting influence on the system. By definition, this influence is proportional to the measured error. Since the actuator output has some effect on the system, the sensor value is checked again, and the whole process is repeated, over and over again to maintain the level(s) in the system.

    ProportionalControlLoop.jpg

    The next figure shows a graph of the change in some error measurements over time. Notice how the error is 3 in the sample at time = 2. Since Kp is 10, the output is 30. In the second sample at time = 7, the error is -2, so the output is -20.

    ProportionalErrorVsOutput.jpg



    Integral Control


    Proportional is just one way to react to an error in the system. The problem with proportional control is that it can't detect trends and adjust to them. This is the job of integral control.

    IntegralBlockDiagram.jpg

    There is another example graph of the error in a system over time on the left of the next figure. Again, it might be the distance of a robot from an object, or it could be fluid level in a tank, or the temperature in a factory oven. Perhaps the target the robot is following keeps on going away from the robot at a speed that the robot isn't catching up with. Maybe the oven door seal is worn; maybe the fluid draw from the tank is unusually large. Regardless of the cause, since proportional is not designed to react to trends it can't detect and correct the problem. That's where integral control comes into the picture.

    IntegralAreaVsOutput.jpg

    Integral measures the area between the error values and the time axis. If the error doesn't return to zero, the area of the error gets larger and larger. The right side of next figure shows how the integral output can react to this kind of trend. As the area between the error curve and the time axis increases, the output increases proportional to this area. As a result, the output drives the actuator harder and harder to correct the error.

    So what happens when the error isn't a straight line, like the curve shown in the next figure? That's what the calculus operation of integration determines, the area between a curve and an axis. In the case of integral control, as more time passes with an error, the area under the curve grows, and so does the value that the integral calculation will use to drive against the system error. If the error curve drops below the time axis, the buildup of negative area subtracts from the buildup of positive area. When tuned correctly, integral control can help the system home in on an error of zero.

    AreaUnderCurve.jpg



    Derivative Control

    DerivativeControlLoop.jpg

    Here's a situation that neither proportional nor integral control really deal with. It's rapid changes to the system that come from an external source. Keeping the system steady when outside influences are making it change abruptly is the job of derivative control. In calculus, derivative is an operation that measures the rate of change of a curve, such as the error curve shown in the next figure. By taking action based on the rate the error is changing, the output drive can respond rapidly to disturbances to the system.

    ContinuousDifferentiationSamples.jpg


    Best Regards, Thanos
  2. tronicgr

    tronicgr

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
    Hi Sirnoname,

    I used to use Proportional and Derivative terms but the added complexity of the program and the speed loss on the update rate, lead me to end up using only the Proportional term in my Firmware v1.0. That why its the only term you can change through the hyperterminal interface. :blush:

    Another thing is that low 8-bit resolution values [X-Sim1] prevent me doing the math needed without introducing stepping. I might try again with 16bit input position values [X-Sim2] and 16bit encoders to see if I can do better with full PID this time...

    Its all trial and error after all.

    Regards, Thanos
  3. tronicgr

    tronicgr

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
    Well that the basic concept.

    But I handle the direction matter a little differently on my AMC cause the PWM values are in reality 9bit by their nature. It means that I get 512 different speeds per direction. And it goes like this:

    Direction 1: 511 value decreasing to 0 value, then the speed value will be inverted PWM + offset value. (inverted 512 value)
    Direction2: 512 value increasing to value 1023, then the speed value will be the original PWM value (normal 512 value).

    You may not understand it, as its more associated to the internal handling of pwm values on my code... But I give it anyway to see that even with 9-bit we can have 10-bit speed range around a position!!!

    Regards, Thanos
  4. tronicgr

    tronicgr

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
    @Sirnoname, Just to anwer some more quetions...


    I use Kp value 4 for the X axis and Kp value 6 for the Y axis. The difference is because Y axis has slower responce during the bigger distance from the pivot point!!!! I had to increase it to get the same reaction as in X axis.


    What do you mean? It reads the pots one time per entire loop of the program. That is around 307 times per second! You want perhaps the curve that it does as it accelerates and decelerates from one side to the other...?

    Thanos
  5. tronicgr

    tronicgr

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
    First, I use 10 bit variables for the position. That means that 512 values swing to each direction!
    Second, I calculate the error within 16-bit values!

    That means that I can handle the error even if its very large. BUT since the ADC input is also 10-bit I can't get bigger error than 1024!! So most of the times the error falls inside the 1024 boundaries of the 10-bit position values!!! Also I limit the max error produced to within the 1024 values so in worst case it will instantly top on 1024 value (full left direction i.e) or hit bottom 0 value (full right direction i.e)

    I wish I could encode the Data input (error) ADC input (feedback sensor) and PWM output (drive) in one graph to see how it reacts on changes!!!

    Regards, Thanos
  6. tronicgr

    tronicgr

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
    I'm not sure about how a software based PID will work without real position feedback...

    Maybe I'll compile a test version of my AMC firmware that sends back to PC the values of the potentiometers. Then Sirnoname could use it on the AMC1.5 board I sent him to try it himself and calibrate it.

    But IMHO PID algorithms depend alot on the update frequency of the feedback readouts so it can be easily encounter bottleneck traffic throu the serial interface. And in case of program failure (program stops responding or blue screen) the actuator will be out of control!!

    Regards, Thanos