Forums

[cross-post] dither generator on fpga

Started by alb June 28, 2014
Hi there,

we are measuring from a quadrature encoder the raw sine and cosine and 
need to extract the angular position [1]. The position is then fedback 
to a PID which drives a motor.

We've been told that dither may be efficient in removing spurious 
harmonics due to quantization errors which may affect the control loop 
only few days before pcb production, therefore the only possibility was 
to add few resistors from the FPGA to Vref used in the opamp which feeds 
the ADC. Noise generated from the 4 toggling pins of the FPGA will be 
injected right at the input of our ADC.

We met the deadline for the pcb production (great!), but unfortunately 
we just postpone the issue and moved it into the FPGA (imagine how happy 
was the fpga team!).

Now I have the following questions: 

1. how do I prove I need a dither generator? Indeed we didn't have even 
   the time to figure out if we really need it. Is there a dedicated 
   test I can perform which may undoubtly confirm the need?

2. how the dither generator noise spectrum should look like? I've read 
   about both in-band and out of band dither but I'm still confused.

3. any reference for such generators on FPGA? A long LFSR (say 64bit)
   and only 4 pin used might seem silly, but is simple. OTOH I read LFSR 
   do not provide random enough patterns therefore introducing other 
   issues.

Any help is appreciated.

Al

[1] by tracking demodulation.

-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
On Sat, 28 Jun 2014 14:39:49 +0000, alb wrote:

> Hi there, > > we are measuring from a quadrature encoder the raw sine and cosine and > need to extract the angular position [1]. The position is then fedback > to a PID which drives a motor. > > We've been told that dither may be efficient in removing spurious > harmonics due to quantization errors which may affect the control loop > only few days before pcb production, therefore the only possibility was > to add few resistors from the FPGA to Vref used in the opamp which feeds > the ADC. Noise generated from the 4 toggling pins of the FPGA will be > injected right at the input of our ADC. > > We met the deadline for the pcb production (great!), but unfortunately > we just postpone the issue and moved it into the FPGA (imagine how happy > was the fpga team!). > > Now I have the following questions: > > 1. how do I prove I need a dither generator? Indeed we didn't have even > the time to figure out if we really need it. Is there a dedicated > test I can perform which may undoubtly confirm the need?
Calculate the worst-case inaccuracy in position due to quantization errors. This will be at a point where one ADC is reading maximum or minimum, and the other one is reading close to it's center point. If that inaccuracy if small enough to not cause you problems, then you're golden. If you don't know how small an error you need, then you must analyze your control loop, or you must build the system and give it a whirl. As a rule of thumb, your allowed quantization step should be about 1/4 or less of the desired precision of the axis, and it must be small enough that the quantization noise going into the derivative term in your controller does not heat up your motor or final amplifier, or cause undue power drain. Also, look at the ADC data sheets. If the internal noise from the ADC is greater than 1 LSB (it usually is for ADCs of more than 14 bits or so) then you're getting dither generated for you for absolutely free. In that case you may need to oversample the ADCs and average their outputs anyway, to avoid noise issues.
> 2. how the dither generator noise spectrum should look like? I've read > about both in-band and out of band dither but I'm still confused.
That depends on how complicated you want to get. In general dither is only going to do you any good if you accompany it by oversampling and decimating. In that case you'd either like the dither to be out of band, which you can approximate pretty well with a sigma-delta modulator on the dither signal, or you'd like the dither to be periodic, in which case you'd sample the raw ADC synchronously with updating the dither, and you'd average the ADC readings and decimate synchronous with the periodicity of the dither.
> 3. any reference for such generators on FPGA? A long LFSR (say 64bit) > and only 4 pin used might seem silly, but is simple. OTOH I read LFSR > do not provide random enough patterns therefore introducing other > issues.
If you oversample by a factor of 16, and if your four FPGA pins go through weighting resistors to make a 4-bit DAC, then just count from 0 to 15 and repeat. Unless you're driving an RC filter to your Vref you won't be able to do better than that.
> [1] by tracking demodulation.
I would capture the correct number by doing an arctan of the ADC inputs. This has worked well for me in the past, in software. You'll probably want to calculate the arctan using CORDIC or some other FPGA-ish method, but that's a nit. -- Tim Wescott Control system and signal processing consulting www.wescottdesign.com
Hi Tim,

