This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Calculating phase offset using calibration resistors

Other Parts Discussed in Thread: MSP430FR4133, AFE4300

I am trying to accurately calculate phase of an RC network. From a couple of posts here (including my own) I realized that calibrating the phase offset everytime I use a new frequency might be the easiest thing to do.

I am using an MSP430FR4133 launchpad to control the AFE4300EVM. I got it working for the most part and I can read continuous impedance data from multiple frequencies without any issue (in the IQ mode). However, calculating the phase has been a bit challenging. So my current approach is to initialize all registers, set an initial frequency, set ISW and VSENSE MUX to read from the 100Ohm calibration resistors, read corresponding I and Q, clear ISW and VSENSE MUX, set ISW and VSENSE MUX to read from 750Ohm calibration resistor, increment frequency and repeat. My aim is to 1. Ensure I am able to read 750Ohms properly  and 2. Ensure that I can offset whatever phase is already there.

        // The command 'miiii?' makes the program enter into frequency sweep mode
        // iiii is the hex code for the ISW_MUX and VSENSE_MUX
        
        // The output takes the format - frequency, I_cali, Q_cali /n frequency,I_calc, Q_calc /n 
        
        else if (uartRxBuffer[uartRxRdBufPtr] == 'm')
        {
          int index = 0;
          initDRDY();
          
        // Get the output pins for I and V
          uartRxRdBufPtr++;
          if (uartRxRdBufPtr >= MAXRXBUF)
            uartRxRdBufPtr = 0;

          // Converts the ASCII bytes to Pin address.
          afe4300outputs = ascii2uint8(uartRxBuffer[uartRxRdBufPtr])<<12;
         
          uartRxRdBufPtr++;
          if (uartRxRdBufPtr >= MAXRXBUF)
            uartRxRdBufPtr = 0;
          afe4300outputs |= ascii2uint8(uartRxBuffer[uartRxRdBufPtr])<<8;
          
          uartRxRdBufPtr++;
          if (uartRxRdBufPtr >= MAXRXBUF)
            uartRxRdBufPtr = 0;
          afe4300outputs |= ascii2uint8(uartRxBuffer[uartRxRdBufPtr])<<4;
          
          uartRxRdBufPtr++;
          if (uartRxRdBufPtr >= MAXRXBUF)
            uartRxRdBufPtr = 0;
          afe4300outputs |= ascii2uint8(uartRxBuffer[uartRxRdBufPtr]);
          
          
          char afeStringData[8];
          
          // Set Initial frequency
          spiWrite(AFE4300_BCM_DAC_FREQ,0x0000);
          spiWrite(AFE4300_DEVICE_CONTROL2,0x0000);
          spiWrite(AFE4300_BCM_DAC_FREQ, frequencies[index]);
          spiWrite(AFE4300_DEVICE_CONTROL2, frequencies[index+1]);


          // When 's' is pressed the while loop exits
          while(UCA0RXBUF != 's'){
            
            // Select Calibration Resistor on PCB - CAL 100 is selected
            spiWrite(AFE4300_ISW_MUX, 0x0101);
            spiWrite(AFE4300_VSENSE_MUX, 0x0101);
            
            itoa(frequencies[index], &afeStringData[0], 10);

            uartTXByte(',');

            // Calibration
            // Set Peripheral to I 
            spiWrite(AFE4300_ADC_CONTROL_REGISTER2, ADC_REF_SEL_VREF | PERIPHERAL_SEL_BCM_I);         

            while(readADCFlag==0); // Wait till the interrupt
            readADCFlag = 0;
            P4OUT ^= BIT0;
            afe4300Data = spiRead(0);
            itoa(afe4300Data, &afeStringData[0], 10);

            uartTXByte(',');
                   
            // Set Peripheral to Q
            spiWrite(AFE4300_ADC_CONTROL_REGISTER2, ADC_REF_SEL_VREF | PERIPHERAL_SEL_BCM_Q);

            while(readADCFlag==0); // Wait till the interrupt
            readADCFlag = 0;
            P4OUT ^= BIT0;
            afe4300Data = spiRead(0);
            itoa(afe4300Data, afeStringData, 10);

            uartTXByte('\n');
            spiWrite(AFE4300_ISW_MUX, 0x0000);
            spiWrite(AFE4300_VSENSE_MUX, 0x0000);
            
            // Set Pins to required pinout 
            spiWrite(AFE4300_ISW_MUX, afe4300outputs);
            spiWrite(AFE4300_VSENSE_MUX, afe4300outputs);            
            itoa(frequencies[index], &afeStringData[0], 10);
            uartTXByte(',');

            // Calculation
            // Set Peripheral to I 
            spiWrite(AFE4300_ADC_CONTROL_REGISTER2, ADC_REF_SEL_VREF | PERIPHERAL_SEL_BCM_I);         

            while(readADCFlag==0); // Wait till the interrupt
            readADCFlag = 0;
            P4OUT ^= BIT0;
            afe4300Data = spiRead(0);
            itoa(afe4300Data, &afeStringData[0], 10);

            uartTXByte(',');
                   
            // Set Peripheral to Q
            spiWrite(AFE4300_ADC_CONTROL_REGISTER2, ADC_REF_SEL_VREF | PERIPHERAL_SEL_BCM_Q);

            while(readADCFlag==0); // Wait till the interrupt
            readADCFlag = 0;
            P4OUT ^= BIT0;
            afe4300Data = spiRead(0);
            itoa(afe4300Data, afeStringData, 10);

            uartTXByte('\n');
          
            index += 2;
            if (index>8) {index = 0;}
            // Write New Frequency
            spiWrite(AFE4300_BCM_DAC_FREQ,0x0000);
            spiWrite(AFE4300_DEVICE_CONTROL2,0x0000);
            spiWrite(AFE4300_BCM_DAC_FREQ, frequencies[index]);
            spiWrite(AFE4300_DEVICE_CONTROL2, frequencies[index+1]);

            
          }
          readADCFlag = 0;
          DRDYIEL();
          uartRxRdBufPtr = 0;
          uartRxWrBufPtr = 0;
          uartRxBufLength = 0;        
        }
    }  

