Reply by Paul April 30, 20112011-04-30
In article <16c21154-6e25-4c2a-bf76-
57afd41477ac@n2g2000prj.googlegroups.com>, ron.eggler@gmail.com says...
> > On Apr 29, 3:40&#4294967295;am, Paul <p...@pcserviceselectronics.co.uk> wrote: > > In article <ipclva$qq...@speranza.aioe.org>, not.going.to...@seen.com > > says... > > > > > > > > > Hi Ron, > > > > > On 4/28/2011 1:32 PM, cerr wrote: > > > > I need to resolve following problem: > > > > I have an led panel with an opto transistor on it that measures the > > > > light emitted/reflected from the target. I want to control the emitted > > > > light to be equal to a certain setpoint from what the opto transistor > > > > measures. Does that make sense? I'm using an 18F pic to control the > > > > whole circuit and I wanted to come up with a PI if not a PID > > > > controller algorithm that controls my LEDs. I've been reading about > > > > PID controllers but am not 100% sure about some things. So far I've > > > > come up with below code: > > > > ...... > > > > > Also, depending on what you are controlling and how it is likely > > > to *fail*, you might want to put some anti-windup protection on > > > your integral term to keep "Integrator" from becoming *so* > > > large (positive or negative) that it dominates the loop's > > > performance for an inordinately long time. &#4294967295;E.g., imagine using > > > "doubles" for these variables. &#4294967295;Now, imagine the detector is > > > obstructed for 10,000 iterations of your control loop. &#4294967295;In > > > that case, you are likely to see a big "Error" *and* accumulate > > > it repeatedly -- regardless of what your control is trying to > > > do to compensate for it! &#4294967295;When the detector is eventually > > > unobstructed, the "Output" is way out of whack for a long > > > time (until the integrator "clears"). > > > > As a general rule for any electronics or algorithm (software or > > hardware) that is measuring light level from photodetectors to imaging > > sensors should alwasy cope with the error conditions first of > > > > a) The output is always minimum (obstruction/lens cap) > > > > b) The output is always maximum (pointed at sun or bright light) > > > > c) The output of the sensor is disconnected, or failed. > > > > At start up I always ignore at least the FIRST two samples to determine > > what the ambient condition is. In your case I would also every once > > in a while do a detection cycle with the emitter OFF to get an ambient > > condition. This is not used in control loop but tests the sensor is > > working if ambient is not min or max. Then with emmitter ON your error > > must be at least a minimum away from ambient for operations to be > > useable. > > Well, I have a software low passfilter after I read thwe adc and i let > it swing it on bootup, meaning i loop 20 * FILTER in order to get a > valid value, I determined that 20x is a pretty good value to get a > decent start value with a filter like this: > MyVal = (MyVal * FILTER + ADCVal) / (FILTER + 1) and i'm currently > using a FILTER value of 10.
You have heard of 'Garbage In Garbage Out' If all the readings are due to pointing at a bright light, so reading is out of normal range, your filter will still produce an out of output.
> > If you sampling regime is 50 or 60 Hz you should be able to fit a test > > sample inbetween sampling times without effecting the sampling times > > without affecting the sampling loop. > > Yep, that's actually the plan, in between the LED-on cycles, I'm > sampling the ambient brightness which is fed back to the "main-brain" > of the system.
Do you do any the reading is meaningless do NOT process, flag error states.
> Thanks for your contribution too! > roN
-- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.pcserviceselectronics.co.uk/fonts/> Timing Diagram Font <http://www.gnuh8.org.uk/> GNU H8 - compiler & Renesas H8/H8S/H8 Tiny <http://www.badweb.org.uk/> For those web sites you hate
Reply by cerr April 29, 20112011-04-29
On Apr 29, 3:40=A0am, Paul <p...@pcserviceselectronics.co.uk> wrote:
> In article <ipclva$qq...@speranza.aioe.org>, not.going.to...@seen.com > says... > > > > > Hi Ron, > > > On 4/28/2011 1:32 PM, cerr wrote: > > > I need to resolve following problem: > > > I have an led panel with an opto transistor on it that measures the > > > light emitted/reflected from the target. I want to control the emitte=
d
> > > light to be equal to a certain setpoint from what the opto transistor > > > measures. Does that make sense? I'm using an 18F pic to control the > > > whole circuit and I wanted to come up with a PI if not a PID > > > controller algorithm that controls my LEDs. I've been reading about > > > PID controllers but am not 100% sure about some things. So far I've > > > come up with below code: > > ...... > > > Also, depending on what you are controlling and how it is likely > > to *fail*, you might want to put some anti-windup protection on > > your integral term to keep "Integrator" from becoming *so* > > large (positive or negative) that it dominates the loop's > > performance for an inordinately long time. =A0E.g., imagine using > > "doubles" for these variables. =A0Now, imagine the detector is > > obstructed for 10,000 iterations of your control loop. =A0In > > that case, you are likely to see a big "Error" *and* accumulate > > it repeatedly -- regardless of what your control is trying to > > do to compensate for it! =A0When the detector is eventually > > unobstructed, the "Output" is way out of whack for a long > > time (until the integrator "clears"). > > As a general rule for any electronics or algorithm (software or > hardware) that is measuring light level from photodetectors to imaging > sensors should alwasy cope with the error conditions first of > > a) The output is always minimum (obstruction/lens cap) > > b) The output is always maximum (pointed at sun or bright light) > > c) The output of the sensor is disconnected, or failed. > > At start up I always ignore at least the FIRST two samples to determine > what the ambient condition is. In your case I would also every once > in a while do a detection cycle with the emitter OFF to get an ambient > condition. This is not used in control loop but tests the sensor is > working if ambient is not min or max. Then with emmitter ON your error > must be at least a minimum away from ambient for operations to be > useable.
Well, I have a software low passfilter after I read thwe adc and i let it swing it on bootup, meaning i loop 20 * FILTER in order to get a valid value, I determined that 20x is a pretty good value to get a decent start value with a filter like this: MyVal =3D (MyVal * FILTER + ADCVal) / (FILTER + 1) and i'm currently using a FILTER value of 10.
> If you sampling regime is 50 or 60 Hz you should be able to fit a test > sample inbetween sampling times without effecting the sampling times > without affecting the sampling loop.
Yep, that's actually the plan, in between the LED-on cycles, I'm sampling the ambient brightness which is fed back to the "main-brain" of the system. Thanks for your contribution too! roN
Reply by cerr April 29, 20112011-04-29
On Apr 28, 4:26=A0pm, cerr <ron.egg...@gmail.com> wrote:
> > Read this:http://www.wescottdesign.com/articles/Sampling/pidwophd.html > > This article is really helpful and for sure the best of all I read > today (and that was quite a few). > Thank you for that, I rewrote the code and came up with below which > should look better than what I had before: > > typedef struct > { > =A0 signed float iState; > =A0 float iMax, > =A0 =A0 =A0 =A0 =A0 =A0 iMin; > > =A0 float iGain, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pGain; > > }SPid; > > SPid CntrlData; > CntrlData.iGain=3D1; > CntrlData.pGain=3D1; > CntrlData.iMax=3D50; > CntrlData.iMin=3D0; > > signed int8 error=3D0; > int8 target=3D150; > > error =3D adcval() - target; //adcval() will return 8bit value > CntrlLEDs(&CntrlData, error); > //-----------------------------------------------------------------------=
-- ----
> signed float CntrlLEDs(Spid *pid, signed int8 error) > { > signed float pTerm,iTerm; > > /** P **/ > pTerm =3D pid->pGain * error; > > /** I **/ > pid->iState +=3D error; > > if (pid->iState > pid->iMax) > =A0 pid->iState=3Dpid->iMax; > else if (pid->iState < pid->iMin) > =A0 pid->iState=3Dpid->iMin; > > iTerm =3D pid->iGain * pid->iState; > > return pTerm+iTerm; > > } > > Thanks again for your help and your article sure is a keeper!
Well, I'll use above PI controller for now, built it into my software but can't test it yet as i don't have the hardware available yet... any one know of a free controller tune application where i an enter my possible values and maybe even let it run with my code...? Thanks, Ron
Reply by Paul April 29, 20112011-04-29
In article <ipclva$qq2$1@speranza.aioe.org>, not.going.to.be@seen.com 
says...
> > Hi Ron, > > On 4/28/2011 1:32 PM, cerr wrote: > > I need to resolve following problem: > > I have an led panel with an opto transistor on it that measures the > > light emitted/reflected from the target. I want to control the emitted > > light to be equal to a certain setpoint from what the opto transistor > > measures. Does that make sense? I'm using an 18F pic to control the > > whole circuit and I wanted to come up with a PI if not a PID > > controller algorithm that controls my LEDs. I've been reading about > > PID controllers but am not 100% sure about some things. So far I've > > come up with below code:
......
> Also, depending on what you are controlling and how it is likely > to *fail*, you might want to put some anti-windup protection on > your integral term to keep "Integrator" from becoming *so* > large (positive or negative) that it dominates the loop's > performance for an inordinately long time. E.g., imagine using > "doubles" for these variables. Now, imagine the detector is > obstructed for 10,000 iterations of your control loop. In > that case, you are likely to see a big "Error" *and* accumulate > it repeatedly -- regardless of what your control is trying to > do to compensate for it! When the detector is eventually > unobstructed, the "Output" is way out of whack for a long > time (until the integrator "clears").
As a general rule for any electronics or algorithm (software or hardware) that is measuring light level from photodetectors to imaging sensors should alwasy cope with the error conditions first of a) The output is always minimum (obstruction/lens cap) b) The output is always maximum (pointed at sun or bright light) c) The output of the sensor is disconnected, or failed. At start up I always ignore at least the FIRST two samples to determine what the ambient condition is. In your case I would also every once in a while do a detection cycle with the emitter OFF to get an ambient condition. This is not used in control loop but tests the sensor is working if ambient is not min or max. Then with emmitter ON your error must be at least a minimum away from ambient for operations to be useable. If you sampling regime is 50 or 60 Hz you should be able to fit a test sample inbetween sampling times without effecting the sampling times without affecting the sampling loop.
> Some implementations clamp the magnitude of the Error signal. > > Some loops clear the integrator automagically when the sign > of the Error changes. > > Some loops "damp" changes to the setpoint (since a setpoint > change looks like a disturbance). Bumpless transfer, etc.
.... -- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.pcserviceselectronics.co.uk/fonts/> Timing Diagram Font <http://www.gnuh8.org.uk/> GNU H8 - compiler & Renesas H8/H8S/H8 Tiny <http://www.badweb.org.uk/> For those web sites you hate
Reply by Bruce Varley April 29, 20112011-04-29
<snip>
Thank you both D & Tim for your contributions!
I have been reading the whole morning and will keep doing it for the
rest of today I assume... What I learned so far is, I don't need the D
part and neither do I need to I part.

