VSD Open-phase-fault detection#

This module provides functions for open phase fault (OPF) detection based on Vector Space Decompositon (VSD) for an asymmetric six phase machine. Since the VSD transformation can be used for both PMSM and asynchronous machines, this module can be used for both machine types. The OPF detection can be extended to other stator arrangements, eg. symmetrical six phase machines or 5 and 9 phase machines. However, this is not included in this module, since the underlying equations for the fault indices have to be adjusted for it according to the stator arrangement.

The open phase fault detection for asymmetric six phase machines is described in detail in [[1]].

The fault detection is based on six fault indices, one for each phase of the machine. The fault indices are calculated based on the measured VSD-currents with the following equations. \({R_{1}}, {R_{2}}, {R_{3}}, {R_{4}}, {R_{5}}, {R_{6}}\) are the fault indices for the phases 1 to 6 in the order \(a_1, b_1, c_1, a_2, b_2, c_2\). \(i_\alpha, i_\beta, i_x, i_y, i_{0^+}, i_{0^-}\) are the VSD-currents calculated from the measured phasecurrent with the VSD-Transformation.

\[{R_{1}} =-\frac{i_x}{i_\alpha+i_{0^+}}\]
\[\begin{split}R_{2} =\frac{i_x}{-i_\alpha+\sqrt3\ i_\beta-\sqrt3\ i_y+2\ i_{0^+}}\\\end{split}\]
\[\begin{split}R_{3} =\frac{i_x}{-i_\alpha-\sqrt3\ i_\beta+\sqrt3\ i_y+2\ i_{0^+}}\\\end{split}\]
\[\begin{split}R_{4} =\frac{i_x}{i_\alpha+\frac{1}{\sqrt3}\ i_\beta+\frac{1}{\sqrt3}\ i_y+\frac{2}{\sqrt3}\ i_{0^-}}\\\end{split}\]
\[\begin{split}R_{5} = \frac{i_x}{i_\alpha-\frac{1}{\sqrt3}\ i_\beta-\frac{1}{\sqrt3}\ i_y-\frac{2}{\sqrt3}\ i_{0^-}}\\\end{split}\]
\[\begin{split}R_{6} =-\frac{i_y}{i_\beta-i_{0^+}}\\\end{split}\]

The fault indices are in pre-fault operation zero as the torque producing currents are mapped only into the \(\alpha\beta\)-plane while into the \(xy\)- and \(0^+0^-\)-planes only currents because of asymmetries and some harmonics are mapped, which are close to zero, especially if a proper control system is used and if the PMSM contains few harmonic and asymmetric components. After a phase failure, the fault indices are no longer zero as now significant current components occur in the \(xy\)- and \(0^+0^-\)-system as the three subsystems are no longer uncoupled. The fault index of the faulted phase is on average one. The remaining fault indices follow different non-zero functions depending on the fault scenario.

By filtering the fault indices, they can be converted so that only the fault indices of the faulted phases are constant one, while all other fault indices are zero. For the filtering an hysteresis band filter followed by an moving average filter is used. The hysteresis band filter set the value of a fault index to zero if the value is not in a narrow band around one defined by an upper and lower hysteresis band limit. The moving average smoothes the fault indices so that short disturbances do not affect the fault detection. The length of the smoothing intervall is defined as a portion of one electrical period of the phase currents. The filtered fault indices are evaluated by a threshold value. A phase detected as faulted if its fault index exceeds this threshold.

After the filtering the fault indices have two possible states and are either 0 (no fault in the corresponding phase) or 1 (fault in the corresponding phase) and can therefore be used for OPF detection.

The following module contains functions for calculating the fault indices, applying hysteresis band and moving average filtering and evaluating the filtered fault indices. The obtained results of the evaluated fault indices can be used for an control scheme during OPF.

Fault indices#

struct uz_6phFD_indices#

Struct for fault indices for the six phase Open-Phase-Fault-Detection.

Public Members

float R1#

Fault index for phase 1 (a1)

float R2#

Fault index for phase 2 (b1)

float R3#

Fault index for phase 3 (c1)

float R4#

Fault index for phase 4 (a2)

float R5#

Fault index for phase 5 (b2)

float R6#

Fault index for phase 6 (c2)

Description#

Struct for 6 fault indices, each indicating if the corresponding phase of the machine is under open phase fault.

Fault detection module#

typedef struct uz_VSD_6ph_FD_t uz_VSD_6ph_FD_t#

Struct definition for uz_VSD_6ph_FD_t.

struct uz_VSD_6ph_FD_config#

Configuration struct for six phase VSD fault detection. Pass to init function. Accessible by the user.

Public Members

float upperlimit#

