LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

PID Control on FPGA - LabVIEW 8.6.1

I have a loop running at ~40 us (capable of running higher, but this is overkill) reading two voltages, doing some math, then running that value into the PID sub-vi as the process variable.  How does the sampling time setting apply in this case?  The documentation says that this is how fast the PID loop runs, but how can that be if the FPGA loop in which the PID sub-vi is in is running faster than any setting I can use in the express settings?  My implementation of this worked fine when I was using integer math, but now that I've switched to FXP (which I would like to keep if at all possible), I can't tune the thing at all.  Running the loop slower makes things worse.  I've attached the code for review.  Pardon the casting from FXP to FXP but I do this so the resolution (after doing math functions) doesn't eat up all the resources on the FPGA.  I have four of these loops on a 2M gate fpga and only using about 50% of the slices . . .  The point of the program is the hold the resistance of an RTD (as it heats up, the resistance changes - I'd like to drive up the resistance by say 25% and hold it there - getting there as fast as possible is what I need to do).

 

Thanks in advance.

 

Tommy R.

><><><><><><
Tommy R.
><><><><><><
Download All
0 Kudos
Message 1 of 12
(3,782 Views)

Hi Tommy,

 

You need to make sure the sampling time Ts in the configuration page matches exactly the rate your FPGA loop is running. You should be able to type in 40e-6 in that field.

 

The other thing that looks suspicious is the number of FXP conversions, especially from the integer DA local variables. The To Fixed-Point conversion respects the original value, so the resulting FXP number will have a fractional part of zero. I'm not sure if that is what you intended or not. I would recommend converting the integer parameters immediately to FXP, then doing all further arithmetic in FXP. If you were using integers to represent scaled values and want to retain the same bit pattern in FXP, you will need to do a "cast" by using Number to Boolean Array and Boolean Array to Number to reinterpret the integer as a FXP number.

 

I would also recommend being very explicit about your overflow handling and rounding, making as many operations lossless as possible. Then highlight (comment) those few that will be reducing the integer or fractional wordlength. Also explicitly convert to the supported input type for PID (ie, with a maximum word length of 16 bits) to avoid the coercion dots on the input. Those dots imply that a rounding operation is taking place in this case, but it is better to be explicit about it with a conversion out front just so there's no ambiguity.

 

Hope that helps,

 

Jim

0 Kudos
Message 2 of 12
(3,774 Views)

Thanks Jim.  Thanks for the quick reply.

 

The auto-formatting on the PID inputs had me worried that I couldn't go below 0.001 s . . .  I'll try with the 40e-6 setting.  Nice!  The initial setpoint values also auto format . . .

 

The DA variables are measured resistances (entered on the RT host program - they are part of a resistor network) where the fractional part doesn't really matter - I cast to FXP and do math (using the resistances and the two measured voltages) to calculate the resistance and current of the RTD (so much better than integer math).  When I multiply two FXP numbers , I cast back to something reasonable (16,11).  Before, when I didn't do this, the program wouldn't compile because I ran out of FXP space.  With the coversion back to reasonable FXP resolution (remember I have four of these loops running), the compile goes smoothly (and I have plenty left . . . .).

><><><><><><
Tommy R.
><><><><><><
0 Kudos
Message 3 of 12
(3,769 Views)

there are some conceptual problems with your approach to using fixed point.  I can help if you have some more info.

what is the range of R4 and Ra.  What is the expected range of AI0, AI2.  (what module are you using.)

 

 

Stu
0 Kudos
Message 4 of 12
(3,755 Views)

I have a two voltage dividers connected to the output of an amplifier circuit (with a gain of 2, 0-10V from the cRIO translates to 0-20V out of the amplifier circuit).  R1 and R2 are on one side (I measure the voltage at R2, AI0 is set to +/- 1V), and Rv (basically an RTD that changes resistance) and R4 (I measure the voltage at R4, again AI2 is set to 1V in the module).  Ra is calculated from the resistor network ((R1+R2)*R4)/R2) where Rv= Ra*(V2/V1) - R4 (I measure two voltages because I don't want to assume what the actual voltage is at the output of the amplifier).  So I can calculate Rv on the fly as I change voltage (I also run in a constant voltage mode, which is simple).  For the PID part, I want to target a Resistance for Rv and hold that resistance by modulating the input voltage of the amplifier.  This technique is not the prettiest (PWM would also work), but we have another reason to do it this way . . . . The device that changes resistance is sensitive to airflow, so the PID is also necessary to hold the particular resistance in flow conditions.

 

This setup works on an older program (LV 8.2) using all integer math.  I'm trying to switch over to using the FXP on the FPGA to free up memory on the controller for other functionality (my controller is a 9073).  I use a 9205 for AI and a 9263 for AO.  I can do the calculations more effectively on the FPGA side with FXP (compared to the tricky integer multiplications and divisions previously).

 

R1, R2, and R4 are all fixed (100k, 2.2k, and 10 ohm, respectively).  Ra is a constant that gets sent in to the FPGA to use in the calculation of Rv and Current through Rv.  Rv is nominally 150 ohm and increases to 200-250 ohm during load (0-20V applied).  We also have devices that are 1000 ohm (changing up to about 1200 ohm) in which case R4 is replaced with a 5W 25 ohm resistor.

 

Thanks, Stu!

Message Edited by trouinky on 03-23-2009 09:41 PM
><><><><><><
Tommy R.
><><><><><><
0 Kudos
Message 5 of 12
(3,746 Views)
While I resolved the fixed point issues with your calculations, there are still issues with the fixed point PID implementation (loss of resolution).  I will research a bit more before posing a solution.
Stu
0 Kudos
Message 6 of 12
(3,664 Views)

attached is an example project with PID and my attempt at recoding your code.  it will run under windows so you can debug and probe values.  see the comments in the code.

Good luck.

 

Stu
0 Kudos
Message 7 of 12
(3,620 Views)

In the interim, I started working on updating my code with the integer-based implementation, but will check out your sample program and see what happens.  Would certainly like to stay in the fixed-point mode from now on, given that the math is so much simpler (and more accurate).

 

Thanks for the input either way, Stu.

 

Tommy R.

><><><><><><
Tommy R.
><><><><><><
0 Kudos
Message 8 of 12
(3,587 Views)
The code that I send is a hybrid between fixed point and integer.  it performs the calculations using fixed point and converts to integer for the PID.  Hope it helps.
Stu
0 Kudos
Message 9 of 12
(3,582 Views)

I was thinking since my integer implementation was working that that would be a good idea, but since I didn't get far with the FXP version, I'd just go back to integer.  I did this today and everything works fine (PID tuning is another story . . . ).  I'm anxious to try your FXP to INT solution.  Keeping the math as accurate as possible seems to be pretty important in targeting single degrees of temperature (what we're trying to do with these specialty RTD's).

 

I'll certainly let you know how it goes . . .

 

TR

Message Edited by trouinky on 03-26-2009 04:19 PM
><><><><><><
Tommy R.
><><><><><><
0 Kudos
Message 10 of 12
(3,579 Views)