Menu

PID controller

Help
2009-02-20
2013-05-30
  • Edward LaBudde

    Edward LaBudde - 2009-02-20

    Hi all newbie here.  I finished the PID controller.  Was good experience!
    It is used for feedback controllers.  Lots of stuff on the web about them.  Please note that this version is not in “standard” form (related to the way the tree terms are combined).

    Kent, please note that I now consult chip data for oscillator commands.  I am also studying the chip datasheet and help with vigor.

    Here is the code, use at your own risk.  It can be touchy with gain settings because of rollovers in the Byte values.

    'A PID controller with PWM output
    'Tested 02-20-09
    'Use at your own risk!

    'Chip model
    #chip 16F88, 8
    #config INTRC_IO

    'Set the pin directions
    dir portA.0 in    'input feedback on pin #17 from rc filter
    dir portB.0 out 'set pwm output on pin #6 filter with 10k and 10uF capacitor to simulate a 1 second plant

    'Set parameters
    Pg = 5            'set proportional gain
    Ig = 1            'set integral gain-used to control steady stae error left by the proportional term
    Dg = 1            'set dervitive gain- used to control overshoot
    command = 127    'set command input - drive to this value
    Iterm = command    'set integrator init set command to minimize errors
    Ioutn = 0        'Set integrator init use 0 initally will update on first cycle

    PWMon   
    for rampcmd = 0 to command    'Ramp input to command control ssyetms do not like step inputs
    HPWM  1, 10, rampcmd               
    wait 10 ms
    if rampcmd = command then goto Ready
    next

    Ready:
    resp = readad(an0)                'get new data
    errorn = command - resp            'generate error signal
    Pterm = errorn * Pg                'generate proportional term
    Iterm = errorn*Ig + Ioutn        'generate integral term I*dt
    Dterm = (errorn-erroro)*Dg        'generate dervitive term D/dt
    output = Pterm + Iterm + Dterm    'generate output
    erroro = errorn                    'set previous error
    Ioutn = Iterm                    'set previuos int value
    HPWM  1, 10, output                'output PWM
    wait 10 ms                        'set sample rate = dt

    goto ready

     
    • Santiago

      Santiago - 2009-02-20

      Very interesting!
      I didn't know about this kind of things and i think it is just what i needed...

      But there are some considerations that you have to take care abut:

      You are using byte variables, that means that you only can manage 0 to 255 values... not negative or >255 values are allowed.

      Then lets suppose:

      resp = 130

      When this line is executed:

      errorn = command - resp

      you have:
      errorn = 127 -130  ---> errorn = 252 '....(255-3)

      Pterm = 252 * 5 ---> Pterm = 236 '... not 100% sure about this but the logic is:

      252 * 5 = 1260 ---> 0100 1110 1100
      as Pterm is just 8 bits then Pterm=11101100=236

      Then i think something like this should be done to avoid <0 values:

      if command > resp then
      errorn = command -resp
      error_sign = 1 'positive
      end if

      if command <= resp then
      erron = resp - command
      error_sign = 0
      end if
      this

      Pterm and some other variables should declared as word as it can be >255

      Perhaps the good choice is to declare all variables as word ( 2 bytes)...

      Thanks for sharing ideas....

       
    • Edward LaBudde

      Edward LaBudde - 2009-02-20

      Santiago, Thanks for your comments. 

      The a-d converter returns values from 0-255, there are no negative values. 

      Yes these are the "rollovers" I was talking about.  You can dim as word and use readad10 command, that will help. 

      The resp will usually be smaller than the command, however external disutrbances could produce what you suggest.  Try it out your self.  If you get something better please post it.

      Regards, Ed.

       
    • Santiago

      Santiago - 2009-02-21

      Hi Ed

      I just comment somethings i think could bring problems... just my thoughts:

      >The a-d converter returns values from 0-255, there are no negative values. 

      I was talking about:

      errorn = command - resp

      when resp > command

      or may be:
      Pterm = errorn * Pg
      output = Pterm + Iterm + Dterm

      When the resultant value is >255
      Perhaps is not possible that this happen, but if possible it will happen.

      >The resp will usually be smaller than the command

      Within my ignorance about PID i think this is deppending of the kind of aplication.
      Some aplications may need positive and negative corrections... i mean Pterm can be below or behind command point in every moment.

      I'm just reading about PID and try to better understand how it works.
      I see that the values of the terms and errors should not be very hight, then perhaps i'm talking about a problem that doesn't exist...

      Regards...

       
    • Santiago

      Santiago - 2009-02-21

      Hi again...

      Very interesting the PID controlers... it's a very good thing.
      Now i start understanding how derivative an integral control works, and i think that some kind of signed variables are needed:

      Perhaps the system will never overshoot, then resp > command,..  this seems to be very optimistic, but possible if system is over-cushioned.
      But for example in the derivative term, signed variable looks to be a must, because previous error is espected to be hihger than actual in some moments, then in this calculation erroro > errorn:

      Dterm = (errorn-erroro)*Dg

      This should cause unespected behaivors...

      Other matter is avoiding values > 255, for example here:

      Pterm = errorn * Pg

      erron should be limited at 255/Pg, something like:

      if erron > 255/Pg then erron = 255/Pg

      And perhaps here:

      output = Pterm + Iterm + Dterm

      terms should be limited to 255/3... or limited to 512/3 and check STATUS,C bit... if STATUS,C=1 then output=255

      this will bring in a more complex code, but it will stay in a known state.

       
    • Edward LaBudde

      Edward LaBudde - 2009-02-21

      Santiago, I apologize for the inadequate response to your question yesterday.  It was late in the day and it was nearing gin and tonic time.  After a few G&T's I realized what you were talking about, the integer math.  You are correct.  There is a problem with signs.

      As you can tell I have no experience with integer math.  I will rework this to get it right and post back later.

      Thank you for your astute observations, Regards, Ed.

       
    • mmotte

      mmotte - 2009-02-21

      Ed,
      Interesting discussion.
      I have been working around process PID control for many years and just to throw in a couple of comments.

      You have the basic concepts.

      Integral term should have a "time" tuning variable.  Integral allows you to get back to setpoint when because of nonlinearities in the process you have been running off of setpoint and  proportional gain is not enough.

      Deriative is the slope of the error.  Noise in the measured signal('resp' usually called PV) will drive this crazy. Because it is a slope you would need +/- and so positive and neg values.

      Actually Proportional gain can be +/- depending on the sense of the control,  ie. heating/cooling

      I also searched on the web and there is a lot of info but watch out because some of it isn't right.

      I have too many irons in the fire to work much on this but you might inspire me enough to try it

      good luck
      mike

       
    • Santiago

      Santiago - 2009-02-21

      Hi mmotte. thanks for the aclarations.

      I discovered PID and start understanding it thanks to Ed keep it basic...
      Looking for PID info in the web is sometimes very confusing... lots of ecuations and complex math, but looking to this code is easy to understand how each term is working.

      Now i have readen some pages about PID, i see integral constant is ussually very small. sometyhing like 0,001... but i suppose it dependes on the aplication. There is the problem of float math in GCBasic, but i think it can be managed as 1/100...

      I think Ed uses a low-pass kind filter previous the data is sent to PID.. i saw some code about this in a previous thread.

      I want to try PID to control motors in a small robot... i think this can solve some problems i have. I think the difficult side is to find the correct values for the constants of every term to it reacts as espected and quickly but not becoming unstable... for the moment just try to get a code that adapts to what i have.

      Regards.

       
    • Edward LaBudde

      Edward LaBudde - 2009-02-21

      Santiago
      Here is a corrected code that deals with the negative number issue.  It may not be the most efficient but it seems to work ok. 

      I will have to revisit the low pass filter as well when I get a chance.  If you get your robot working with a PID controller please post it.  Also please use your eagle eyes when you see me post something.  I need lots of help.

      Mike, thanks for the input

      Regards, Ed.

      Ready:
      resp = readad(an0)                    'get new data
      If resp > command then test=true     'Test input
      'Generate Pterm
      If test = false then
      errorn = command - resp
      Pterm = errorn * Pg + command        'For resp<command
      end if
      if test = true then
      errorn = command -(resp - command)    'For resp>command
      Pterm = command - (command -errorn)*Pg   
      end if
      'Generate Iterm I*dt
      if test = true then
      Iterm = errorn*Ig + Ioutn        'For resp<command
      end if
      if test=false then
      errorn = resp-command
      Iterm = iout - errorn*Ig        'For resp>command
      end if
      'Generate Dterm D/dt
      If test=false then
      Dterm = (errorn-erroro)*Dg        'For resp<command
      erroro = errorn                    'set previous error
      end if
      If test=true then
      errorn = resp-command            'For resp>command
      Dterm = (erroro-errorn)*Dg
      erroro = errorn                    'set previous error
      end if

      output = Pterm  + Iterm + Dterm    'generate output

      Ioutn = Iterm                    'set previuos int value
      HPWM  1, 10, output                'output PWM
      wait 1 ms                        'set sample rate = dt
      goto ready

       
    • Edward LaBudde

      Edward LaBudde - 2009-02-22

      Santiago, Since you indicated an interest in robot control, I thought you would be interested in this simple controller code.  A PID controller is a very good general-purpose controller because you are able to “tune” the response to just about any plant and get good results.  But it is more complex and way overkill on simple motor control problems.

      There is a much simpler controller that can perform well on motors.  It is called a Bang-Bang controller because it is just on or off.  It is used to control Laser Guided Bombs! It does not require a PWM on the chip, just uses one of the digital pins for output.  You may have to use an L-C filter to keep the high frequency out of the motor as it just causes power loss (heating).  A small “H Bridge” with an L-C filter and you’re done!

      Hope this can help you.  Thanks for your help.  Regards, Ed.

      'A Bang Bang Controller
      'Tested 02-22-09

      'Chip model
      #chip 16F88, 8
      #config INTRC_IO

      'Set the pin directions
      dir portA.0 in    'Feedback signal pin #17 (an0)
      dir portB.0 out    'output signal pin #6

      'name I/O
      #define pulse portB.0   

      Command = 127 'set desired output from plant

      Ready: 'reads input and computes output
      Input = readad(an0)    'get new data
      if Input < Command then set pulse on
      if Input >= Command then set pulse off
      'wait 1 ms    'option sampling rate control
      goto Ready

       
    • Santiago

      Santiago - 2009-02-22

      Thanks Ed..
      I'm learning about the different kinds of controlers.

      This Bang-Bang controller was my first attempt, but then i wanted a more "soft" movements.. then i did somekind of "proportional" controller, it just pulsed the motors longer or shorter deppending on the "error", but i had some problems ( now i see the typical problems of proportional)... sometimes i had overshooting(derivative for this), and it never reached the target point as very short pulses just didn't do anything (integer for this) ... i think derivative an integer controls can solve this problems.
      Other good thing is that i (or the robot itselfs) can change the constants in different situations... quick response little overshooted may be necessary sometimes, or slow overcushioned in other moments, to have different behaivors...

      I didn't know anything about control... just think what i want and try to program it; now i have a "method" with a few mathematical operations, that is even simpler than my own "proportional" method.

      I hope to learn more about control methods, it's a very interesting and powerful tool.

      The L-C filter is something i have to add... i think just a capacitor in parallel with the motor, as the motor winding is already an inductor... what do you think?

      Thanks for the suggestions.

       
    • Edward LaBudde

      Edward LaBudde - 2009-02-22

      Santiago, thanks for the reply.  I hope you learn control stuff it is very powerful to have it in your bag.  The PID is the best all around controller for any given situation as it can do everything you need to control overshoots and gain errors. 

      "Soft control" means lower bandwidth in a proportional controller.  You could also use the ramp funtion like what I used to get the system approximately were you want it before "closing the loop."

      No about capacitor that will blow out your amp.  Add inductance in series to reduce transient currents on edges of signal.  Also can add a little resistance to reduce ringing of filter if necessary.

      Regards, Ed.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.