% va vb fisse a Vn ----- vc unbalance +-50%xVn step 5%xVn
clear all

%% INIZIALIZZAZIONE VARIABILI
Vn = 230;
factor = 0.05;
step_voltage = factor*Vn;

%% INIZIALIZZAZIONE DEL CANALE
fprintf('\n');
input('Premi INVIO per inizializzare il canale CAN...');
canch = canChannel('PEAK-System', 'PCAN_USBBUS1');
configBusSpeed(canch, 250000);
fprintf("Il canale è attivo\n")

%% ATTIVAZIONE DEL CANALE CAN
fprintf('\n');
input('Premi INVIO per comunicare con ITECH IT7900P...');
start(canch);

% lettura conferma attivazione canale
pause(2)
msg = receive(canch, Inf, 'OutputFormat','timetable');
if isempty(msg)
    fprintf("Errore di comunicazione con ITECH IT7900P\n")
else
    fprintf("ITECH IT7900P sta comunicando\n");
end
%% IMPOSTAZIONE MODALITA' TRIFASE
fprintf('\n');
input('Premi INVIO per impostare la modalità trifase...');
msg = canMessage(0x601, false, 8);
msg.Data = [0x23 0x01 0x30 0x02 0x01 0x00 0x00 0x00];
transmit(canch, msg)

% lettura conferma modalità trifase
msg = canMessage(0x601,false,8);
msg.Data = [0x43 0x01 0x30 0x02 0x00 0x00 0x00 0x00];
transmit(canch, msg);
pause(2)
msg = receive(canch, Inf, 'OutputFormat','timetable');
filtered = msg(msg.ID == 1409, :);
if isempty(filtered)
    fprintf('Nessun messaggio trovato con ID 581\n');
else
    lastMsg = filtered(end,:);
    data = lastMsg.Data{1};
    firstByte = data(1);
    fifthByte = data(5);
    if firstByte == 67 && fifthByte == 1 
        fprintf("Modalità trifase attivata\n")
    else
        fprintf("Problema attivazione modalità trifase\n")
    end                 
end

% IMPOSTAZIONE DI va vb vc a Vn
voltage = Vn;
msg = canMessage(0x601,false,8);
msg.Data = [0x23 0x03 0x30 0x02 (swapbytes(typecast(single(voltage),'uint8')))];
transmit(canch, msg);

% lettura conferma impostazione tensione 
msg = canMessage(0x601,false,8);
msg.Data = [0x43 0x03 0x30 0x02 0x00 0x00 0x00 0x00];
transmit(canch, msg);
pause(2)
msg = receive(canch, Inf, 'OutputFormat','timetable');
filtered = msg(msg.ID == 1409, :);
if isempty(filtered)
    fprintf('Nessun messaggio trovato con ID 581\n');
else
    lastMsg = filtered(end,:);
    data = lastMsg.Data{1};
    firstByte = data(1);
    if firstByte == 67
        value = data(end-3:end);
        realValue = typecast(swapbytes(value) , 'single');
        fprintf('Va = %.2f V, Vb = %.2f V, Vc = %.2f V\n', realValue, realValue, realValue);
    else
        fprintf("Problema impostazione della tensione\n")
     end                 
end

%% set balance mode: OFF
fprintf('\n');
input('Premi INVIO per disattivare il bilanciamento delle fasi...');
msg = canMessage(0x601, false, 8);
msg.Data = [0x23 0x03 0x30 0x01 0x00 0x00 0x00 0x00];
transmit(canch, msg);

% lettura conferma balance mode off
msg = canMessage(0x601,false,8);
msg.Data = [0x43 0x03 0x30 0x01 0x00 0x00 0x00 0x00];
transmit(canch, msg);
pause(2)
msg = receive(canch, Inf, 'OutputFormat','timetable');
filtered = msg(msg.ID == 1409, :);
if isempty(filtered)
    fprintf('Nessun messaggio trovato con ID 581\n');
else
    lastMsg = filtered(end,:);
    data = lastMsg.Data{1};
    firstByte = data(1);
    fifthByte = data(5);
    if firstByte == 67 && fifthByte == 0
        fprintf("Modalità bilanciamento delle fasi disattivata correttamente\n");
    else
        fprintf("Problema disattivazione bilanciamento delle fasi\n")
    end                 
end
%% ATTIVAZIONE DELL'OUTPUT
fprintf('\n');
input('Premi INVIO per attivare l output...');
msg = canMessage(0x601, false, 8);
msg.Data = [0x23 0x02 0x30 0x01 0x01 0x00 0x00 0x00];
transmit(canch, msg);

% lettura conferma attivazione dell'uscita
msg = canMessage(0x601, false, 8);
msg.Data = [0x43 0x02 0x30 0x01 0x00 0x00 0x00 0x00];
transmit(canch, msg);
pause(2)
msg = receive(canch, Inf, 'OutputFormat','timetable');
filtered =msg(msg.ID == 1409, :);
if isempty(filtered)
    fprintf('Nessun messaggio trovato con ID 581\n');