** It's the D & P you don't need.

And just as a little clarification, my pwm that activates the LEDs is having 
a frequency of
100kHz and will be active for 200-500uS while a "light pulse" is
active, that light pulse will come in 50 or 60Hz intervals.... does
this make it any more complicated? I might still need the I part as I
need to sample the adc (and run through the whole controller logic)
while the led is on which would directly interfer with the pwm time
being reset, I can't tell right now if the pwm needs to finish it's
current cycle before it starts the next one with the new duty cycle
tho. I'm using a PIC16F883 - maybe someone here knows...?

Thanks for everything! Your help is greatly appreciated! 


Reply by cerr April 28, 20112011-04-28
> Read this:http://www.wescottdesign.com/articles/Sampling/pidwophd.html
This article is really helpful and for sure the best of all I read today (and that was quite a few). Thank you for that, I rewrote the code and came up with below which should look better than what I had before: typedef struct { signed float iState; float iMax, iMin; float iGain, pGain; }SPid; SPid CntrlData; CntrlData.iGain=1; CntrlData.pGain=1; CntrlData.iMax=50; CntrlData.iMin=0; signed int8 error=0; int8 target=150; error = adcval() - target; //adcval() will return 8bit value CntrlLEDs(&CntrlData, error); //----------------------------------------------------------------------------- signed float CntrlLEDs(Spid *pid, signed int8 error) { signed float pTerm,iTerm; /** P **/ pTerm = pid->pGain * error; /** I **/ pid->iState += error; if (pid->iState > pid->iMax) pid->iState=pid->iMax; else if (pid->iState < pid->iMin) pid->iState=pid->iMin; iTerm = pid->iGain * pid->iState; return pTerm+iTerm; } Thanks again for your help and your article sure is a keeper!
Reply by D Yuniskis April 28, 20112011-04-28
Hi Ron,

