Post Go back to editing

Interfacing & configuring ADAS3022

I am using this ADC first time & finding difficult to get desired result.

I wish to use it in basic sequencer mode, 4 differential channel pairs i.e. IN0/IN1 to IN6/IN7, +-20.48V. I am configuring the Configuration Register by the value 0 x F7FF.

D0 is CS, D1 is SCLK & D2 is ADC Data

the code for initialize is :

  digitalWrite(CS_ADC , LOW);
  digitalWrite(CNV_ADC ,HIGH);
  digitalWrite(CNV_ADC ,LOW);  
  x = SPI.transfer(0xF7);;
  y = SPI.transfer(0xFF);;   
  digitalWrite(CS_ADC , HIGH);
    
  digitalWrite(CS_ADC , LOW);
  x = SPI.transfer(0);
  y = SPI.transfer(0);   
  digitalWrite(CS_ADC , HIGH);
 
  digitalWrite(CS_ADC , LOW);
  x = SPI.transfer(0);
  y = SPI.transfer(0);
  digitalWrite(CS_ADC , HIGH);

  digitalWrite(CS_ADC , LOW);
  x = SPI.transfer(0);
  y = SPI.transfer(0);
  x = SPI.transfer(0);
  y = SPI.transfer(0);
  x = SPI.transfer(0);
  y = SPI.transfer(0);
  x = SPI.transfer(0);
  y = SPI.transfer(0);
  x = SPI.transfer(0);
  y = SPI.transfer(0);
  digitalWrite(CS_ADC , HIGH);

I didn't find any example/timing diagram for this mode. however after a bit trial & error I am seeing this value got configured as shown in attached screenshot of initializing ADC.But during periodic data read I do not wish to change the configuration & read only data of 4 channels. So for that reading I am sending only 0x0000 over SPI & seeing the configuration getting changed to 0 x 77FF instead of 0 x F7FF.

D0 is CS, D1 is SCLK & D2 is ADC Data

The code for reading sequentially is :

    digitalWrite(CS_ADC,LOW);     
    digitalWrite(CNV_ADC ,HIGH);
    digitalWrite(CNV_ADC ,LOW);
    dummy  = SPI.transfer(0);
    dummy  = SPI.transfer(0);
    digitalWrite(CS_ADC,HIGH);    
    
    digitalWrite(CS_ADC,LOW);  
    dummy  = SPI.transfer(0);
    dummy  = SPI.transfer(0);
    digitalWrite(CS_ADC,HIGH);    
    
    digitalWrite(CS_ADC,LOW);  
    dummy  = SPI.transfer(0);
    dummy  = SPI.transfer(0);
    digitalWrite(CS_ADC,HIGH);

    digitalWrite(CS_ADC,LOW);          
    msb[0] = SPI.transfer(0);
    lsb[0] = SPI.transfer(0);   
    
    msb[1] = SPI.transfer(0);
    lsb[1] = SPI.transfer(0);       
    
    msb[2] = SPI.transfer(0);
    lsb[2] = SPI.transfer(0);   
    
    msb[3] = SPI.transfer(0);
    lsb[3] = SPI.transfer(0);   
    
    dummy  = SPI.transfer(0);
    dummy  = SPI.transfer(0);     
    
    digitalWrite(CS_ADC,HIGH);

The problem I am facing is incorrect values, wrong PGA etc. Full count i.e. 7FFF is shown at 7V, & at 3V the count is around 0C22. Since the host is slower reading is at low conversion speeds. If anybody can help let me know.



