from Longitudinal Redundancy Check for Modbus by Steven Edmund
Longitudinal Redundancy Check (LRC) for Modbus PLC Controllers using ASCII

LRC(out,mode)
function [report, string] = LRC(out,mode)
% [report, string] = LRC(out,mode)
% Calculate the Longitudinal redundnacy check of a series of hex numbers to
% be sent to Eaton PLC controller.  
%
% out is the string to either be checked (mode 1) or to have an LRC
% generated and appended (mode 2)
% Mode 1:  Report is 1 for LRC being correct, 0 for incorrect
% Mode 2: Report is 1 for no problems, 0 for error
%           string is the output to be written to the PLC
%
%  When the total addition in the LRC is greater then 8bits the LRC is
%  composed of the 2's complament of negation using the lowest 8 bits:

% LRC.m - The value appended to the end of each communication to assure 
% that the data received is not corrupted.  The LRC is the 2's compliment 
% negation of the sum.  When the total adition in the LRC constitutes a 
% number greater then 8bits only the lowest 8bits are used to compute the LRC. 
%  LRC.m has two modes, in mode 1 it compares the LRC received to one 
%  calculated and in mode 2 it calculates an LRC and appends it onto a 
%  string for outgoing communication.  LRC.m uses a try-catch structure 
%  to ensure that if an error occurs in calculating the LRC, possibly due 
%  to an unrecognized character being received, the program can continue.  
% 
% All Modbus communications are in Hex.  The modbus communication starts 
% with a ':' followed by the address of the device the communication is
%  meant for '01'.  Following the device number is the mode '02' 
%  (read multiple digital).  in the case of mode 2 this is followed by
%   the starting address '0800' and then the number of points to read 
%   '0028'  (40 points).  At the end of the communication is appended the 
%   Longitudinal Redundancy Check.
% 
% As mentioned previously, the included modbus programs were written for 
% a process control program to interface with specific variables on the PLC.  
% These addresses can be modified, however note that when changing any of 
% the strings to be sent to the PLC, the 2-byte Longitudinal redundancy 
% code must be updated.  This can be done using the code:
% [report,StringOut] = LRC(StringIn,2)
% where StringIn is the data to be written to the PLC without the LRC 
% i.e. [':','01','02','08','00','00','28']
% the returned variable StringOut contains the LRC appended string ':010208000028CD'.
% 




%Test Case: should return 1E
% out = ':01032021341A2C162D13240C8023281F401B5800000000000000000000000000000000';
% mode = 2;

% Check that the LRC of a message is valid
try

if mode == 1  % mode for checking if LRC is correct

    Lout = length(out);   % length of incoming string
    outLRC = out(Lout-3:Lout-2);  % last two characters are CR/LF
    outmess = out(1:Lout-4);  % message portion of the sting to analyze
    
    %Put each Hex set in a different row
    for j = 1:(length(outmess)-1)/2
        mes(j,:) = outmess(2*j:2*j+1);
    end

    decmes = hex2dec(mes);  % convert to dec
    sumdec = sum(decmes);  %sum the decimal values
    hexsum = dec2hex(sumdec,4); % generate a 4 digit hex number
    binsum = dec2bin(sumdec,8); % genearte 8bit binary number

    % Handle the number being large
    if length(binsum) > 8
        binsum = binsum(length(binsum)-7:length(binsum));  % grab the last 8 bit binary number
    end
    
	% Perform the inversion of 1's and 0's
    empbin = ['00000000'];  % start with an empty binary number
    firstfind = 0;
    for i = 1:length(binsum)
        if binsum(end+1-i) == '0'
            if firstfind == '0'
                %leave as 0			% leave first 0's found as 0
            elseif firstfind == 1
               empbin(end+1-i) = '1';    %swap a 1 for 0
            end
        elseif binsum(end+1-i) == '1'
            if firstfind == 0
                empbin(end+1-i) = '1';
                firstfind = 1;
            elseif firstfind == 1
                empbin(end+1-i) = '0';
            end
        else
                disp('Error in LRC calculation')
        end
    end

    CalcLRC = bin2dec(empbin);  % LRC calculated by the program
    
    if CalcLRC == hex2dec(outLRC)  % compare the caluclated and given LRC
        report = 1;  % LRC is correct
    else
        disp(['LRC Inconsistant, PLC gives: ',num2str(hex2dec(outLRC)),...
            ' Calculated LRC is: ',num2str(CalcLRC)])
        report = 0;
    end
    string = out;

    
% Calculate the LRC for a string: output is the string with LRC appended    
elseif mode == 2
    %Put each Hex set in a different row
    for j = 1:(length(out)-1)/2
        mes(j,:) = out(2*j:2*j+1);
    end

    decmes = hex2dec(mes);  % convert to dec
    sumdec = sum(decmes);  %sum the decimal values
    hexsum = dec2hex(sumdec,4); % generate a 4 digit hex number
    binsum = dec2bin(sumdec,8); % genearte 8bit binary number
    
    % Handle the number being large
    if length(binsum) > 8
        binsum = binsum(length(binsum)-7:length(binsum));
    end
    
    empbin = ['00000000'];  % start with an empty binary number
    
    firstfind = 0;
    for i = 1:length(binsum)
        if binsum(end+1-i) == '0'
            if firstfind == '0'
                %leave as 0
            elseif firstfind == 1
               empbin(end+1-i) = '1';    %swap a 1 for 0
            end
        elseif binsum(end+1-i) == '1'
            if firstfind == 0
                empbin(end+1-i) = '1';
                firstfind = 1;
            elseif firstfind == 1
                empbin(end+1-i) = '0';
            end
        else
                disp('Error in LRC calculation')
        end
    end

    CalcLRC = dec2hex(bin2dec(empbin),2);  % LRC calculated by the program
    Lout = length(out);
    out(Lout+1:Lout+2) = CalcLRC;
    string = out;
    report = 1;
else
    disp(['Improper selection of mode in LRC.m to: ',num2str(mode)])
    report = 0;
    string = '';
end
    
    
catch
    report = 0;
    string = [''];
    disp('Catch in LRC')
end

    
    
    
    


Contact us at files@mathworks.com