When I use this code to collect data, I expected to see the data to fluctuate between what I normally see for 750Ohm and what I normally see for 100Ohm. Instead, the I and Q values are somewhere in between. The only reason I can think of why this would happen is if somehow the resistors are seen in parallel. But the I and Q values are not remotely close to 100Ohms for this to be true. Is there some other register I should program? I am not sure why this code does not work.

Typical I, Q values for 750 Ohm (Z_magnitude is not calibrated, it is calculated as sqrt(I^2 + Q^2), Phase = atan(Q/I))

Frequency, I, Q, Z_magnitude, Phase

8    7424    -3595    8248.624    -25.8381
16    7053    -5756    9103.645    -39.2181
32    7096    -2662    7578.883    -20.5631
64    8522    557    8540.183    3.7395
128    8198    -1405    8317.525    -9.7251
8    7363    -3580    8187.195    -25.9297
16    7041    -5752    9091.82    -39.2464
32    7120    -1438    7263.762    -11.4182
64    8630    1018    8689.835    6.7276
128    8074    2671    8504.335    18.305

Typical I,Q values for 100 Ohm

Frequency, I, Q, Z_magnitude, Phase

8    1049    -415    1128.107    -21.5845
16    994    -875    1324.259    -41.3569
32    1013    -188    1030.298    -10.5138
64    1235    130    1241.823    6.009
128    1137    355    1191.131    17.3397
8    1043    -417    1123.271    -21.7919
16    1045    484    1151.643    24.8516
32    1153    190    1168.55    9.3575
64    1262    186    1275.633    8.3842

Values with switching between two calibration resistors ( Odd rows have values from 100 Ohm resistor (calibration) and Even rows have test values (750 Ohm)).

Frequency, I, Q, Z_magnitude, Phase

8    4350    179    4353.681    2.3564
8    3798    -3733    5325.42    -44.5055
16    4386    -672    4437.182    -8.7108
16    3783    4010    5512.82    46.6685
32    4806    1426    5013.094    16.5263
32    4544    731    4602.423    9.139
64    5693    373    5705.206    3.7486
64    4645    1315    4827.551    15.8068
128    5432    725    5480.169    7.6022
128    3769    2499    4522.208    33.546
8    4369    260    4376.73    3.4057
8    3897    -3439    5197.435    -41.4276
16    4494    -1830    4852.312    -22.1566
16    3332    -5095    6087.795    -56.8163
32    3823    -1848    4246.226    -25.7987
32    4270    -1204    4436.498    -15.7467
64    5499    -181    5501.978    -1.8852
64    4586    1195    4739.137    14.6051
128    5421    697    5465.624    7.3266
128    3765    2474    4505.097    33.3091

  • Hi Mathews,

    Can you please share how calibration resistor are connected to the AFE4300?

    Regards,
    Prabin
  • Prabin,

    I am using the AFE4300EVM. Hence, I am using R58 (100 Ohm) and R56 (750 Ohm) as detailed in sbau201 (www.ti.com/.../sbau201.pdf)
  • Hi Mathews,

    If I understand correctly, you are able to measure the correct I/Q values for both the calibration resistors individually.
    You have problem with above code that does the switching of ISW_MUX/VSENSE_MUX, am I right ?

    Also what is the value of "afe4300outputs" in line 90 and 91?

    Regards,
    Prabin
  • Pravin,

    That is correct. I am using a GUI (on MATLAB) to communicate to send commands to the MSP430. In the example I noted,
    afe4300outputs = 0x0201 (connected to 750 Ohms, i.e R56).
    I tried to calibrate with resistors outside the evm too (using IOUTs from the J38 connectors in a bipolar configuration). This produced the same result. I can individually read everything, but cannot switch appropriately.
  • Hi Mathews,

    Can you please insert some delay (~ 300mS) between the moment you change the MUX (ISW_MUX and VSENSES) and read the ADC output?
    You also can try to adjust the delay and see how are the reading.
    The reason for this delay is 1.59Hz LPF at "OUTP_Q_FILT and OUTM_Q_FILT ( also OUTP_I_FILT and OUTM_I_FILT)" as shown in figure 8 of the datasheet.
    You can also manually measure the volatge across OUTP_Q_FILT and OUTM_Q_FILT ( also OUTP_I_FILT and OUTM_I_FILT) to make sure the MUX ( ISW_MUX and VSENSE) are switched correctly.

    Regards,
    Prabin
  • Prabin,

    Thank you for helping me out with this. I can report that adding a 500ms delay fixed the problem at an ADC rate of 16SPS. Could you explain how you came up with the ~300ms delay value? I couldn't quite understand how this was relevant to the LPF. Is it the settling time?

    However, this made the overall data collection too slow for my application. I managed to figure out how to synchronize the SPI clock with device clock and I have been getting very stable phase values. I think I will stick that method for now.

    Thank you for the help.