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.

MSP430F6779: Zero Crossing

Part Number: MSP430F6779

Hello there,

I'm doing some logic on the MSP430F6779 which requires zero-crossing detection, to do time-sensitive relay switching.

We're using the EMDC package to also do energy metering.

Are there any consequences if I use the EMDC package, but have a loop which waits for a zero-crossing by reading the ADC values directly?

How would such a wait-loop be implemented with the way EMDC sets up the ADCs?

Since a lot of the code is pre-compiled, I'm not entirely sure how the ADCs are setup in EMDC, nor how to wait for a zero-crossing to perform time-sensitive switching.

Any ideas?

Thanks in advance! The TI support forum has been very helpful so far, we appreciate the TI support team very much :)

  • Hi, 

    From the EMDC, we cannot directly give you a real time zero crossing signal - I assumed it would be used to control a triac. Please add a ZC hardware detection to IO interrupt and you can do a time sync with ZC signal. 

  • Is there any way to directly access the instantaneous voltage-values from the Delta Sigma which EMDC has setup? (to get + and - values?)

    We don't want to add extra hardware if possible, so even if we have some rudimentary Zero-Crossing detection in software, it would go a long way.

    I'd like to just have a while-loop which waits for Phase 1 to go from positive to negative (even if there's some noise, our application doesn't have to be exact, just roughly close).

  • I gave this a try, in order to read instantaneous values; are there any downsides to using this for reading the instantaneous values?

    int16_t Read_phaseV(uint8_t phase)
    {
        int16_t retVal;
        switch(phase)
        {
            case 0// Phase A
                retVal = SD24_B_getHighWordResults(SD24_BASE, SD24_B_CONVERTER_0);
                retVal = EM_voltageDCFilter(&gEmSWResult.phaseBGResults[EM_PH_A_IDX].vDCEstimate, retVal);
                break;
            case 1// Phase B
                retVal = SD24_B_getHighWordResults(SD24_BASE, SD24_B_CONVERTER_1);
                retVal = EM_voltageDCFilter(&gEmSWResult.phaseBGResults[EM_PH_B_IDX].vDCEstimate, retVal);
                break;
            case 2// Phase C
                retVal = SD24_B_getHighWordResults(SD24_BASE, SD24_B_CONVERTER_2);
                retVal = EM_voltageDCFilter(&gEmSWResult.phaseBGResults[EM_PH_C_IDX].vDCEstimate, retVal);
                break;
            defaultbreak;
        }
        return retVal;
    }
  • I modified my approach;

    https://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/EnergyMeasurementDesignCenter/1_40_00_03/release/EnergyMeasurementDesignCenter_1_40_00_03/docs/api_guide/html/group__result__api.html

    int16_t EM_voltageDCFilter (int32_t *p, int16_t x)
      The following API is intended for the removal of the DC content from 16 bit 50Hz/60Hz mains signals. All samples should be passed through the filter, in sequence, to obtain a signal free of DC content. The estimation is based on a noise shaped single pole LPF.The cutoff frequency of this filter is set very low, so its gain is essentially flat from 45Hz upwards. This means the filter can take several seconds to stabilize when the signal is initially applied. More...

    So I guess I'm not going to use the approach above, since it will ruin the DC Filter.

    In case it helps anyone else, I decided to go into "hal_adc.c" and use a new global variable to keep these in, which updates pretty frequently.

    int16_t phAVInstSamples[3];

    ...

            // Apply Voltage DC Filter
            tempV = EM_voltageDCFilter(&gEmSWResult.phaseBGResults[EM_PH_A_IDX].vDCEstimate, phAVSamples[phAWriteVIdx]);
            phAVSamples[phAWriteVIdx] = tempV;
            phAVInstSamples[0] = tempV;

    I modified the routine to set/clear a bit on each update to Phase A, then used a logic analyzer to check the timing. It was updating PhaseA every 243us, pretty consistently. This is with a EMDC programmed sample rate of 2048 Hz, so I believe this is accurate enough for my purposes!

    It's updated every 1.46% of a cycle. For purposes of identifying clock-wise vs counter-clockwise orientation, this is plenty good enough.

  • Hi,

    I think you are in a correct way. From the ADC data, you can measure the ZC by sw and detect the peak/bottom of the phase voltage. If you can accept the accuracy, it would be good. And in order to reduce the detection error, I suggest to add a sw hysteresis comparator.