% Example script for direct communication with Sessantaquattro+ and
% impedance reading
% Works with firmware version 5.11
%
% OT Bioelettronica
% v 1.0

close all
clear all

% Refer to the communication protocol for details about these variables:
FSAMP = 1;      % if MODE != 3: 0 = 500 Hz,  1 = 1000 Hz, 2 = 2000 Hz
                % if MODE == 3: 0 = 2000 Hz, 1 = 4000 Hz, 2 = 8000 Hz
                % Impedance is measured at 1/4 of the sampling frequency
NCH  = 3;       % 0 = 8 channels, 1 = 16 channels, 2 = 32 channels, 3 = 64 channels
MODE = 5;       % 0 = Monopolar, 1 = Bipolar, 2 = Differential, 3 = Accelerometers
                % 5 = Impedance check advanced, 6 = Impedance check, 7 = Test Mode
HRES = 1;       % 0 = 16 bits, no need for 24 bit during impedance check
HPF  = 1;       % 1 = High pass filter active the DC component must be removed
GAIN = 0;       % 0 = resolution is 0.2861mV
                % 1 = resol is 0.143mV if HRES=1, resol is 0.5722mV if HRES=0
                % 2 = resol is 0.0954mV if HRES=1, resol is 0.3815mV if HRES=0
                % 3 = resol is 0.0715mV if HRES=1, resol is 0.2861mV if HRES=0
TRIG = 0;       % 0 = Data transfer controlled remotely, 3 = REC on SD controlled from the pushbutton or remotely
GO   = 1;       % 0 = just send the settings, 1 = send settings and start the data transfer

NumCycle = 1;
OffsetPlot = 0;

% The conversion factor has to be multiplied the ARV value estimated from
% the raw data generated by the Sessantaquattro+ when in impedance check or
% Advanced Impedance check mode the get the impedance in kohm
ConvFact = 0.1;

% Create the command to send to Sessantaquattro+
Command = 0;
Command = Command + GO;
Command = Command + TRIG * 4;
Command = Command + GAIN * 16;
Command = Command + HPF * 64;
Command = Command + HRES * 128;
Command = Command + MODE * 256;
Command = Command + NCH * 2048;
Command = Command + FSAMP * 8192;
dec2bin(Command)

% Set the variables for the script
switch NCH
    case 0
        if(MODE == 1)
            NumChan = 8;
        else
            NumChan = 12;
        end
    case 1
        if(MODE == 1)
            NumChan = 12;
        else
            NumChan = 20;
        end
    case 2
        if(MODE == 1)
            NumChan = 20;
        else
            NumChan = 36;
        end
    case 3
        if(MODE == 1)
            NumChan = 36;
        else
            NumChan = 68;
        end
end

switch FSAMP
    case 0
        if(MODE == 3)
            sampFreq = 2000;
        else
            sampFreq = 500;
        end
    case 1
        if(MODE == 3)
            sampFreq = 4000;
        else
            sampFreq = 1000;
        end
    case 2
        if(MODE == 3)
            sampFreq = 8000;
        else
            sampFreq = 2000;
        end
    case 3
        if(MODE == 3)
            sampFreq = 16000;
        else
            sampFreq = 4000;
        end
    otherwise
        disp('wrong value for FSAMP')
end

% The function tcpip is substituted by the functions
% tcpserver/tcpclient from Matlab version 2022a

if verLessThan('matlab','9.12')
    % Open the TCP socket as server
    t = tcpip('0.0.0.0', 45454, 'NetworkRole', 'server');
    % Increase the input buffer size
    t.InputBufferSize = 500000; %190152;
    % Wait into this function until a client is connected
    fopen(t)
else
    % Open the TCP socket as server
    t = tcpserver(45454,"ByteOrder","big-endian");
    % Increase the input buffer size
    t.InputBufferSize = 500000; %190152;
    % Wait into this function until a client is connected
    fopen(t)
    while(t.Connected < 1)
       pause(0.1)
    end
end

disp('Connected to the Socket')

ARV = zeros(NumChan-4, 1);

% Send the command to Sessantaquattro+
fwrite(t, Command, 'int16');

if(GO == 0)
    
    % Wait for 10 seconds
    pause(10)
    
    %stop the recording on MicroSD cards
    fwrite(t, Command-2, 'int16');
    
else

    % If the high resolution mode (24 bits) is active
    if(HRES == 1)
        % one second of data: 3 bytes * channels * Sampling frequency
        blockData = 3*NumChan*sampFreq;

        ChInd = (1:3:NumChan*3);

        % Main plot loop
        for i = 1 : NumCycle

            i

            % Wait here until one second of data has been received
            while(t.BytesAvailable < blockData)
            end

            % Read one second of data into single bytes
            Temp = fread(t, NumChan*3*sampFreq, 'uint8');
            Temp1 = reshape(Temp, [NumChan*3, sampFreq]);

            % Combine 3 bytes to a 24 bit value
            data{i} = Temp1(ChInd,:)*65536 + Temp1(ChInd+1,:)*256 + Temp1(ChInd+2,:);

            % Search for the negative values and make the two's complement
            ind = find(data{i} >= 8388608);
            data{i}(ind) = data{i}(ind) - (16777216);

            % Plot the data received
            hold off
            for j = 1 : NumChan-4
                plot(data{i}(j,:)*ConvFact + OffsetPlot*(j-1));
                hold on
                ARV(j) = mean(abs(data{i}(j,:))) *0.08 - 22;
                if(ARV(j) < 0)
                    ARV(j) = 0;
                end
            end
            
            ARV
            
            drawnow;
        end   
    else       
        % If the low resolution mode (16 bits) is active

        % One second of data: 3 bytes * channels * Sampling frequency
        blockData = 2*NumChan*sampFreq;

        % Main plot loop
        for i = 1 : NumCycle

            i

            % Wait here until one second of data has been received
            while(t.BytesAvailable < blockData)
            end

            % Read one second of data into signed integer
            Temp = fread(t, NumChan*sampFreq, 'int16');
            data{i} = reshape(Temp, [NumChan, sampFreq]);

            % Plot the data received
            hold off
            for j = 1 : NumChan-4
                plot(data{i}(j,:)*ConvFact + OffsetPlot*(j-1));
                hold on                
                ARV(j) = mean(abs(data{i}(j,:))) *0.08 - 22;
                if(ARV(j) < 0)
                    ARV(j) = 0;
                end
            end

            ARV
            drawnow;
        end
    end
end

% Close the TCP socket
clear('t')

