Discrete time PID control

I've implemented a DSSS receiver in an FPGA. The code rate NCO is controlled by an early/late detector. The carrier NCO is controlled by a Costas Loop. I chose PI gain constants for the control loops by trial and error but would like to do it more scientifically by analysing stability using a Bode plot of open loop gain. I always do it this way for analogue PLLs; but I'm new to z-domain stability analysis.

TimW - I bought your book; but, to be honest, found it quite heavy going. Nevertheless, adapting some code from the accompanying CD, I came up with this Scilab script:

kPD = 2^20; kP = 2^(41-64); kI = 2^(15-64); kNCO = 10000; G = -kPD * (kP + kI/(%z-1)) * kNCO / (%z-1); G.dt = 1e-3; scf(0); clf; bode(G);

The resulting Bode plot never even passes through unity gain! So is the system unconditionally stable? Here's a simplified version of the FPGA code:

`define KP 41 `define KI 15

reg [63:0] phase, rate; // 64 places after the binary point reg signed [31:0] err; // = Early - Late

always @ (posedge clk) // 10 MHz if (millisecond) begin phase

Reply to
Andrew Holme
Loading thread data ...

Is 'err' quantized to two values, early or late bang-bang style, or is it some finer-grain time error signal?

John

Reply to
John Larkin

err is fine-grained: approx +/- 2^20

Actually, kPD slope should be 2*(2^20) per chip.

Reply to
Andrew Holme

There's several things wrong with this -- does the loop actually work?

Your gain is HUGE -- I'm seeing nearly 60dB of gain at Fs/2, which should guarantee wild Fs/2 oscillations.

kP / kI is 67 million some odd, which means your integrator doesn't start doing anything until Fs/67000000 or so -- that's a pretty low frequency for an integrator to kick in.

As a minor point, you're including the subtraction in the phase comparator, meaning that your phase shift criterion is 0 rather than 180

-- that's not how most folks do it, but there's a significant enough minority that do that I can't quibble _too_ much.

As another minor point, Scilab (and anything that uses polynomials for this sort of analysis) is vulnerable to numerical errors when the order of the system gets high. Using

-->G = kPD * tf2ss(kP + kI / (%z - 1)) * tf2ss(kNCO / (%z - 1));

dodges this (note that I'm using my preferred sign convention). It's not the issue here.

I'm not going to pick through that Verilog code for a complete model unless you pay me, but I know it's not matching the transfer function that you give. Here's some points that I can pick out:

  • If KP were 0, then phase
Reply to
Tim Wescott

Tim, thank you. I had applied that kNCO=10000 multiplier to both kI and kP. It should only be applied to kI for exactly the reason you have pointed out.

The following code is giving me a sensible looking Bode plot:

kPD = 2^20; kP = 2^(41-64); kI = 10000 * 2^(18-64); G = -kPD * (kP + kI/(%z-1)) / (%z-1); G.dt = 1e-3; scf(0); clf; bode(G);

I'm using `KI=18 in the latest FPGA. The rate was taking several seconds to settle.

Thanks for the free consultancy :-) I will study the book.

Reply to
Andrew Holme

The integrator shift of 15 certainly showed in the Bode plot as being insufficient for fast settling.

Note that with all-digital systems like this you can often push your system much harder than you would if you have physical components -- you don't have such inconveniences as unknown dynamics or gains that change. On the other hand, you have to make sure that your model really does match reality!!

--

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
Reply to
Tim Wescott

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.