Post Go back to editing

AD5940 sequencer EDA + voltage measurements

Hello,

I'd like to use the AD5940 sequencer to make impedance measurements (CE/SE) in parallel with voltage measurements (AIN0-3). 

impedance measurements voltage measurements
pins CE, SE AIN0-3
sample frequency 1 kHz ~1 Hz
ODR 4 Hz ~1 Hz

I'm basing the impedance measurements on the EDA example. Is there a good strategy for working in additional measurements with regards to power consumption and juggling 4 different low data-rate ADC channel readings?

I'm thinking of inserting the voltage measurements into the impedance measurement readout ISR - reconfiguring the device for a voltage measurements and reading each pin in turn, then running the impedance measurement configuration setup again. But not sure if this will interfere with impedance measurements running in the background off the wakeup timer and sequencer.

This is a pretty high-level question, but strategic advice would be appreciated!

Parents
  • Hi,

    If you just want parallel impedance and voltage measurements, you may choose the 4-Wire BIA project.

    Refer to 4-Wire BIA section of AN-1557: Implementing the AD5940 and AD8233 in a Full Bioelectric System | Analog Devices

    Impedance measurement is done between CE0/AIN1 

    and voltage measurement is done between AIN2/AIN3.

  • Thank you, this is a good reference!

    This example seems to store DFT measurements of both measured current and voltage. However, I would like to only use DFT measurements for impedance and do raw DC voltage measurements separately. Would the following changes be appropriate towards this end?

    Original code from AppBIASeqMeasureGen():

      AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N);
      AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bTRUE);  /* Enable Waveform generator, ADC power */
      AD5940_SEQGenInsert(SEQ_WAIT(16*50));
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE);  /* Start ADC convert and DFT */
      AD5940_SEQGenInsert(SEQ_WAIT(WaitClks));  /* wait for first data ready */  
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG|AFECTRL_ADCPWR, bFALSE);  /* Stop ADC convert and DFT */
    
      AD5940_ADCMuxCfgS(ADCMUXP_AIN3, ADCMUXN_AIN2);
      AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bTRUE);  /* Enable Waveform generator, ADC power */
      AD5940_SEQGenInsert(SEQ_WAIT(16*50));  //delay for signal settling DFT_WAIT
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE);  /* Start ADC convert and DFT */
      AD5940_SEQGenInsert(SEQ_WAIT(WaitClks));  /* wait for first data ready */
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG|AFECTRL_ADCPWR, bFALSE);  /* Stop ADC convert and DFT */

    Modified code for AppBIASeqMeasureGen():

      AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N);
      AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bTRUE);  /* Enable Waveform generator, ADC power */
      AD5940_SEQGenInsert(SEQ_WAIT(16*50));
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE);  /* Start ADC convert and DFT */
      AD5940_SEQGenInsert(SEQ_WAIT(WaitClksImp));  /* wait for first data ready */  
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG|AFECTRL_ADCPWR, bFALSE);  /* Stop ADC convert and DFT */
    
      AD5940_ADCMuxCfgS(ADCMUXP_AIN3, ADCMUXN_AIN2);
      AD5940_AFECtrlS(AFECTRL_ADCPWR, bTRUE);  /* Enable ADC power */
      AD5940_SEQGenInsert(SEQ_WAIT(16*50));  // Delay for signal settling DFT_WAIT
      AD5940_AFECtrlS(AFECTRL_ADCCNV, bTRUE);  /* Start ADC convert */
      AD5940_SEQGenInsert(SEQ_WAIT(WaitClksVolt));  /* wait for first data ready */
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG|AFECTRL_ADCPWR, bFALSE);  /* Stop ADC convert and DFT */

    Thank you!

Reply
  • Thank you, this is a good reference!

    This example seems to store DFT measurements of both measured current and voltage. However, I would like to only use DFT measurements for impedance and do raw DC voltage measurements separately. Would the following changes be appropriate towards this end?

    Original code from AppBIASeqMeasureGen():

      AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N);
      AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bTRUE);  /* Enable Waveform generator, ADC power */
      AD5940_SEQGenInsert(SEQ_WAIT(16*50));
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE);  /* Start ADC convert and DFT */
      AD5940_SEQGenInsert(SEQ_WAIT(WaitClks));  /* wait for first data ready */  
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG|AFECTRL_ADCPWR, bFALSE);  /* Stop ADC convert and DFT */
    
      AD5940_ADCMuxCfgS(ADCMUXP_AIN3, ADCMUXN_AIN2);
      AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bTRUE);  /* Enable Waveform generator, ADC power */
      AD5940_SEQGenInsert(SEQ_WAIT(16*50));  //delay for signal settling DFT_WAIT
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE);  /* Start ADC convert and DFT */
      AD5940_SEQGenInsert(SEQ_WAIT(WaitClks));  /* wait for first data ready */
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG|AFECTRL_ADCPWR, bFALSE);  /* Stop ADC convert and DFT */

    Modified code for AppBIASeqMeasureGen():

      AD5940_ADCMuxCfgS(ADCMUXP_HSTIA_P, ADCMUXN_HSTIA_N);
      AD5940_AFECtrlS(AFECTRL_WG|AFECTRL_ADCPWR, bTRUE);  /* Enable Waveform generator, ADC power */
      AD5940_SEQGenInsert(SEQ_WAIT(16*50));
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT, bTRUE);  /* Start ADC convert and DFT */
      AD5940_SEQGenInsert(SEQ_WAIT(WaitClksImp));  /* wait for first data ready */  
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG|AFECTRL_ADCPWR, bFALSE);  /* Stop ADC convert and DFT */
    
      AD5940_ADCMuxCfgS(ADCMUXP_AIN3, ADCMUXN_AIN2);
      AD5940_AFECtrlS(AFECTRL_ADCPWR, bTRUE);  /* Enable ADC power */
      AD5940_SEQGenInsert(SEQ_WAIT(16*50));  // Delay for signal settling DFT_WAIT
      AD5940_AFECtrlS(AFECTRL_ADCCNV, bTRUE);  /* Start ADC convert */
      AD5940_SEQGenInsert(SEQ_WAIT(WaitClksVolt));  /* wait for first data ready */
      AD5940_AFECtrlS(AFECTRL_ADCCNV|AFECTRL_DFT|AFECTRL_WG|AFECTRL_ADCPWR, bFALSE);  /* Stop ADC convert and DFT */

    Thank you!