else
    lastMsg = filtered(end,:);
    data = lastMsg.Data{1};
    firstByte = data(1);
    fifthByte = data(5);
    if firstByte == 67 && fifthByte == 1 
        fprintf("Output attivo\n");
    else
        fprintf("Problema attivazione dell'output\n");
    end                 
end
%% VOLTAGE UNBALANCE TEST

Va_total = [];
Vb_total = [];
Vc_total = [];


% IMPOSTAZIONE DI vc unbalance +50%
fprintf('\n');
input('Premi INVIO per iniziare il ciclo +50% di unbalance...');
voltage_unb = Vn;
while voltage_unb < 1.5*Vn
      voltage_unb = voltage_unb + step_voltage; 
      msg = canMessage(0x601,false,8);
      msg.Data = [0x23 0x03 0x30 0x04 (swapbytes(typecast(single(voltage_unb),'uint8')))];
      transmit(canch, msg);
      
      % lettura tensione vc
      msg = canMessage(0x601,false,8);
      msg.Data = [0x43 0x03 0x30 0x04 0x00 0x00 0x00 0x00];
      transmit(canch, msg);
      pause(2)
      msg = receive(canch, Inf, 'OutputFormat','timetable');
      filtered = msg(msg.ID == 1409, :);
      if isempty(filtered)
         disp('Nessun messaggio trovato con ID ',num2str(581));
      else
         lastMsg = filtered(end,:);
         data = lastMsg.Data{1};
         firstByte = data(1);
        if firstByte == 67
            value = data(end-3:end);
            Vc = typecast(swapbytes(value) , 'single');
        else
            disp("Problema impostazione della tensione")
        end 

      % lettura tensione va
      msg = canMessage(0x601,false,8);
      msg.Data = [0x43 0x03 0x30 0x02 0x00 0x00 0x00 0x00];
      transmit(canch, msg);
      pause(2)
      msg = receive(canch, Inf, 'OutputFormat','timetable');
      filtered = msg(msg.ID == 1409, :);
      if isempty(filtered)
         disp('Nessun messaggio trovato con ID ',num2str(581));
      else
         lastMsg = filtered(end,:);
         data = lastMsg.Data{1};
         firstByte = data(1);
        if firstByte == 67
            value = data(end-3:end);
            Va = typecast(swapbytes(value) , 'single');
        else
            disp("Problema impostazione della tensione")
        end                 
      end

      % lettura tensione vb
      msg = canMessage(0x601,false,8);
      msg.Data = [0x43 0x03 0x30 0x03 0x00 0x00 0x00 0x00];
      transmit(canch, msg);
      pause(2)
      msg = receive(canch, Inf, 'OutputFormat','timetable');
      filtered = msg(msg.ID == 1409, :);
      if isempty(filtered)
         disp('Nessun messaggio trovato con ID ',num2str(581));
      else
         lastMsg = filtered(end,:);
         data = lastMsg.Data{1};
         firstByte = data(1);
        if firstByte == 67
            value = data(end-3:end);
            Vb = typecast(swapbytes(value) , 'single');
        else
            disp("Problema impostazione della tensione")
        end                 
      end
     
      fprintf('[UNBALANCE TEST] Step: %+3.0f%% Vn -> Va = %.2f V | Vb = %.2f V | Vc = %.2f V\n', ...
        (voltage_unb/Vn-1)*100, Va, Vb, Vc);
      end

Va_total = [Va_total Va];
Vb_total = [Vb_total Vb];
Vc_total = [Vc_total Vc];

% pausa la somma delle pause in letturaq delle tensioni
end 

% Risettaggio tensione a Vn
voltage = Vn;
msg = canMessage(0x601,false,8);
msg.Data = [0x23 0x03 0x30 0x02 (swapbytes(typecast(single(voltage),'uint8')))];
transmit(canch, msg);


