function [rx,err,errstr]=sendmessage(H,message)

i=0;

% Tipos de erros
OK=0;
ERROR_REQ     =1;
ERROR_SOF     =2;
ERROR_EMPTYMSG=3;
ERROR_INV_RECV=4;
ERROR_INV_SEND=5;
ERROR_BCC_RECV=6;
ERROR_BCC_SEND=7;
ERROR_OPCODE  =8;
ERROR_INVREQ  =9;
ERROR_CPRESET =10;
ERROR_UNKNOWN =-1;

% Load global data
data;

% Validação dos argumentos
if (length(message)~=USART_SEND_LENGTH || (message(1)~=MESSAGE_REQ && message(1)~=MESSAGE_TEST));
    error('Mensagem a transmitir inválida!');
end

% Adicionar byte BCC
message=[message mod(sum(message),256)];

% Mensagem a transmitir
msg=uint8(message);

% Inicialização de variáveis
rx=[];
err=OK;              % Sem erro no inicio
errstr='OK';

tries=0;             % Número de tentativas
maxtries=10;         % Número máximo de tentativas

% A transmissão da mensagem de solicitação é repetida sempre que um erro
% ocorra
while (tries<=maxtries)
    
    % Reinicialização do estado de Erro
    err=OK;
    
    % Se na segunda tentativa (ou mais), reinicializar os buffers série
    if (tries>0)
        [status,errstr]=cportreset(H);
        if (status==0)
            err=ERROR_CPRESET;
            break;
        end
    end

    % Envio da mensagem de pedido
    n=cportwrite(H,msg);
    if (n>=0)
        msg=msg(n+1:end);
    end

    % Verificando se a transmissão falhou
    if (~isempty(msg))
        tries=tries+1;
        err=ERROR_REQ;
        continue;
    end
    
    % Recepção da mensagem de resposta
    while (tries<=maxtries)
    
        % Contagem do número de tentativas
        tries=tries+1;
    
        % Detecção do primeiro byte da frame
%         rx0=0;
%         tries2=0;
%         maxtries2=3;
%         status=0;
%         while (status==0 && tries2<=maxtries2)
%             [rx0,status]=cportgetint(H,1,1);
%             if (status==1 && uint8(intunsigned(rx0,8))<MESSAGE_MINTYPE), status=0; end
%             tries2=tries2+1;
%         end
%         if (status==0)
%             err=ERROR_SOF;
%             continue
%         end

        % Recepção de um array de bytes (bytes seguintes ao primeiro)
        [rx,status]=cportgetint(H,1,USART_RECV_LENGTH+1);
        %rx=[rx0; rx];
        
        % Se a recepção falhou, voltar a tentar a recepção
        if (status==0)
            err=ERROR_EMPTYMSG;
            continue
        end
        
        % Neste ponto do programa, é garantido que uma mensagem série foi
        % obtida

        % Ajuste da mensagem recebida
        rx = uint8(intunsigned(rx,8))';

        % Cálculo do BCC da mensagem recebida
        bcc=mod(sum(rx(1:end-1)),256);
        % Comparando o BCC code da mensagem com o último byte
        bcc_err=(bcc~=rx(end));
    
        % Erro de BCC na mensagem de resposta
        if (bcc_err==1)
            err=ERROR_BCC_RECV;
        % Erro de OpCode não coincidente
        elseif (rx(2)~=message(2))
            err=ERROR_OPCODE;
        % Mensagem transmitida com parâmetros inválidos
        elseif (rx(1)==MESSAGE_INVREQ)
            err=ERROR_INVREQ;
        % Mensagem transmitida com erro de BCC
        elseif (rx(1)==MESSAGE_INVALID)
            err=ERROR_BCC_SEND;
        % Master não consegue ler a mensagem de solicitação
        elseif (rx(1)==MESSAGE_ERROR)
            err=ERROR_INV_SEND;
        % Mensagem de natureza desconhecida
        elseif (rx(1)~=MESSAGE_SUCESS && rx(1)~=MESSAGE_TEST)
            err=ERROR_INV_RECV;
        end
        
        break;
    end
    
    %  Apenas sair do último loop, se tudo correu bem!
    if (err==OK), break, end

    % Preparação da mensagem a retransmitir
    msg=uint8(message);
end

if (tries>1)
    disp 'XXXXXXXXXXXXXXXXXXXXXX TRIES>1 XXXXXXXXXXXXXXXXXXXX'
    tries
end

% Preparação da mensagem de saída
rx=rx(1:end-1);

% Mensagem de erro
if (err~=OK)
    switch err
        case ERROR_REQ
            errstr='Mensagem de solicitação não transmitida!';
        case ERROR_SOF
            errstr='Primeiro byte não detectado!';
        case ERROR_EMPTYMSG
            errstr='Impossivel obter resposta!';
        case ERROR_INV_RECV
            errstr='Mensagem de resposta inválida!';
        case ERROR_INV_SEND
            errstr='Mensagem de solicitação não recebida com sucesso pelo Master!';
        case ERROR_BCC_RECV
            errstr='Mensagem de resposta com erro de BCC!';
        case ERROR_BCC_SEND
            errstr='Mensagem de solicitação com erro de BCC no Master!';
        case ERROR_OPCODE
            errstr='Byte de tipo (OpCode) não coincidente!';
        case ERROR_INVREQ
            errstr='Mensagem com parametros invalidos!';
        case ERROR_CPRESET
            errstr=['Erro na reinicialização dos buffers série: ',errstr];
        otherwise
            errstr='Erro desconhecido!';
    end
    
    % Reinicializar comunicações
    cportreset(H);
end