On 4/28/2011 2:58 PM, cerr wrote:
> I have been reading the whole morning and will keep doing it for the > rest of today I assume... What I learned so far is, I don't need the D
The Derivative term allows your controller to *anticipate* (in a sense) the response of the system being controlled. It is useful when you have lots of lag in your measurement+control+system. In your case (as I understand it) you are just looking at a reflection and tweaking the "illumination" to achieve some desired result.
> part and neither do I need to I part. And just as a little > clarification, my pwm that activates the LEDs is having a frequency of > 100kHz and will be active for 200-500uS while a "light pulse" is > active, that light pulse will come in 50 or 60Hz intervals.... does > this make it any more complicated?
You have to look at the timing relationship between your "PWM drive" and your measurement -- along with the response characteristics of the emitter and detector. E.g., if your emitter and detector are *ideal*, then when the emitter is off, you will see "darkness" (nothing reflected because the light is already *gone*). So, if you are sampling the detector "instantaneously* (no averaging or integration), then sampling when the emitter is *on* will give you different signals than when it is *off*. If the timing of your sampling varies relative to the drive of the emitter, then you will see apparent variations in the measured signal that really aren't present in the *actual* signal (sometimes it's on, sometimes it's off, etc.) [I can't say what is right for you as I don't understand the actual application you are facing]
> I might still need the I part as I > need to sample the adc (and run through the whole controller logic) > while the led is on which would directly interfer with the pwm time > being reset, I can't tell right now if the pwm needs to finish it's > current cycle before it starts the next one with the new duty cycle > tho. I'm using a PIC16F883 - maybe someone here knows...?
A "P only" controller, IMO, is harder to tune than an "I only" controller. If you really only want to have *one* term to tweak, then I vote for I (assuming your system can handle the response times consequential to this). If you have "enough headroom" in the integrator, then you can have a painfully low integral gain and still -- eventually -- get the system to be stable (assuming you can tolerate the response time *and* that your system doesn't change "too fast") I'm not sure I understand your comments re: the PWM, here. But, then again, I have already confessed my ignorance of your application! :> In a purely generic sense, I would design: - a measurement system that samples the detector "whenever it *should*" - a drive system that runs the PWM at a particular duty cycle and rate - a control system that straddles the two of these -- taking data from the measurement system and "operating parameters" (setpoint, etc.) from "somewhere" (the user?), computing the required "drive" (Output) for the current state reported by the measurement system, and then passing a new "command" to the drive system to effect the changes required to get the system where you want it. My read of your comments suggested that you were trying to control each individual PWM cycle by instantaneously observing the detector's signal (?)
> Thanks for everything! Your help is greatly appreciated!
Reply by cerr April 28, 20112011-04-28
On Apr 28, 2:58=A0pm, cerr <ron.egg...@gmail.com> wrote:
> On Apr 28, 2:35=A0pm, Tim Wescott <t...@seemywebsite.com> wrote: > > > > > > > > > > > On 04/28/2011 01:32 PM, cerr wrote: > > > > Hi There, > > > > I need to resolve following problem: > > > I have an led panel with an opto transistor on it that measures the > > > light emitted/reflected from the target. I want to control the emitte=
d
> > > light to be equal to a certain setpoint from what the opto transistor > > > measures. Does that make sense? I'm using an 18F pic to control the > > > whole circuit and I wanted to come up with a PI if not a PID > > > controller algorithm that controls my LEDs. I've been reading about > > > PID controllers but am not 100% sure about some things. So far I've > > > come up with below code: > > > > #define OFFSET 0 > > > #define P 1 > > > #define I 1 > > > int control_func(int measure, int setpoint) > > > { > > > static int intgrl_err=3D0; > > > int output; > > > int curr_err; > > > > //P > > > curr_err=3Dmeasure-setpoint; > > > output=3D(curr_err*P)+OFFSET; > > > > //I > > > intgrl_err+=3Dcurr_err; > > > output*=3Dg*I*intgrl_err; > > > > return output; > > > } > > > > I however am not exactly sure what the g variabl in the I part is. Th=
e
> > > documentation i read doesn't outline it... :( Some assistance would b=
e
> > > appreciated. > > > Response to a change in output is going to be picked up on the next > > sample (I assume), so you really don't need anything other than integra=
l
> > action -- proportional and derivative control are just invitations for > > Fs/2 oscillation. > > > Normally, if you're not adjusting for sampling rate the overall > > integrator gain is less than one -- I suspect that's what the 'g' is. > > It would also be more clear to name your integrator state intgrl_state =
-
> > it's not really an error. =A0_Multiplying_ your proportional term by th=
e
> > integrator state is _definitely weird_. > > > Read this:http://www.wescottdesign.com/articles/Sampling/pidwophd.html > > > then merge what you learned with this (decorations left as an exercise > > to the reader). > > > int control_func(int measure, int setpoint) > > { > > =A0 =A0static int int_state; > > =A0 =A0int output; > > > =A0 =A0int_state -=3D (measure - setpoint); > > > =A0 =A0// Some code to check for integrator overflow would be a Good > > =A0 =A0// Idea here > > > =A0 =A0output =3D int_state >> INT_SHIFT; > > > =A0 =A0return output; > > > } > > > -- > > > Tim Wescott > > Wescott Design Serviceshttp://www.wescottdesign.com > > > Do you need to implement control loops in software? > > "Applied Control Theory for Embedded Systems" was written for you. > > See details athttp://www.wescottdesign.com/actfes/actfes.html > > Thank you both D & Tim for your contributions! > I have been reading the whole morning and will keep doing it for the > rest of today I assume... What I learned so far is, I don't need the D > part and neither do I need to I part. And just as a little > clarification, my pwm that activates the LEDs is having a frequency of > 100kHz and will be active for 200-500uS while a "light pulse" is > active, that light pulse will come in 50 or 60Hz intervals.... does > this make it any more complicated? I might still need the I part as I > need to sample the adc (and run through the whole controller logic) > while the led is on which would directly interfer with the pwm time > being reset, I can't tell right now if the pwm needs to finish it's > current cycle before it starts the next one with the new duty cycle > tho. I'm using a PIC16F883 - maybe someone here knows...? > > Thanks for everything! Your help is greatly appreciated!
Otherwise, I'd see it making sense if I buffered the controller output and maybe average it during each Frequency pwm cycle(200-500uSec) and once thas's done, apply the new pwm value to be used when the next pulse comes around...
Reply by cerr April 28, 20112011-04-28
On Apr 28, 2:35=A0pm, Tim Wescott <t...@seemywebsite.com> wrote:
> On 04/28/2011 01:32 PM, cerr wrote: > > > > > > > > > > > Hi There, > > > I need to resolve following problem: > > I have an led panel with an opto transistor on it that measures the > > light emitted/reflected from the target. I want to control the emitted > > light to be equal to a certain setpoint from what the opto transistor > > measures. Does that make sense? I'm using an 18F pic to control the > > whole circuit and I wanted to come up with a PI if not a PID > > controller algorithm that controls my LEDs. I've been reading about > > PID controllers but am not 100% sure about some things. So far I've > > come up with below code: > > > #define OFFSET 0 > > #define P 1 > > #define I 1 > > int control_func(int measure, int setpoint) > > { > > static int intgrl_err=3D0; > > int output; > > int curr_err; > > > //P > > curr_err=3Dmeasure-setpoint; > > output=3D(curr_err*P)+OFFSET; > > > //I > > intgrl_err+=3Dcurr_err; > > output*=3Dg*I*intgrl_err; > > > return output; > > } > > > I however am not exactly sure what the g variabl in the I part is. The > > documentation i read doesn't outline it... :( Some assistance would be > > appreciated. > > Response to a change in output is going to be picked up on the next > sample (I assume), so you really don't need anything other than integral > action -- proportional and derivative control are just invitations for > Fs/2 oscillation. > > Normally, if you're not adjusting for sampling rate the overall > integrator gain is less than one -- I suspect that's what the 'g' is. > It would also be more clear to name your integrator state intgrl_state - > it's not really an error. =A0_Multiplying_ your proportional term by the > integrator state is _definitely weird_. > > Read this:http://www.wescottdesign.com/articles/Sampling/pidwophd.html > > then merge what you learned with this (decorations left as an exercise > to the reader). > > int control_func(int measure, int setpoint) > { > =A0 =A0static int int_state; > =A0 =A0int output; > > =A0 =A0int_state -=3D (measure - setpoint); > > =A0 =A0// Some code to check for integrator overflow would be a Good > =A0 =A0// Idea here > > =A0 =A0output =3D int_state >> INT_SHIFT; > > =A0 =A0return output; > > } > > -- > > Tim Wescott > Wescott Design Serviceshttp://www.wescottdesign.com > > Do you need to implement control loops in software? > "Applied Control Theory for Embedded Systems" was written for you. > See details athttp://www.wescottdesign.com/actfes/actfes.html
Thank you both D & Tim for your contributions! I have been reading the whole morning and will keep doing it for the rest of today I assume... What I learned so far is, I don't need the D part and neither do I need to I part. And just as a little clarification, my pwm that activates the LEDs is having a frequency of 100kHz and will be active for 200-500uS while a "light pulse" is active, that light pulse will come in 50 or 60Hz intervals.... does this make it any more complicated? I might still need the I part as I need to sample the adc (and run through the whole controller logic) while the led is on which would directly interfer with the pwm time being reset, I can't tell right now if the pwm needs to finish it's current cycle before it starts the next one with the new duty cycle tho. I'm using a PIC16F883 - maybe someone here knows...? Thanks for everything! Your help is greatly appreciated!
Reply by Tim Wescott April 28, 20112011-04-28
On 04/28/2011 01:32 PM, cerr wrote:
> Hi There, > > I need to resolve following problem: > I have an led panel with an opto transistor on it that measures the > light emitted/reflected from the target. I want to control the emitted > light to be equal to a certain setpoint from what the opto transistor > measures. Does that make sense? I'm using an 18F pic to control the > whole circuit and I wanted to come up with a PI if not a PID > controller algorithm that controls my LEDs. I've been reading about > PID controllers but am not 100% sure about some things. So far I've > come up with below code: > > #define OFFSET 0 > #define P 1 > #define I 1 > int control_func(int measure, int setpoint) > { > static int intgrl_err=0; > int output; > int curr_err; > > //P > curr_err=measure-setpoint; > output=(curr_err*P)+OFFSET; > > //I > intgrl_err+=curr_err; > output*=g*I*intgrl_err; > > return output; > } > > I however am not exactly sure what the g variabl in the I part is. The > documentation i read doesn't outline it... :( Some assistance would be > appreciated.
Response to a change in output is going to be picked up on the next sample (I assume), so you really don't need anything other than integral action -- proportional and derivative control are just invitations for Fs/2 oscillation. Normally, if you're not adjusting for sampling rate the overall integrator gain is less than one -- I suspect that's what the 'g' is. It would also be more clear to name your integrator state intgrl_state - it's not really an error. _Multiplying_ your proportional term by the integrator state is _definitely weird_. Read this: http://www.wescottdesign.com/articles/Sampling/pidwophd.html then merge what you learned with this (decorations left as an exercise to the reader). int control_func(int measure, int setpoint) { static int int_state; int output; int_state -= (measure - setpoint); // Some code to check for integrator overflow would be a Good // Idea here output = int_state >> INT_SHIFT; return output; } -- Tim Wescott Wescott Design Services http://www.wescottdesign.com Do you need to implement control loops in software? "Applied Control Theory for Embedded Systems" was written for you. See details at http://www.wescottdesign.com/actfes/actfes.html