Este artigo explica como realizar a comunicação OPC entre o software SCADA Action₀NET e o MATLAB.
Leitura e Escrita em Tags
Para esse exemplo, foi criado um projeto no Action₀NET com duas Tags: POT_1 e AMP_1.
No Action₀NET, basta subir o projeto com o Servidor OPC ligado.
O MATLAB precisa ser uma versão mais nova que a 2012, com a Toolbox de OPC instalada.
Segue o código utilizado:
% Conexão OPC:
da = opcda('localhost', 'Action.NET.OPCDAServer.2');
connect(da);
grp = addgroup(da);
itm1 = additem(grp, 'Tag.POT_1');
itm2 = additem(grp, 'Tag.AMP_1');
POT_1 = read(itm1); %Lê o valor do itm1(Tag.POT_1) e guarda na
variável POT_1.
write(itm2, 12); %Escreve no itm2(Tag.AMP_1) o valor 12.
OBS.: ao ler o itm1 e guardá-lo na variável POT_1, a variável POT_1 se torna uma variável do tipo STRUC com a seguinte estrutura:
POT_1 =
ItemID: 'Tag.POT_1'
Value: 0.2635
Quality: 'Good: Non-specific'
TimeStamp: [2016 7 21 9 44 37.4610]
Error: ''
Portanto, para acessar seu valor devemos acessá-lo através do comando:
POT_1.Value
ans =
0.2635
Fluxo de Potência com o MATPOWER
Neste exemplo, será utilizada uma biblioteca chamada MATPOWER, que nos dá uma função de fluxo de potência de uma rede modelada.
Para isso, é necessário existir uma rede modelada (anexo 2.1: case1_2) e todos os arquivos precisam estar dentro do diretório do MATPOWER.
No exemplo a seguir, a rede foi modelada com apenas 2 barramentos. No primeiro, está ligada uma fonte com tensão constante igual a 1 fase 0º p.u. e no segundo está ligada uma carga consumindo a potência que será lida da Tag.POT_1.
O Programa irá ler o valor de potência da Tag.POT_1 (em MW) e calculará a corrente (em p.u.) no ramo que une as duas barras.
Tempo Real
clear;
close;
clc;
% Conexão OPC:
da = opcda('localhost', 'Action.NET.OPCDAServer.2');
connect(da);
grp = addgroup(da);
itm1 = additem(grp, 'Tag.POT_1');
itm2 = additem(grp, 'Tag.AMP_1');
TEMPO = 5 * 60; %Define o tempo de simulação
Q = (sqrt(1-(0.92*0.92)))/0.92; %Fator de conversão da potência ativa para reativa (FP 0,92)
mpc = runpf('case1_2');
%% Simulação
for i = 1:TEMPO;
POT_1 = read(itm1); %Lê o valor do itm1(Tag.POT_1) e guarda na variável POT_1.
mpc.bus(2,3) = POT_1.Value;
mpc.bus(2,4) = Q * POT_1.Value;
save 'TempoReal';
disconnect(da);
mpc = runpf('TempoReal'); %Fluxo de Carga
connect(da);
AMP_1 = sqrt((mpc.branch(1,14) + mpc.branch(1,16))/mpc.branch(1,3));
write(itm2, AMP_1); %Escreve no itm2(Tag.AMP_1) o valor da variável AMP_1.
end
disconnect(da);
OBS.: todos os arquivos estarão em anexo. Basta rodar o arquivo TempoReal.m.
Anexo
Case1_2
function mpc = case1_2
%CASE9 Power flow data for 9 bus, 3 generator case.
% Please see CASEFORMAT for details on the case file format.
%
% Based on data from Joe H. Chow's book, p. 70.
% MATPOWER
% $Id: case9.m 1559 2010-03-10 18:08:32Z ray $
%% MATPOWER Case Format : Version 2
mpc.version = '2';
%%----- Power Flow Data -----%%
%% system MVA base
mpc.baseMVA = 2;
%% bus data
% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin
mpc.bus = [
1 3 0.00000 0.00000 0 0 1 1 0 13.8 1 1.1 0.9 ;
2 1 0.00000 0.00000 0 0 1 1 0 13.8 1 1.1 0.9 ;
];
%% generator data
% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf
mpc.gen = [
1 0 0 0 0 1 1 1 300 1;
];
%% branch data
% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax
mpc.branch = [
1 2 0.9 0.4 0 250 250 250 0 0 1 -360 360;
];
%%----- OPF Data -----%%
% %% area data
% % area refbus
% mpc.areas = [
% 1 5;
% ];
%
% %% generator cost data
% % 1 startup shutdown n x1 y1 ... xn yn
% % 2 startup shutdown n c(n-1) ... c0
% mpc.gencost = [
% 2 1500 0 3 0.11 5 150;
% 2 2000 0 3 0.085 1.2 600;
% 2 3000 0 3 0.1225 1 335;
% ];