ADC Count mentioned.
[edited by: NBhange674 at 7:16 AM (GMT 0) on 23 Apr 2019]
Parents
  • NBhange674,

    First of all there are a couple of things that might be going on here so lets try 1 thing at a time.

    1) For the configuration you have provided to the part you will require 17 clocks to output all the data so first thing I would suggest is change the LSB to a 0.

    2) The ADAS3022 only produces one ADC output result per conversion period and the results in the data register are only valid after the first conversion.  Thus you must either wait for busy to go low or otherwise add a delay to your code between when you assert CNV and when you send the serial data transfer.   For example.

    //Write desired configuration

    digital_write(CNV,HIGH)

    digital_write(CNV,LOW)

    delaymicroSeconds(1); // wait for conversion to end.

    digital_write(CSB,LOW);

    x = spi.transfer16(0xF7FE);   //SK - Modified CPHA to ensure data read back in 16 clocks.

    digital_write(CSB,HIGH);

    //Repeat the following twice to load configuration into memory. 

    digital_write(CNV,HIGH)

    digital_write(CNV,LOW)

    delaymicroSeconds(1); //wait for conversion to end.

    digital_write(CSB,LOW);

    x = spi.transfer16(0x0000);

    digital_write(CSB,HIGH);

    // At this point you should now have the part configured and be able to read back data consistently

    // Continue to only send CFG = 0x0000 to avoid resetting the sequencer.

    3) If you desire to read back the configuration each time simply add another x= spi.transfer16(0x0000) after each data word write and you should see 0x77FE read back.  This is because the MSB is automatically stripped off by the ADAS3022 as it's only purpose is to indicate that the configuration should be updated.

    Try running the code as I've described above...check my syntax as I've only just provided pseudocode based on my assumption you are using the Arduino IDE and looked at the command reference (didn't actually try it).

    Let me know how you make out and if you have any more questions.

    BR,


    Sk

  • Thank you for taking time to reply back & providing support.

    I do understand why config is read as 0x77FE instead of 0xF7FE. In my case ADC was getting configured correctly as it was showing 0x77FF instead of 0xF7FF.

    I have already ensured that busy signal is going low before starting reading without delay. The conversion pulse width is around 3.7 microsec so before conversion signal becomes low busy signal goes high to low, After that I am starting to read the data. For getting sufficient time to read all channels I have kept conversion cycle time period greater than 100 micro seconds.

    However I have update program as per your suggestion with config resistor 0xF7FE. But I am still not able to read the data correctly. The code for reading is given below & ADC signal waveform is attached. All 4 channels are shorted & the data read is not correct but configuring value on fifth read is matching. The following waveform are immediately read after configuration.

    But in next reading cycle as per code given below the fifth reading cycle does not produce correct configuration value. The waveform from 1st to fifth read cycle is shown as given below:

    The code for reading is as follows.

      digitalWrite(CNV_ADC ,HIGH);
      digitalWrite(CNV_ADC ,LOW);  
      delayMicroseconds(1); // wait for conversion to end.
      digitalWrite(CS_ADC,LOW);  
      v[0]   = SPI.transfer16(0);
      v[1]   = SPI.transfer16(0);
      v[2]   = SPI.transfer16(0);
      v[3]   = SPI.transfer16(0);
      dummy  = SPI.transfer16(0); 

    Waiting for reply. Hope somebody will resolve it.

  • NBhange264,

    To clarify, because you are using the ADAS3022 you will only ever get 1 channel result and 1 configuration result per CNV pulse.   Thus your transactions v[2], v[3] and dummy only create a circular buffer access where you will repeatedly get the same data.

    Let's try this to make sure we start from a known starting point, I'm going to assume you have access to the PD and RESET pins as well.

    // House Keeping to make sure signals are where we want them.

    digitalWrite( PD_ADC, LOW );

    digitalWrite( CS_ADC, HIGH);

    digitalWrite( RESET_ADC,LOW);

    // Reset Device

    digitalWrite(RESET_ADC, HIGH);

    digitalWrite(RESET_ADC, LOW);

    // Configure Device

    digtalWrite(CNV_ADC, HIGH);

    digitalWrite(CNV_ADC,LOW);

    digitalWrite(CS_ADC, LOW);

    x = SPI.transfer16(F7FE);

    digitalWrite(CS_ADC, HIGH);

    //DUMMY CONVERSIONS

    digtalWrite(CNV_ADC, HIGH);

    digitalWrite(CNV_ADC,LOW);

    digtalWrite(CNV_ADC, HIGH);

    digitalWrite(CNV_ADC,LOW);

    // READBACK CFG, Check Valid - Also first Result of Channel 0-Channe1 Pair

    digitalWrite(CS_ADC, LOW)

    data_pair0_1 = SPI.transfer16(0);

    cfg_check = SPI.transfer16(0);

    digitalWrite(CS_ADC, HIGH);

    // CONVERT CHANNEL 2/3 Pair and Read back

    digtalWrite(CNV_ADC, HIGH);

    digitalWrite(CNV_ADC,LOW);

    digitalWrite(CS_ADC, LOW)

    data_pair2_3 = SPI.transfer16(0);

    digitalWrite(CS_ADC, HIGH);

    // CONVERT CHANNEL 4/5 Pair and Read back

    digtalWrite(CNV_ADC, HIGH);

    digitalWrite(CNV_ADC,LOW);

    digitalWrite(CS_ADC, LOW)

    data_pair4_5 = SPI.transfer16(0);

    digitalWrite(CS_ADC, HIGH);

    // CONVERT CHANNEL 6/7 Pair and Read back

    digtalWrite(CNV_ADC, HIGH);

    digitalWrite(CNV_ADC,LOW);

    digitalWrite(CS_ADC, LOW)

    data_pair6_7 = SPI.transfer16(0);

    digitalWrite(CS_ADC, HIGH);

  • Thanks for the clarification.

    Unfortunately I don't have access to PD & Reset. Both are grounded.

    After correcting the code generating conversion pulse for each reading I am finding that analog input given to Channel 1/2 pair affecting channel reading of 3/4, 4/5, 6/7 equally though not as desired.  Whereas channel 1 data  is not changing.

    The analog input given as 1/2 : 5V , 2/3 : Short, 4/5 : Short, 6/7:Open

    In following fig CH:1(Yellow) is Busy signal, CH2(Red) is CNV signal.

  • NBhange674,

    Can you change the SPI mode to Mode 0 using the SPI.SPIsettings library function?  I'm curious to see if this isn't causing the issue.

  • Changing to Mode 0 results in more unstable readings though readings are not correct in both modes. Sharing sample readings sent via serial port for following analog input in both modes. Also shared schematic of ADC part. CH2/3, CH4/5 & CH6/7 are shorted & The negative input (2,3,5,7) is grounded whereas CH1 is given 5V.

     CH1: 5 V,     CH2: 0V,      CH3: 0V,       CH4: 0V,

    Mode 3
     CH1: 34724, CH2: 14696, CH3: 10644, CH4: 63212,
     CH1: 34728, CH2: 15554, CH3: 17674, CH4: 63214,
     CH1: 34726, CH2: 14814, CH3: 11390, CH4: 63214,
     CH1: 34802, CH2: 17814, CH3: 11500, CH4: 63202,
     CH1: 34778, CH2: 17652, CH3: 14834, CH4: 63204,

    Mode 0
     CH1: 17406, CH2: 10535, CH3: 10454, CH4: 64375,
     CH1: 17397, CH2: 10512, CH3: 9874,   CH4: 64376,
     CH1: 17385, CH2: 7350,  CH3: 5376,    CH4: 64376,
     CH1: 17410, CH2: 7343,  CH3: 5780,    CH4: 64375,
     CH1: 17398, CH2: 10890, CH3: 8904,    CH4: 64372,

  • NBhange674,

    I see an issue with your schematic.   Pins 33 and 34 (REF1 and REF2) MUST be connected together.  You are likely having issues with the ADC reference which may in part be related to your issue (see figures 63-65 in the datasheet).  Can you please try placing a jumper wire from C36 to C38 in your design to see if this changes the behavior.

    If everything is working (and I've aligned the data correctly) then you should get the following for each channel.

    Channel 0: ~16000 LSBs

    Channels 1-3: ~0 lsbs.  Note that formatting is two's complement so a small negative number may be closer to 65K codes.

    BR,

    SK

  • SK,

    You observed & pointed out correctly. It was a big mistake. It resolved the issue.

    Thanks a lot for the help & support.

    I am seeing Ch1 & Ch4 readings as per analog input but still CH2 & Ch3 readings are not correct.

     CH1: 5 V,     CH2: 0V,      CH3: 0V,       CH4: 0V,

     CH1: 16018, CH2: 15472, CH3: 15348, CH4: 6,
     CH1: 16014, CH2: 15472, CH3: 15370, CH4: 4,
     CH1: 16018, CH2: 15472, CH3: 15376, CH4: 8,
     CH1: 16018, CH2: 15474, CH3: 15376, CH4: 6,
     CH1: 16016, CH2: 15478, CH3: 15384, CH4: 6,

    I cross checked pcb traces to the ADC pins for CH2 & CH3. It's fine. What can be the reason?

    BR,

    NB

Reply
  • SK,

    You observed & pointed out correctly. It was a big mistake. It resolved the issue.

    Thanks a lot for the help & support.

    I am seeing Ch1 & Ch4 readings as per analog input but still CH2 & Ch3 readings are not correct.

     CH1: 5 V,     CH2: 0V,      CH3: 0V,       CH4: 0V,

     CH1: 16018, CH2: 15472, CH3: 15348, CH4: 6,
     CH1: 16014, CH2: 15472, CH3: 15370, CH4: 4,
     CH1: 16018, CH2: 15472, CH3: 15376, CH4: 8,
     CH1: 16018, CH2: 15474, CH3: 15376, CH4: 6,
     CH1: 16016, CH2: 15478, CH3: 15384, CH4: 6,

    I cross checked pcb traces to the ADC pins for CH2 & CH3. It's fine. What can be the reason?

    BR,

    NB

Children
  • NB,

    Can you please send scope captures of what you are observing?  This might help the analysis.  Including analog channels monitoring the input differential would be good as well.

    The one thing I noticed in your schematic is that your input filters have very low corners.  Is it possible that by the time you take the samples the input filter has not settled and thus the input acquires a non-zero value?   Not exactly sure what your test setup/procedure is like so probably just worth a peak at the input voltages to make sure nothing is contrary to your expectation

    One thing you could try is to extend the time between conversions to say a few milliseconds to see if the results don't settle out.   I will caution you that using ceramic capacitors that are non-NPO/COG type can have performance effects over temperature in terms on non-linearity so be sure to check for this as you continue to validate your design.

    Sean

  • SK,

    The conversion frequency is already slow around 100ms. All the channels are being read sequentially after this period.

    In testing setup a dc voltage of 5V from a calibrator is given to CH1 & other three channels differential input are shorted to ground, so I don't suspect the sampling & filtering time issue.  I agree on capacitors type & I assure you that COG types have been used.  I will try to provide you the waveform on Monday.

    Thanks for the inputs & help.

    NB

  • NB,

    I may be misinterpreting this statement you made.

    All the channels are being read sequentially after this period.

    Just to emphasize this point again, you will only get ONE conversion result per CNV toggle and only ONE result may be stored.  There is NOT internal storage to allow you to read more than the last result some time later.  As long as you are executing the code similar to what I provided on 22-May you should be okay. 

    I would just suggest putting some additional latency between the conversions themselves to see if this alleviates your issue.

    SK