前言:主动移频正反馈方法实现简单,计算量小,检测盲区小,在逆变器的孤岛检测中有很多应用。
通过在并网逆变器的电流给定上的角度上做频率扰动,正常工作时PCC点频率被电网钳位,而当电网失压时,PCC点的频率会因为新周期的锁相环检测的频率和孤岛分析方法叠加的频率扰动影响,产生频率的变化,当频率变化足够大时,孤岛就能被检测到。
恶劣情况下本地负载RLC的Q值很小,其谐振频率又恰好是50Hz,在这种极端情况下,电网失压后可能逆变器的输出电流和PCC点的电压频率基本上无变化,就会导致孤岛检测失败。目前使用主动移动正反馈算法的孤岛分析方法,能较好的识别出孤岛情况。其算法思想是,正常工作下使用接近电网频率的扰动频率来输出逆变器电流,在电网失压后,PCC点频率变化时,把新PCC的频率与默认情况下正常电网频率的误差叠加到新的频率扰动上去,扩大孤岛频率扰动的幅度,更快的检测到孤岛情况。
代码实现,以状态机的方法简单的实现主动移频,其方法是对输入锁相环的PCC相位角度theta来实现,在函数输出的theta变量上以更高的频率运行,其必然会更快与PCC锁相环的输出theta达到PI和2PI这两个区域。使用了状态机来分别管理等于PI和2PI区域时候的情况,就是在这里停止函数输出的THETA的继续积分。在波形上可以看到此时区域为平台区域,就是文献中提出的Tz区域。
正反馈部分主要是判断PCC的电网与正常电网频率的差,如果超出到一定范围则在提升或降低主动移频率方法的扰动频率,该功能仅在电网负向过零区域穿越时动作一次。
测试,单相并网逆变器
运行,CH4 AFD 输出的电流给定基准正弦波,可见Tz区域对并网电流还是有一定的影响。
在1秒时断开电网连接,本地负载谐振频率50Hz(25欧,1mH,10.3mF)开关频率变化明显,孤岛能被检测到。
本人能力有限,如有错误恳请帮忙指正,感谢观看感谢支持,谢谢。
static inline float32_t ads_island_func(AFD_SS *p, float32_t grid_theta, float32_t cf, float32_t grid_freq_norm, float32_t ts, float32_t pcc_freq)
{
const float32_t _2PI = 6.2831852f;
const float32_t _PI = 3.1415926f;
const float32_t SPLL_THETA_STEP = 0.05f;
float32_t islanding_AFD_Tz = cf * _2PI;
float32_t k_ff = 0.125f;
float32_t island_APF_setp = 0.5f;
static float32_t AFD_FREQ, theta_inv, step;
static uint16_t run_afd_theta_flag;
const float32_t islanding_delat_freq = grid_freq_norm - pcc_freq;
const float32_t over_aff_freq = 0.2f;
switch(p->enum_ac)
{
case ac_neg_hold:
theta_inv = 0;
run_afd_theta_flag = 0;
if(pcc_freq >= grid_freq_norm)
{
if((pcc_freq - grid_freq_norm) > over_aff_freq)
{
step += k_ff * islanding_delat_freq;
}
else
{
step = island_APF_setp;
}
AFD_FREQ = pcc_freq + step;
}
else
{
if((grid_freq_norm - pcc_freq) > over_aff_freq)
{
step += k_ff * island_APF_setp;
}
else
{
step = island_APF_setp;
}
AFD_FREQ = pcc_freq - step;
}
if(grid_theta > SPLL_THETA_STEP)
{
p->enum_ac = ac_pos;
theta_inv = 0;
run_afd_theta_flag = 1u;
}
break;
case ac_pos:
if(theta_inv > (_PI - islanding_AFD_Tz))
{
theta_inv = _PI;
run_afd_theta_flag = 0;
}
if(grid_theta > (_PI - SPLL_THETA_STEP))
{
p->enum_ac = ac_neg;
theta_inv = _PI;
run_afd_theta_flag = 1u;
}
break;
case ac_neg:
if(theta_inv > (_2PI - islanding_AFD_Tz))
{
theta_inv = _2PI;
run_afd_theta_flag = 0;
}
if(grid_theta > (_2PI - SPLL_THETA_STEP))
{
p->enum_ac = ac_neg_hold;
theta_inv = _2PI;
run_afd_theta_flag = 1u;
}
break;
default:
p->enum_ac = ac_neg_hold;
theta_inv = 0;
run_afd_theta_flag = 0;
break;
}
if(run_afd_theta_flag) {theta_inv += _2PI * ts * AFD_FREQ;}
return(theta_inv);
}