Children
  • Hi,

    The above change will not help.

    You may add a printf line to AppBIADataProcess() as below:

    static AD5940Err AppBIADataProcess(int32_t * const pData, uint32_t *pDataCount)
    {
      uint32_t DataCount = *pDataCount;
      uint32_t ImpResCount = DataCount/4;
    
      fImpPol_Type * const pOut = (fImpPol_Type*)pData;
      iImpCar_Type * pSrcData = (iImpCar_Type*)pData;
    
      *pDataCount = 0;
    
      DataCount = (DataCount/4)*4;/* We expect RCAL data together with Rz data. One DFT result has two data in FIFO, real part and imaginary part.  */
    
      /* Convert DFT result to int32_t type */
      for(uint32_t i=0; i<DataCount; i++)
      {
        pData[i] &= 0x3ffff; /* @todo option to check ECC */
        if(pData[i]&(1<<17)) /* Bit17 is sign bit */
        {
          pData[i] |= 0xfffc0000; /* Data is 18bit in two's complement, bit17 is the sign bit */
        }
      }
      for(uint32_t i=0; i<ImpResCount; i++)
      {
        iImpCar_Type *pDftVolt, *pDftCurr;
    
        pDftCurr = pSrcData++;
        pDftVolt = pSrcData++;
        float VoltMag,VoltPhase;
        float CurrMag, CurrPhase;
    
        VoltMag = sqrt((float)pDftVolt->Real*pDftVolt->Real+(float)pDftVolt->Image*pDftVolt->Image);
        VoltPhase = atan2(-pDftVolt->Image,pDftVolt->Real);
        CurrMag = sqrt((float)pDftCurr->Real*pDftCurr->Real+(float)pDftCurr->Image*pDftCurr->Image);
        CurrPhase = atan2(-pDftCurr->Image,pDftCurr->Real);
        
        printf("VMag: %f Volts , VPhase: %f \n",VoltMag,VoltPhase*180/MATH_PI);
    
        VoltMag = VoltMag/CurrMag*AppBIACfg.RtiaCurrValue[0];
        VoltPhase = VoltPhase - CurrPhase + AppBIACfg.RtiaCurrValue[1];
    
        pOut[i].Magnitude = VoltMag;
        pOut[i].Phase = VoltPhase;
        
      }
      *pDataCount = ImpResCount; 
      /* Calculate next frequency point */
      if(AppBIACfg.SweepCfg.SweepEn == bTRUE)
      {
        AppBIACfg.FreqofData = AppBIACfg.SweepCurrFreq;
        AppBIACfg.SweepCurrFreq = AppBIACfg.SweepNextFreq;
    		AppBIACfg.RtiaCurrValue[0] = AppBIACfg.RtiaCalTable[AppBIACfg.SweepCfg.SweepIndex][0];
        AppBIACfg.RtiaCurrValue[1] = AppBIACfg.RtiaCalTable[AppBIACfg.SweepCfg.SweepIndex][1];
        AD5940_SweepNext(&AppBIACfg.SweepCfg, &AppBIACfg.SweepNextFreq);
      }
      return AD5940ERR_OK;
    }

    This way, comport displays the voltage across AIN2 and AIN3 

    and impedance across CE0 and AIN1.

  • Hi Akila,

    You show how to display the readings - this is clear, thanks.

    I would like to know how to change the voltage measurement across AIN2 and AIN3 from AC to DC. I do not want to do DFT processing of the measurement, but rather display the original DC voltage measurement. Will the modifications to the code as shown above do this?

  • Hi,

    This is not possible with one project

    as the fifo configuration done in  AD5940PlatformCfg() defines the fifo source. Only one source can be chosen for one project.

    But you can always concatenate two projects such as AD5940_impedance and AD5940_Amperometric.

    This way you can call AD5940PlatformCfg() two times,

    one with FIFOSRC_DFT as the fifo source (for impedance),

    and another with FIFOSRC_SINC2NOTCH as fifo source (for voltage output).