Shop OBEX P1 Docs P2 Docs Learn Events
A question about ADCs — Parallax Forums

A question about ADCs

I did a simple test with ADC and DAC. What I hear is a white noise at about -60 dB. DACs are silent: put 0 there and no noise can be hear so it is ADC which generate the noise.

This means I got only about 10 effective bits.

I used pins 0 and 1 ad inputs using cinch socketd on an accessory board.

Is it normal? Or I am doing something wrong here?

Also the input impedance is very high

Can it be set lower in the program or... add the external resistor at input?

' ADC and DAC


CON
_clkfreq        = 300000000
adcpinl         = 0
adcpinr         = 1
dacpinl         = 6
dacpinr         = 7


pub start()

coginit(7,@mixer,0)

cogstop(cogid())




DAT
              org
mixer         wrpin adc_config, #adcpinl              
              wxpin  #%10_1001, #adcpinl
              dirh   #adcpinl
              wrpin  adc_config, #adcpinr              
              wxpin  #%10_1001,  #adcpinr
              dirh   #adcpinr

              wrpin dac_config,#dacpinl
              wxpin a512,#dacpinl
              wrpin dac_config,#dacpinr
              wxpin a512,#dacpinr
              dirh  #dacpinl addpins 1

              setse1  #%001<<6 + adcpinl   


loop        
              rdpin x,#adcpinl
              rdpin y,#adcpinr

              sub x,diffx1
              add diffx1,x
              sub x,diffx2
              add diffx2,x

              sub y,diffy1
              add diffy1,y
              sub y,diffy2
              add diffy2,y
              shr x,#11
              shr y,#11
              wypin   x,#dacpinl
              wypin   y,#dacpinr

              waitse1                 'wait for new period

              jmp     #loop          'loop


adc_config      long    %0000_0000_000_100011_0000000_00_11000_0      
dac_config      long    %0000_0000_000_10111_00000000_01_00011_0       
diffx1          long    0
diffx2          long    0
diffy1          long    0
diffy2          long    0
affff           long    $FFFF
x               long    0
y               long    0
p1              long    0
p2              long    0
a512            long    512