upper limit of hysteresis band, recommended values: 1.1 (1 … 1.5)

float lowerlimit#

lowerlimit lower limit of hysteresis band, recommended values: 0.9 (0.6 … 1)

float threshold#

threshold value above which a fault index is judged as an error, recommended values: 0.4 (0.2 … 0.7)

uint32_t mov_average_filter_length#

maximal length of moving average filter, needs to be sufficiently long for all sampling values according to the operating motor speeds and the parameter percent_of_el_period

float sample_frequency_Hz#

sample frequency in Hz, frequency with which the OPF detection is called during operation

float percent_of_el_period#

desired filter length as portion of an electric period, recommended values: 0.4 (0.3 … 0.7)

uz_movingAverageFilter_t *movingAverageFilter_R1#

moving average filter for fault index R1

uz_movingAverageFilter_t *movingAverageFilter_R2#

moving average filter for fault index R2

uz_movingAverageFilter_t *movingAverageFilter_R3#

moving average filter for fault index R3

uz_movingAverageFilter_t *movingAverageFilter_R4#

moving average filter for fault index R4

uz_movingAverageFilter_t *movingAverageFilter_R5#

moving average filter for fault index R5

uz_movingAverageFilter_t *movingAverageFilter_R6#

moving average filter for fault index R6

uz_VSD_6ph_FD_t *uz_VSD_6ph_FD_init(struct uz_VSD_6ph_FD_config config)#

Init function for the six phase OPF detection.

Parameters:
  • uz_VSD_6ph_FD_t* – pointer to OPF fault detection struct

  • struct – uz_VSD_6ph_FD_config, config for the fault detection

Returns:

uz_VSD_6ph_FD_t*, pointer to the fault detection

Fault detection#

uz_6phFD_indices uz_vsd_opf_6ph_faultdetection_step(uz_VSD_6ph_FD_t *VSD_FD, uz_6ph_alphabeta_t vsdcurrents, float omega_el_rad_per_sec)#

Function for six-phase open-phase-fault detection, has to be cyclicly called with a the frequency configured in sample_frequency_Hz.

Parameters:
  • uz_VSD_6ph_FD_t* – pointer to OPF fault detection struct

  • vsdcurrents – VSD currents

  • omega_el_rad_per_sec – omega_el in rad per seconds

Returns:

uz_6phFD_indices fault indices for the six phases filtered and evaluated

Description#

Function for using the complete open-phase-fault detection. This function includes the calculation of the fault indices, filtering with a hysteresis band filter and moving average filter and finally the evaluation of the filtered fault indices. The individual substeps of this function are available in the following functions _uz_vsd_opf_6ph_fault_indices_calculation, _uz_vsd_fd_hysteresis_filter and _uz_vsd_fd_evaluation.

Calculation of the fault indices#

uz_6phFD_indices uz_vsd_opf_6ph_fault_indices_calculation(uz_6ph_alphabeta_t vsdcurrents)#

Function to calculate the fault indices (unfiltered) for 6-phase open-phase-fault detection (used by uz_vsd_opf_6ph_faultdetection_step)

Parameters:
  • vsdcurrents – uz_6ph_alphabeta_t struct, vsd currents of 6-phase system

Returns:

uz_6phFD_indices fault indices for the six phases

Description#

Function for calculating the raw fault indices from the six VSD-currents of the machine according to the equations.

Hysteresis Filter#

uz_6phFD_indices uz_vsd_fd_hysteresis_filter(uz_6phFD_indices input, float lowerlimit, float upperlimit)#

Hysteresis filter function for the vsd open phase fault detection. Sets fault indices to zero if they are not in the hysteresis band bounded by the limits (used by uz_vsd_opf_6ph_faultdetection_step)

Parameters:
  • input – fault indices, value is set to 0 if the value of the index is outside of the hysteresis band

  • upperlimit – upper limit of hysteresis band

  • lowerlimit – lower limit of hysteresis band

Returns:

uz_6phFD_indices fault indices after filtering with the hysteresis band

Description#

Function for filtering the raw fault indices calculated by _uz_vsd_opf_6ph_fault_indices_calculation with a hysteresis band specified by the input values. The fault indices are set to zero if they are outside the hysteresis band bounded by the upper and lower limit.

Fault indices evaluation#

uz_6phFD_indices uz_vsd_fd_evaluation(uz_6phFD_indices input, float threshold)#

Evaluates uz_6phFD_indices values with a threshold value (used by uz_vsd_opf_6ph_faultdetection_step)

Parameters:
  • input – input fault indices

  • threshold – value from which a fault index is judged as an error

Returns:

uz_6phFD_indices fault indices set to 0 if fault index is below or set to 1 if fault index is above the threshold value