% IMPOSTAZIONE DI vc unbalance -50%
voltage_unb = Vn;
fprintf('\n');
input('Premi INVIO per iniziare il ciclo -50% di unbalance...');
while voltage_unb > 0.5*Vn
      voltage_unb = voltage_unb - step_voltage; 
      msg = canMessage(0x601,false,8);
      msg.Data = [0x23 0x03 0x30 0x04 (swapbytes(typecast(single(voltage_unb),'uint8')))];
      transmit(canch, msg);

       % lettura tensione vc
      msg = canMessage(0x601,false,8);
      msg.Data = [0x43 0x03 0x30 0x04 0x00 0x00 0x00 0x00];
      transmit(canch, msg);
      pause(2)
      msg = receive(canch, Inf, 'OutputFormat','timetable');
      filtered = msg(msg.ID == 1409, :);
      if isempty(filtered)
         disp('Nessun messaggio trovato con ID ',num2str(581));
      else
         lastMsg = filtered(end,:);
         data = lastMsg.Data{1};
         firstByte = data(1);
        if firstByte == 67
            value = data(end-3:end);
            Vc = typecast(swapbytes(value) , 'single');
        else
            disp("Problema impostazione della tensione")
        end 

      % lettura tensione va
      msg = canMessage(0x601,false,8);
      msg.Data = [0x43 0x03 0x30 0x02 0x00 0x00 0x00 0x00];
      transmit(canch, msg);
      pause(2)
      msg = receive(canch, Inf, 'OutputFormat','timetable');
      filtered = msg(msg.ID == 1409, :);
      if isempty(filtered)
         disp('Nessun messaggio trovato con ID ',num2str(581));
      else
         lastMsg = filtered(end,:);
         data = lastMsg.Data{1};
         firstByte = data(1);
        if firstByte == 67
            value = data(end-3:end);
            Va = typecast(swapbytes(value) , 'single');
        else
            disp("Problema impostazione della tensione")
        end                 
      end

      % lettura tensione vb
      msg = canMessage(0x601,false,8);
      msg.Data = [0x43 0x03 0x30 0x03 0x00 0x00 0x00 0x00];
      transmit(canch, msg);
      pause(2)
      msg = receive(canch, Inf, 'OutputFormat','timetable');
      filtered = msg(msg.ID == 1409, :);
      if isempty(filtered)
         disp('Nessun messaggio trovato con ID ',num2str(581));
      else
         lastMsg = filtered(end,:);
         data = lastMsg.Data{1};
         firstByte = data(1);
        if firstByte == 67
            value = data(end-3:end);
            Vb = typecast(swapbytes(value) , 'single');
        else
            disp("Problema impostazione della tensione")
        end                 
      end
     
      fprintf('[UNBALANCE TEST] Step: %-3.0f%% Vn -> Va = %.2f V | Vb = %.2f V | Vc = %.2f V\n', ...
        (voltage_unb/Vn-1)*100, Va, Vb, Vc);
      end

Va_total = [Va_total Va];
Vb_total = [Vb_total Vb];
Vc_total = [Vc_total Vc];

% pausa la somma delle pause in letturaq delle tensioni
end 

%% TERMINE PROVA
fprintf('\n');
input('Premi INVIO per terminare la prova...');

% DISATTIVAZIONE OUTPUT
msg = canMessage(0x601, false, 8);
msg.Data = [0x23 0x02 0x30 0x01 0x00 0x00 0x00 0x00];
transmit(canch, msg);
% lettura conferma disattivazione dell'uscita
msg = canMessage(0x601, false, 8);
msg.Data = [0x43 0x02 0x30 0x01 0x00 0x00 0x00 0x00];
transmit(canch, msg);
pause(2)
msg = receive(canch, Inf, 'OutputFormat','timetable');
filtered =msg(msg.ID == 1409, :);
if isempty(filtered)
    fprintf('Nessun messaggio trovato con ID 581\n');
else
    lastMsg = filtered(end,:);
    data = lastMsg.Data{1};
    firstByte = data(1);
    fifthByte = data(5);
    if firstByte == 67 && fifthByte == 0 
        fprintf("Output disattivato\n");
    else
        fprintf("Problema disattivazione dell'output\n");
    end                 
end

% IMPOSTAZIONE MODALITA' MONOFASE (imposta le tensioni a 0V in automatico)
msg = canMessage(0x601, false, 8);
msg.Data = [0x23 0x01 0x30 0x02 0x00 0x00 0x00 0x00];
transmit(canch, msg);

% lettura conferma modalità monofase
msg = canMessage(0x601,false,8);
msg.Data = [0x43 0x01 0x30 0x02 0x00 0x00 0x00 0x00];
transmit(canch, msg);
pause(2)
msg = receive(canch, Inf, 'OutputFormat','timetable');
filtered =msg(msg.ID == 1409, :);
if isempty(filtered)
    fprintf('Nessun messaggio trovato con ID 581\n');
else
    lastMsg = filtered(end,:);
    data = lastMsg.Data{1};
    firstByte = data(1);
    fifthByte = data(5);

    if firstByte == 67 && fifthByte == 0 
        fprintf("Modalità monofase attivata\n")
    else
        fprintf("Problema attivazione modalità monofase\n")
    end                 
end
% msg_va = canMessage(0x601,false,8);
% msg_va.Data = [0x23 0x03 0x30 0x02 0x00 0x00 0x00 0x00];
% transmit(canch, msg_va);
% msg_vb = canMessage(0x601,false,8);
% msg_vb.Data = [0x23 0x03 0x30 0x03 0x00 0x00 0x00 0x00];
% transmit(canch, msg_vb);
% msg_vc = canMessage(0x601,false,8);
% msg_vc.Data = [0x23 0x03 0x30 0x04 0x00 0x00 0x00 0x00];
% transmit(canch, msg_vc);
% DISATTIVAZIONE COMUNICAZIONE ITECH IT7900P

% DISATTIVAZIONE COMUNICAZIONE ITECH IT7900P
stop(canch);
% lettura conferma disattivazione canale
pause(2)
msg = receive(canch, Inf, 'OutputFormat','timetable');
if isempty(msg)
    fprintf("Il canale CAN è spento\n");
else
    fprintf("Errore di comunicazione con ITECH IT7900P\n")
end
