Shop OBEX P1 Docs P2 Docs Learn Events
ADC Sampling Breakthrough - Page 49 — Parallax Forums

ADC Sampling Breakthrough

14647495152

Comments

  • TonyB_TonyB_ Posts: 2,099
    edited 2019-01-28 22:30
    cgracey wrote: »
    After some experimentation, I found that periodically clearing the first integrators in the Goertzel circuit, by temporarily switching from Sinc2 to Sinc1, and back to Sinc2, gets rid of the buildup problem.

    Does changing the mode always reset the integrators, so switch to Sinc1 can be followed immediately by switch back to Sinc2?
  • cgraceycgracey Posts: 14,131
    TonyB_ wrote: »
    cgracey wrote: »
    After some experimentation, I found that periodically clearing the first integrators in the Goertzel circuit, by temporarily switching from Sinc2 to Sinc1, and back to Sinc2, gets rid of the buildup problem.

    Does changing the mode always reset the integrators, so switch to Sinc1 can be followed immediately by switch back to Sinc2?

    Correct. During Sinc1 mode, the first integrators always hold the scaled sin and cosine, without accumulating them, like in Sinc2 mode.

    On each clock, the first integrators are added into the second integrators, which get cleared on GETXACC.
  • Bob Lawrence (VE1RLL)Bob Lawrence (VE1RLL) Posts: 1,720
    edited 2019-01-29 01:17
    @ cgracey
    After some experimentation, I found that periodically clearing the first integrators in the Goertzel circuit, by temporarily switching from Sinc2 to Sinc1, and back to Sinc2, gets rid of the buildup problem.

    The new Goertzel circuit allows up to 4 ADC input pins with selectable polarity for each. This is going to make relative measurements possible, among other things.

    In these videos, there is a stable 1MHz sine coming into one pin and a swept sine above and below 1MHz coming into another pin. The two pins are summed to form the input sample. The sample is then multiplied each clock by cosine and sine values which are accumulated and periodically converted to power (hypotenuse).

    For the Sinc2 video, I'm clearing the first integrators at the outset of each swept-sine measurement. You can see the resolving difference between Sinc1 and Sinc2 quite nicely.

    Thanks! for the video's Chip, that's very cool.
  • This is going to make relative measurements possible, among other things.

    I wonder what chip means by other things and What kind of other measurements may be possible ? :)


  • I've thought for a long time that the Goertzel hardware could be used for windowed ADC sampling. But it would be tricky if we wanted to reduce the sample rate by anything other than a power of 2. It could be done if we calculate exactly what steps the Goertzel hardware would use and we put our coefficeints at those locations in the look up table. But what if we don't want to decimate the ADC data by an integer?


    For example, if we want exactly 640 samples per line of NTSC video, we need a sampling rate of 10.06976MHz. Note that I'm ignoring the blanking interval.

    We could divide the 250MHz sysclock by 24.827 to meet our desires. The problem with doing that is we will have some intervals with 25 sysclocks between samples and some intervals with 24 sysclocks between cycles. This will affect our ADC accumulators because integrating for a longer time will result in a larger output value. Maybe we could compensate for that. One of the main lessons in this thread is that we need a window filter to get good performance from the P2 ADC. For demonstration, I'll use a triangular window. There may be other choices that perform better.

    goertzel-sample-points.png
    Early Sampling 
    sample number     1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25
    sample position   7  17  27  38  48  58  69  79  89  99 110 120 130 141 151 161 172 182 192 203 213 223 234 244 254
    window value      6  16  26  37  47  57  68  78  88  98 109 119 126 115 105  95  84  74  64  53  43  33  22  12   2
    
    Late Sampling
    sample number      1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24
    sample position   10  20  30  41  51  61  72  82  92 103 113 123 134 144 154 164 175 185 195 206 216 226 237 247
    window value       9  19  29  40  50  60  71  81  91 102 112 122 122 112 102  92  81  71  61  50  40  30  19   9
    
                      Sum   N samples
    Early Sampling    1577     25
    Late  Sampling    1575     24
    

    Despite having a different number of samples in the interval, the full scale gain doesn't change that much. The gain variance as the number of samples changes is reduced from 4.1% to .13%. Maybe we could compensate for the deviation in the number of samples per interval. But we still need a window function to get good performance from the ADC. The beauty is that a carefully chosen window function will compensate for fractional resampling automatically. All we need to do is program our desired sample rate into the streamer's frequency register.

    This is just a one point test, it's not always this good. The gain varies with the stating phase and the sampling frequency. Over all starting phases, the peak-to-peak gain deviation is .32%

    The P2 ADC video quality looks quite good. The test images are from a TV connected to the propeller's DAC. One is composite direct to the TV for reference. Note that 10.x MHz is a little bit low for the highest quality video. If Chip has added modes to use multiple pins in parallel, that should produce very good video when using 2 or 4 ADC pins.

    1920 x 1440 - 602K
    1920 x 1440 - 680K
    1920 x 1440 - 620K
    1200 x 900 - 29K
  • cgraceycgracey Posts: 14,131
    Saucy, we could use multiple pins in parallel with a common signal, summing their conversions. That could work with the scope mode, too. The biggest problem is that we have something like -3dB @1.5MHz on the ADC's analog front end.
  • potatoheadpotatohead Posts: 10,253
    edited 2019-08-24 20:52
    The standard sample is 13.500Mhz, and it's valid for NTSC and PAL. Most gear is running at that rate these days.

    Saucy, those captures are impressive!

  • cgraceycgracey Posts: 14,131
    Saucy, you could do this now on the V1 silicon: Run the NTSC baseband signal into four pins and sum their conversions, instead of just using one pin. You should get two more bits of quality that way.
  • evanhevanh Posts: 15,091
    The Goertzel function is new to me. I've got some learning to do.
    Prop2 Docs wrote:
    This mode uses the lookup RAM as a source of sine/cosine samples, such that bytes 3 and 2 must be unbiased signed sine and cosine values, and bytes 1 and 0 are biased (positive) sine and cosine values suitable for driving DACs. By incorporating DDS output with Goertzel input, many interactive real-world measurements can be made to determine things like time-of-flight and resonance.

    Question: I don't understand any general meaning of biased/unbiased. I suspect its meaning is situation dependant. You've labelled positive beside biased, is that what biased means there?

  • cgraceycgracey Posts: 14,131
    evanh wrote: »
    The Goertzel function is new to me. I've got some learning to do.
    Prop2 Docs wrote:
    This mode uses the lookup RAM as a source of sine/cosine samples, such that bytes 3 and 2 must be unbiased signed sine and cosine values, and bytes 1 and 0 are biased (positive) sine and cosine values suitable for driving DACs. By incorporating DDS output with Goertzel input, many interactive real-world measurements can be made to determine things like time-of-flight and resonance.

    Question: I don't understand any general meaning of biased/unbiased. I suspect its meaning is situation dependant. You've labelled positive beside biased, is that what biased means there?

    By "biased", I meant that the MSB is inverted, so that it ranges from $01..$FF, whereas unbiased would range from -$7F..+$7F.

    In the new silicon, all Goertzel LUT bytes need to be unbiased. When output to the DACs, the Goertzel hardware will flip the MSB of each byte, making it suitable for DAC output.
  • evanhevanh Posts: 15,091
    Ah, right, of course. Here I was thinking it was more complicated even when you've stated it's to match the DACs.
  • SaucySolitonSaucySoliton Posts: 481
    edited 2019-09-06 05:43
    cgracey wrote: »
    Saucy, you could do this now on the V1 silicon: Run the NTSC baseband signal into four pins and sum their conversions, instead of just using one pin. You should get two more bits of quality that way.

    Combining multiple ADC pins is going to be the last thing I do. Since I use the Goertzel hardware for the window filter, it's one ADC per cog. I'd need to keep all of the cogs exactly in sync, while I vary the sampling frequency to lock onto the video source. What I will try is switching the ADC to 3.16x mode. That may need attenuation and AC coupling. It should improve the quality by using as much of the full ADC range as practical. Maybe we could add a pre-emphasis circuit to equalize the rolloff of the ADC a bit.

    The most important part of video input is synchronization. I'm working on that now. Then perhaps color decoding, because we all like that! We can sample at 13.5MHz, but should we? If we use 12.273MHz we get square pixels for NTSC. I think having a monochrome decoder in one cog is a good goal.


    The code I posted could be adapted to a scope filter with a max sampling rate of perhaps 20MS.
  • I have an Idea about how to best utilize parallel ADCs. The last ~10 pages of this thread are about how the P2 ADC can't have an absolute accuracy better than 1/N where N is the number of clock cycles is the measurement interval. With windowing filters, we can get way more than N output levels. The problem is, at certain points in the ADC output range, like 1/3, the bitstream becomes too uniform to detect small changes in a short sampling time. That causes a non-linearity in the output at those points. It is thought that a second order or higher modulator would not be subject to this problem.

    If using 2 or more ADCs in parallel, it might be best to offset their ranges slightly. That way they both don't hit the non-linear points at the same time. The hardware would look like this:
    in-------o--|C]-----ADC 1
             |
            [R] 
             | 
             o--|C]-----ADC 2
             |
            [R]
             | 
    gnd------o----------GND
    
    AC coupling capacitors optional. For a video input, I would use them because 1. It's industry standard practice. 2. To run the ADCs in 3.16x mode, which results in a full-scale range of 1.56Vpp.
  • Nice idea. There is quite a difference between the adc ranges from one channel to another, as well as from one chip to another. Thats why its necessary to do the autocalibration using GIO and VIO. So, the offset may not be so important, if the two channels are naturally sufficiently different

    The 3.16x makes a lot of sense too
  • cgraceycgracey Posts: 14,131
    Yes, that's a good idea, Saucy.

    In the future I would like to expand the ADC converters so that they work independent of any pin mode. This way, they can always monitor a pin without dictating mode. Also, I would like to increase the number of integrators to 15, each differentiated in some way, like you've shown. That way, we can get 4 bits per clock, instead of one. I wish I could work on that right now.
  • @cgracey

    hello.
    I am not part of the loop on the smart pins. Would you be able to send me a commented code for of how to replicate the counters from the p1 so that I can
    understand how it works. I am attempting to port code from the p1 to the p2. The pins elude me. Please help
    \
    Thanks
  • evanhevanh Posts: 15,091
    Pilot,
    There is no direct replication using the smartpins, or anything in the prop2. The answer depends on the application.
  • cgraceycgracey Posts: 14,131
    pilot0315 wrote: »
    @cgracey

    hello.
    I am not part of the loop on the smart pins. Would you be able to send me a commented code for of how to replicate the counters from the p1 so that I can
    understand how it works. I am attempting to port code from the p1 to the p2. The pins elude me. Please help
    \
    Thanks

    Yeah, the better thing to do would be to determine what you want to accomplish and then figure out what smartpin mode looks appropriate, then ask some questions here.
  • @cgracey
    Sorry it took so long. I have been off of the forums for a couple of weeks. I am looking to replicate the counters so I can use some of the sensors that require the counters. I.E. if I remember correctly one of the gyros, inclinometers and others. I can send you the list. I was able to work the counters in P1 but now have to work with the smart pins. I was not in the loop on the fpga stuff.
  • @cgracey

    What kind of oscope signals will I look for to verify that I am using the smart pins correctly. Can you give me an example of nco with smart pins using a sensor.
    Thanks
  • jmgjmg Posts: 15,140
    pilot0315 wrote: »
    ... I am looking to replicate the counters so I can use some of the sensors that require the counters. I.E. if I remember correctly one of the gyros, inclinometers and others. I can send you the list...
    It may help to expand on what P1 Counter modes you were using ?
    eg if the P2 CTR was used in Pulse Density output as a DAC, you may instead use a real DAC on P2.
    Count gating, and increment on edge modes should have P2 equivalents.
    Logical actions on 2 pins were possible on P1, but not so directly supported on P2.
    P2 has other modes like frequency counting, where it can do quite a bit more than P1, and you can access a lot more than just 2 counters per COG.
  • evanhevanh Posts: 15,091
    pilot0315 wrote: »
    ... smart pins using a sensor.
    I'm guessing that wants a pulse measuring input. There is lots of those smartpins modes ... and some have too terse documentation. I haven't sussed them all out myself.
  • evanhevanh Posts: 15,091
    edited 2019-10-12 01:34
    Here's my most recent summary of the smartpin counter modes:
    SPM_CNT_QUAD	= %01011_0	' count: A-B quadrature encoder
    SPM_CNT_UP_ENA	= %01100_0	' count: A clock up, B enable
    SPM_CNT_DIR	= %01101_0	' count: A clock, B direction
    SPM_CNT_UP	= %01110_0	' count: A clock up
    SPM_CNT_UP_DN	= %01110_0	' count: A clock up, B clock down
    SPM_ACC_UP	= %01111_0	' accumulate: A up
    SPM_ACC_UP_DN	= %01111_0	' accumulate: A up, B down
    SPM_TIM_STEP	= %10000_0	' interval: of most recent step duration
    SPM_TIM_PULSE	= %10001_0	' interval: of most recent pulse duration
    SPM_TIM_MANY	= %10010_0	' interval: of X number of accum/pulses/steps
    SPM_TIMEOUT	= %10010_0	' interval: since most recent high/rise/edge, with X compare
    SPM_TIM_PULS	= %10011_0	' interval: of X number of A-B pulses/steps
    SPM_ACC_PULS	= %10100_0	' accumulate: pulses/steps, of X number of A-B pulses/steps
    SPM_TIM_OVER	= %10101_0	' interval: of A-B pulses/steps, for at least X duration
    SPM_ACC_OVER	= %10110_0	' accumulate: A-B pulses/steps, for at least X duration
    SPM_CNT_OVER	= %10111_0	' count: A-B pulses/steps, for at least X duration
    
    I've given each numerical mode number a name (suitable as a constant) according to how it functions but also kept the mode list in numerical order so they match the order in the prop2 document. Reading both the prop2 document and these one-liners should help categorise them for you.

    EDIT: The three general category descriptions.
    Count: Increment/decrement on a defined transition.
    Accumulate: Increment/decrement every clock cycle that a condition is true. The condition can alternate over time.
    Interval: Increment every clock cycle for the duration between two conditions or transitions.

    EDIT: Updated SPM_TIM_STEP and SPM_TIM_PULSE
    Also, SPM_TIM_A and SPM_TIM_PULS and SPM_ACC_PULS

    EDIT: I haven't got my head around the last three modes. They are likely incorrectly described.
    EDIT: Updated SPM_TIMEOUT and SPM_ACC_PULS
    EDIT: Updated SPM_TIM_OVER, SPM_ACC_OVER and SPM_CNT_OVER
    EDIT: Renamed SPM_TIM_A to SPM_TIM_MANY
  • evanhevanh Posts: 15,091
    edited 2019-10-10 01:51
    Chip! What's the story with the smartpin scope mode? That's managing four ADCs in parallel, with filtering, all in one smartpin! How can that not have bloated?

    EDIT: Not to mention a whole new set of buses added between smartpins and streamers. No wonder revB got bigger!


    EDIT2: Ah, I see, the opening description is a little misleading. The smartpin doesn't handle four ADCs. It's still four smartpins for four ADCs. It's explained further down how the streamer/cog does the grouping of four together via combining multiple RDPIN buses. Which also eliminates those extra buses I imagined.
  • evanhevanh Posts: 15,091
    Lol, I bet Wendy's seen it all before.
  • jmgjmg Posts: 15,140
    evanh wrote: »
    Here's my most recent summary of the smartpin counter modes:
    	SPM_TIM_STEP	= %10000_0		' interval: of one step
    	SPM_TIM_PULSE	= %10001_0		' interval: of one pulse
    
    To me that's still terse, and not helped by the P2 docs being terse too....
    Taking those 2 examples, P2 uses the wording
    %10000 = Time A-input states
    %10001 = Time A-input high states

    It says 'states' but does not clarify what a state actually is. To me, adding new words of step and pulse will only confuse users more.

    %10000 = Time A-input states I cannot quite fathom, but a bit clearer is

    %10001 = Time A-input high states
    Continuous high states are counted in clock cycles.
    Upon each high-to-low transition, the previous high duration count is placed in Z, and IN is raised.


    ie Sounds like a Gated Counter with Capture, H=CountEnable and =\_ is Capture. That gives a 1 whole period read time limit.
    not mentioned is what happens to Ctr on capture, and over-runs ?
    If Ctr clears on capture, over-run will drop a value, if Ctr does not clear, capture increments by t=H for every new capture, and users need to manage 'how many pulses' elsewhere.
    If previous is not read in time, does a new capture replace that, or get discarded ?
    Is there any way for the user to know they skipped a capture ?
  • evanhevanh Posts: 15,091
    The word "one" is relevant in my short description. It basically means most recent. So most recent step or pulse. That's quite short so I'll change to that ...

  • jmgjmg Posts: 15,140
    edited 2019-10-10 02:25
    Re these two,
    evanh wrote: »
    	SPM_TIM_PULS	= %10011_0		' interval: until X number of A-B pulses/steps
    	SPM_ACC_PULS	= %10100_0		' accumulate: A up, until X number of A-B pulses/steps
    
    I think they auto adjust to be whole periods, so that's an important word to have in any description.
    ie %10011 is Time captured over X whole A-B periods. (Time to read is X periods)
    %10100 is a gated version of that, A=H=Enable, so it gives a % of H time.

    in use, Alternating %10011 and %10100 can give PWM(duty) capture in a single Smart Pin, but could give lower precision specs than using 2 smart pins to capture X-Whole_Periods Time and % Time over the same X-periods. (eg RC Oscillator MCUs generating PWM, will have noise/drift added to the results)
    A Xtal generated PWM should be better, with sysclk sampling noise limited.

    Addit: The docs are vague around clear-on-capture ? Merely says "... and a new measurement begins"
    Also vague is if this is 'gapless' ? My guess is one period is consumed at each boundary, but it may be smart enough to capture & restart on the same edge, making capture X-Whole_Periods Time sums gapless and equivalent to real time. (with just a phase delay on the very first edge, after smart pin config/arming)
  • evanhevanh Posts: 15,091
    That's more detail than is suitable for a one-liner.

    The most important part of my list is the classification clarification of what the type of measurement is: count, accumulate or interval.
  • evanhevanh Posts: 15,091
    edited 2019-10-10 03:54
    I'll change all the "until"s to "of"s. It needs a little more thought when reading but is slightly more precise description.

    EDIT: Hmm, might revert that for the "X time" ones. Not sure, I'll double check ...

    EDIT2: Clarification on SPM_TIM_PULSE = %10001_0, it's not the whole pulse period but only the pulse duration. I've corrected the listing. The difference between this and step duration is pulse is only the true interval vs both true and false intervals with step.
Sign In or Register to comment.