Description#

Function for evaluating the filtered fault indices with a threshold value, deciding if a fault index indicates an open phase fault or not. A open phase fault is detected when a fault index is above the set threshold value.

Example of complete open phase fault detection#

Listing 166 Example for using the functions of the module for the fault detection.#
 1int main(void) {
 2
 3  // config for moving average filter
 4  struct uz_movingAverageFilter_config movAvF_config = {
 5      .filterLength = 300U
 6  };
 7
 8  // moving average filter for 6 phases
 9  uz_movingAverageFilter_t* movAvFilter_R1;
10  uz_movingAverageFilter_t* movAvFilter_R2;
11  uz_movingAverageFilter_t* movAvFilter_R3;
12  uz_movingAverageFilter_t* movAvFilter_R4;
13  uz_movingAverageFilter_t* movAvFilter_R5;
14  uz_movingAverageFilter_t* movAvFilter_R6;
15
16  // circular Buffers for 6 moving average filters
17  float dataR1 [500] = {0};
18  uz_array_float_t circularBuffer_R1 = {
19    .length = UZ_ARRAY_SIZE(dataR1),
20    .data = &dataR1[0]
21  };
22  float dataR2 [500] = {0};
23  uz_array_float_t circularBuffer_R2 = {
24    .length = UZ_ARRAY_SIZE(dataR2),
25    .data = &dataR2[0]
26  };
27  float dataR3 [500] = {0};
28  uz_array_float_t circularBuffer_R3 = {
29    .length = UZ_ARRAY_SIZE(dataR3),
30    .data = &dataR3[0]
31  };
32  float dataR4 [500] = {0};
33  uz_array_float_t circularBuffer_R4 = {
34    .length = UZ_ARRAY_SIZE(dataR4),
35    .data = &dataR4[0]
36  };
37  float dataR5 [500] = {0};
38  uz_array_float_t circularBuffer_R5 = {
39    .length = UZ_ARRAY_SIZE(dataR5),
40    .data = &dataR5[0]
41  };
42  float dataR6 [500] = {0};
43  uz_array_float_t circularBuffer_R6 = {
44    .length = UZ_ARRAY_SIZE(dataR6),
45    .data = &dataR6[0]
46  };
47
48  // initialize moving average filter
49  movAvFilter_R1 =  uz_movingAverageFilter_init(movAvF_config, circularBuffer_R1);
50  movAvFilter_R2 =  uz_movingAverageFilter_init(movAvF_config, circularBuffer_R2);
51  movAvFilter_R3 =  uz_movingAverageFilter_init(movAvF_config, circularBuffer_R3);
52  movAvFilter_R4 =  uz_movingAverageFilter_init(movAvF_config, circularBuffer_R4);
53  movAvFilter_R5 =  uz_movingAverageFilter_init(movAvF_config, circularBuffer_R5);
54  movAvFilter_R6 =  uz_movingAverageFilter_init(movAvF_config, circularBuffer_R6);
55
56  // config for OPF fault detection
57  struct uz_VSD_6ph_FD_config OPF_FD_config = {
58      .upperlimit = 1.1f,
59      .lowerlimit = 0.9f,
60      .threshold = 0.4f,
61      .mov_average_filter_length = 500,
62      .sample_frequency_Hz = 1000,
63      .percent_of_el_period = 0.4f,
64      .movingAverageFilter_R1 = movAvFilter_R1,
65      .movingAverageFilter_R2 = movAvFilter_R2,
66      .movingAverageFilter_R3 = movAvFilter_R3,
67      .movingAverageFilter_R4 = movAvFilter_R4,
68      .movingAverageFilter_R5 = movAvFilter_R5,
69      .movingAverageFilter_R6 = movAvFilter_R6,
70  };
71
72  // fault detection module
73  uz_VSD_6ph_FD_t* OPF_FD = uz_VSD_6ph_FD_init(OPF_FD_config);
74
75  float omega_el_rad_per_sec = 0.0f;
76  uz_6ph_abc_t currents_abc = {0};
77  uz_6ph_alphabeta_t vsdcurrents = {0};
78  uz_6phFD_indices faultindices = {0};
79
80  // open phase fault detection (in ISR) called with sample_frequency_Hz
81  while(1){
82    // current omega el from measurement
83    omega_el_rad_per_sec = 100.0f;
84    // current vsd-currents
85    vsdcurrents = uz_transformation_asym30deg_6ph_abc_to_alphabeta(currents_i_abc);
86    // calculate fault indices
87    faultindices = uz_vsd_opf_6ph_faultdetection_step(OPF_FD, vsdcurrents, omega_el_rad_per_sec);
88  }
89
90}