In comp.arch.fpga Tim Wescott <tim@seemywebsite.please> wrote:
[]
>> 1. how do I prove I need a dither generator? Indeed we didn't have even >> the time to figure out if we really need it. Is there a dedicated >> test I can perform which may undoubtly confirm the need? > > Calculate the worst-case inaccuracy in position due to quantization > errors. This will be at a point where one ADC is reading maximum or > minimum, and the other one is reading close to it's center point. If > that inaccuracy if small enough to not cause you problems, then you're > golden.
The precision we have on the position can be directly transformed into angular precision: A = A0 + A1*sin(2*pi*opd/lambda) B = B0 + B1*cos(2*pi*opd/lambda + psi) where A/B are the sine/cosine signals, opd is the optical path difference (position in nm), lambda is the optical frequency (1550 nm) and psi a phase shift. With a precision in position of 20nm we have to have a precision in the phase accumulator which is of the order of 20/1550*2*pi ~4 deg (.00022 radian). But it looks to me a bit too big as a precision on a very sensitive optical mechanism... According to my calculations the 4 deg error corresponds to a normalized signal (A0/B0 removed and A1/B1 renormalized) of nearly 10% full scale... I guess something is wrong in my calculations! I guess though precision is not the only factor to take into account. While I can drive the motor precisely, it does not mean that I drive it smoothly instead might be rather jerky if I allow spourious frequencies to get out.
> > If you don't know how small an error you need, then you must analyze your > control loop, or you must build the system and give it a whirl. As a > rule of thumb, your allowed quantization step should be about 1/4 or less > of the desired precision of the axis, and it must be small enough that > the quantization noise going into the derivative term in your controller > does not heat up your motor or final amplifier, or cause undue power > drain.
But how can I hit the quantization error? Shall I consider a particular frequency for my sine/cosine waveform? IIRC quantization errors show up especially in submultiple of the ADC sampling frequency.
> Also, look at the ADC data sheets. If the internal noise from the ADC is > greater than 1 LSB (it usually is for ADCs of more than 14 bits or so) > then you're getting dither generated for you for absolutely free. In > that case you may need to oversample the ADCs and average their outputs > anyway, to avoid noise issues.
That is a good hint. I have an ENOB of 11.1, so in principle I have less than 1LSB noise for both distortion and noise...
>> 2. how the dither generator noise spectrum should look like? I've read >> about both in-band and out of band dither but I'm still confused. > > That depends on how complicated you want to get. In general dither is > only going to do you any good if you accompany it by oversampling and > decimating.
We are sampling at 250KSps a signal which is from DC to 4KHz... I'm wondering even why we are sampling with such a rate. Anyway it seems that decimating may be easily achieved.
> In that case you'd either like the dither to be out of band, > which you can approximate pretty well with a sigma-delta modulator on the > dither signal, or you'd like the dither to be periodic, in which case > you'd sample the raw ADC synchronously with updating the dither, and > you'd average the ADC readings and decimate synchronous with the > periodicity of the dither.
Being out of band would save me additional logic I guess. Indeed I can make it such to be filtered by the tracking demodulator.
>> 3. any reference for such generators on FPGA? A long LFSR (say 64bit) >> and only 4 pin used might seem silly, but is simple. OTOH I read LFSR >> do not provide random enough patterns therefore introducing other >> issues. > > If you oversample by a factor of 16, and if your four FPGA pins go > through weighting resistors to make a 4-bit DAC, then just count from 0 > to 15 and repeat. Unless you're driving an RC filter to your Vref you > won't be able to do better than that.
wouldn't that harmonic be affecting my tracking demodulator?
> >> [1] by tracking demodulation. > > I would capture the correct number by doing an arctan of the ADC inputs.
This is something I'm also wondering. Offset and renormalization are steps which need to be done anyway, but instead of a tracking demodulator the atan may be very simple, no loop required, no cutoff frequency...just plain easy. What about if your signals have a small phase shift? Truth is that if the phase shift error induced is not that large I could throw away the demodulator and live with the arctan...
> This has worked well for me in the past, in software. You'll probably > want to calculate the arctan using CORDIC or some other FPGA-ish method, > but that's a nit.
We are doing this in hardware and indeed we could have a look at the performances of the CORDIC to be used in our demodulator. Up to now nobody really looked at how we could optimize the algorithm. Al