Comments

  • pik33pik33 Posts: 2,350

    Now there is less noise. I have to understand how these ADCs work....

    DAT
                  org
    mixer         wrpin adc_config, #adcpinl              
                  wxpin  #%10_1001, #adcpinl
                  dirh   #adcpinl
                  wrpin  adc_config, #adcpinr              
                  wxpin  #%10_1001,  #adcpinr
                  dirh   #adcpinr
    
                  wrpin dac_config,#dacpinl
                  wxpin a512,#dacpinl
                  wrpin dac_config,#dacpinr
                  wxpin a512,#dacpinr
                  dirh  #dacpinl addpins 1
    
                  setse1  #%001<<6 + adcpinl   
    
    
    loop        
                  rdpin x,#adcpinl
                  rdpin y,#adcpinr
    
                  sub x,diffx1
                  add diffx1,x
                  sub x,diffx2
                  add diffx2,x
    
    
          '     
                  sub y,diffy1
                  add diffy1,y
                  sub y,diffy2
                  add diffy2,y
                  sar x,#9
                  sar y,#9
                  and x,a3ffff
                  and y,a3ffff
                  sar x,#2
                  sar y,#2
                  mul xx,#7
                  add xx,x
                  shr xx,#3
                  mul yy,#7
                  add yy,y
                  shr yy,#3
                  wypin   xx,#dacpinl
                  wypin   yy,#dacpinr
    
                  waitse1                 'wait for new period
    
                  jmp     #loop          'loop
    
    
    adc_config      long    %0000_0000_000_100011_0000000_00_11000_0      
    dac_config      long    %0000_0000_000_10111_00000000_01_00011_0       
    diffx1          long    0
    diffx2          long    0
    diffx3          long    0
    diffy1          long    0
    diffy2          long    0
    a3ffff           long    $3fFFF
    x               long    0
    xx long 0
    yy long 0
    y               long    0
    p1              long    0
    p2              long    0
    a512            long    512
    
    
  • cgraceycgracey Posts: 14,133
    edited 2021-02-16 04:56

    The simplest mode is 2^n-clock SINC2 sampling, set by 'WXPIN #%00_nnnn'.

    You don't even need to use those filteted ADC smart pin modes. If you do use them, your sample only becomes stable on the third sample from start.

    In some cases, I just use the count-highs smart pin mode. It gives you a good sample on the first measurement, but without any filtering.

    The 1x input mode has an impedance of ~540k to VIO/2. The 100x input mode has an impedance of ~5.4k over a 40 mV range.

  • evanhevanh Posts: 15,188
    edited 2021-02-16 06:44

    When using the "filtering" modes, be sure to use one of the workarounds for register size mismatch - https://forums.parallax.com/discussion/comment/1510074/#Comment_1510074

    EDIT: I now see you're ANDing after the SAR instructions. I'm not sure SAR is suitable there, although it may not matter because all extended bits are stripped by the AND anyway.

  • pik33pik33 Posts: 2,350
    edited 2021-02-16 07:17

    I applied this 5 higher bit mask, nothing changed.

    The noise depends on pin and CPU clock frequency. This is not linear: there are silent frequencies and noisier frequencies. The character of noise also changes with cpu frequency, and also non linear so I can't tell "higher (or lower) frequency noises less/more.

    Pin 0 is more silent than pin 1 in this environment. When the frequency is high (>300) and gain >1 a constant high frequency can be heared. At 200 MHz there is a strange, granular noise on pin 0

    To be continued :)

  • evanhevanh Posts: 15,188
    edited 2021-02-16 09:57

    Right, it makes no difference to your low noise issue but that mask you're now using is important to remove severe numerical glitches that only happen under some odd-ball case. It can definitely happen out of the blue without one of the preventative fixes.

  • pik33pik33 Posts: 2,350
    edited 2021-02-16 14:57

    @cgracey said:
    The simplest mode is 2^n-clock SINC2 sampling, set by 'WXPIN #%00_nnnn'.

    You don't even need to use those filteted ADC smart pin modes. If you do use them, your sample only becomes stable on the third sample from start.

    In some cases, I just use the count-highs smart pin mode. It gives you a good sample on the first measurement, but without any filtering.

    The 1x input mode has an impedance of ~540k to VIO/2. The 100x input mode has an impedance of ~5.4k over a 40 mV range.

    Yes, the 2^n sinc is the simplest: rdpin and nothing else. About the high impedance: I had a jack in one hand and a P2 board with adc->dac program running with only output connected in another hand: the music played out of the headphone jack :)

    How to combine "count highs" with adc?

  • evanhevanh Posts: 15,188

    @pik33 said:

    @cgracey said:
    In some cases, I just use the count-highs smart pin mode. It gives you a good sample on the first measurement, but without any filtering.

    How to combine "count highs" with adc?

    That's the plain single accumulator as per prop1 days. And can be called sinc1. It's present in the collection of counter modes of the smartpins:
    - For internal clocked: %01111 AND !Y[0] = Count A-input highs
    - For external clocked: %01100 = Count A-input positive edges when B-input is high

  • pik33pik33 Posts: 2,350
    edited 2021-02-17 10:52

    For audio applications, I got the best results (less noise) from the simplest solution. Noise dac noises less than pwm dac in this configuration. The ADC is supposed to be 14 bit in this configuration and it seems it is something like 14 bit: I didn't measure the noise level yet.
    I am thinking now about a noise shaper applied directly on adc raw bit stream to move the noise out of accoustic band before integrating anything. I don't know if it is possible or achievable on a P2.

    {{ ADC to DAC audio simplest example}}
    
    CON
    _clkfreq        = 361_267_200  '  44100x8192
    '_clkfreq       = 393_216_000  '  48000x8192, too high for a P2
    
    bank            = 0    ' accessory board at pin 0,
    
    adcpinl         = bank+0   ' input on cinch 0,1
    adcpinr         = bank+1
    dacpinl         = bank+6   ' output on headphone jack
    dacpinr         = bank+7
    
    
    pub start()
    
    coginit(0,@mixer,0)
    
    DAT
                  org
    mixer         wrpin adc_config, #adcpinl
                  wxpin  #%00_1101, #adcpinl
                  dirh   #adcpinl
                  wrpin  adc_config, #adcpinr
                  wxpin  #%00_1101,  #adcpinr
                  dirh   #adcpinr
    
                  wrpin dac_config,#dacpinl
                  wxpin #1,#dacpinl
                  wrpin dac_config,#dacpinr
                  wxpin #1,#dacpinr
                  dirh  #dacpinl addpins 1
    
                  setse1  #%001<<6 + adcpinl
    
    
    loop
                  rdpin x,#adcpinl
                  rdpin y,#adcpinr
                  shl x,#2
                  shl y,#2      
                  wypin   x,#dacpinl
                  wypin   y,#dacpinr
    
                  waitse1                 'wait for new period
    
                  jmp     #loop          'loop
    
    
    adc_config      long    %0000_0000_000_100011_0000000_00_11000_0
    dac_config      long    %0000_0000_000_10111_00000000_01_00010_0
    x               long    0
    y               long    0
    
    
  • TubularTubular Posts: 4,622
    edited 2021-02-17 11:10

    I wonder whether the high clock rates are affecting the ADC performance? Perhaps via self heating too?

    This thread (and paper) from RJSM might be worth a look
    https://forums.parallax.com/discussion/169602/characterizing-p2-eval-analog-performance

  • pik33pik33 Posts: 2,350
    edited 2021-02-17 12:07

    This ADc2DAC works for several hours now, no anomalies detected. P2 is cold, but it has near nothing to do, one cog waiting for ADC pin ready.
    The topic was interesting, this can partially explain why several clock frequencies gives less noise (PLL jitter) and why the noise DAC can noise less (the same LDO for ADC and DAC)

  • cgraceycgracey Posts: 14,133

    In our early experimentation with the ADCs, we found that 1/f noise was the one problem that we could not eliminate. Maybe you would have some ideas about how to improve things. Remember, there's no problem in using 2 or 4 ADCs, or even 8, at once, if you want higher resolution. Lots of strange things are possible.

  • Chip, can you please explain what we have to do about 1/f noise? I know it can't be avoided completely but can it at least be minimized? I've read somwhere that 1/f noise (as the name already tells) would become infinite at f=0Hz (DC) and long term offset drift can also be explained as 1/f noise.

    So if we make the sampling time longer or put a low pass filter over multiple samples, is there a limit where further filtering does not result in lower noise? Or is there an optimum where shorter sampling time would cause more quantisation noise and longer sampling time more 1/f noise?

  • cgraceycgracey Posts: 14,133

    It seems that shorter measurements are better, because there's less time involved.

  • pik33pik33 Posts: 2,350
    edited 2021-02-17 21:22

    For a noise free audio input we don't need 16bit absolute precision as the noise will be masked by louder parts of the music. What we need is to get rid of the noise in silent parts. These ADCs have a controlled gain, so maybe controlled switching between gains can do this. Or use 3 adcs, 1,10 and 100 x and combine their output together. Calibration problems may occur.

    About 70 dB SNR is what a good vinyl record can output. At this level maybe even a simple DNL solution can do the trick.

    So many ideas and still not enough knowledge.

Sign In or Register to comment.