teste de publish

Dependencies:   DS1820 HighSpeedAnalogIn devices mbed

modbusMaster1.cpp

Committer:
brunofgc
Date:
2018-06-08
Revision:
38:07d3907b74e5
Parent:
37:0e95c85f0160

File content as of revision 38:07d3907b74e5:

#include "modbusMaster1.h"
#define maxRetentativas 5
#define maxDelayEntreTentativas 100
//RAD
enum {
    READ_COIL_STATUS = 1,
    READ_INPUT_STATUS,
    READ_HOLDING_REGISTERS,
    READ_INPUT_REGISTERS,
    WRITE_SINGLE_COIL,
    WRITE_SINGLE_REGISTER,
    WRITE_MULTIPLE_COILS,
    WRITE_MULTIPLE_REGISTERS
}modBusFunctions;

uint16_t modBusMaster1::T3_5;
uint16_t modBusMaster1::T1_5;
bool modBusMaster1::pacoteEmEspera;
bool modBusMaster1::pacoteEmEsperaValido;
uint16_t modBusMaster1::MODBUS_TIMEOUT;
bool modBusMaster1::startThreadModBusMaster;
Serial *modBusMaster1::serModBus;
DigitalOut *modBusMaster1::de;
uint16_t modBusMaster1::MODBUS_SERIAL_BAUD;

uint8_t modBusMaster1::buffer[maxLenBufModBus]; //Buffer in e out;
uint16_t modBusMaster1::index;

//Timer
osTimerId modBusMaster1::timer_pacote;
osTimerDef(timerProcessaPacoteModBusMaster1,modBusMaster1::processaPacote);
//Timer

void modBusMaster1::processaPacote(void const *){
    //Validando CRC
    uint16_t crc_calculado;
    uint16_t crc_lido;
    
    if(debug){
        //Lido resposta DEBUG
        pc.printf("Lido de resposta modbus <");
        for(crc_lido = 0; crc_lido < modBusMaster1::index; crc_lido++){
            pc.printf("%02X ",modBusMaster1::buffer[crc_lido]);
        }
        pc.printf(">.\n");
    }
    if(modBusMaster1::index<3){
        modBusMaster1::pacoteEmEspera=false;
        return;
    }
    
    crc_calculado = modBusMaster1::CRC16(modBusMaster1::buffer,modBusMaster1::index-2);
    crc_lido = (modBusMaster1::buffer[modBusMaster1::index-2]<<8)+(modBusMaster1::buffer[modBusMaster1::index-1]);
    
    modBusMaster1::pacoteEmEspera=true;
    if(crc_calculado == crc_lido){
        modBusMaster1::pacoteEmEsperaValido=true;
    }
    //pc.printf("crc_calculado = 0x%02x, crc_lido = 0x%02x.\n",crc_calculado,crc_lido);
}

uint16_t modBusMaster1::CRC16(uint8_t *buf,uint16_t len){
  uint16_t crc = 0xFFFF;  
  uint16_t pos;
  uint16_t i;
  for (pos = 0; pos < len; pos++) {
    crc ^= buf[pos];          // XOR byte into least sig. byte of crc
 
    for (i = 8; i != 0; i--) {    // Loop over each bit
      if ((crc & 0x0001) != 0) {      // If the LSB is set
        crc >>= 1;                    // Shift right and XOR 0xA001
        crc ^= 0xA001;
      }
      else                            // Else LSB is not set
        crc >>= 1;                    // Just shift right
    }
  }
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
  return ((crc<<8)+(crc>>8)); 
}

void modBusMaster1::modBusMaster(Serial *serial,uint32_t baud,DigitalOut *pinDe){
    modBusMaster1::serModBus = serial;     
    modBusMaster1::de = pinDe;
    modBusMaster1::index = 0;
    *modBusMaster1::de = 0;
    modBusMaster1::serModBus->attach(&modBusMaster1::processaCaractere);
    modBusMaster1::serModBus->baud(baud);
    modBusMaster1::pacoteEmEspera = false;    
    //Criando timer_pacote
    modBusMaster1::timer_pacote = osTimerCreate(osTimer(timerProcessaPacoteModBusMaster1),osTimerOnce,NULL);              
}

void modBusMaster1::setBaud(uint32_t baud){    
    modBusMaster1::serModBus->baud(baud);    
    if (baud > 19200){
          modBusMaster1::T1_5 = 750; 
          modBusMaster1::T3_5 = 1750; 
      }else {
          modBusMaster1::T1_5 = 15000000/baud; 
          modBusMaster1::T3_5 = 35000000/baud; 
      }
}



void modBusMaster1::processaCaractere(){
    uint32_t RBR = LPC_UART1->RBR;      //Reset RBR interrupt flag e captura o caractere entrante
    modBusMaster1::buffer[modBusMaster1::index]=RBR;
    modBusMaster1::index++;
    if(modBusMaster1::index>=maxLenBufModBus){
       modBusMaster1::index=modBusMaster1::index-1; 
    }
    modBusMaster1::startThreadModBusMaster=true;
    osSignalSet(idThreadTimers, 0x1); //Envia sinal para a thread de manipulação dos timers para ativar os timers agendados               
    //comLedIn=!comLedIn;
    //pc.printf("%c",RBR);
}

uint16_t modBusMaster1::sendFrame(uint16_t tamBytes){
    uint16_t timeout = modBusMaster1::MODBUS_TIMEOUT;
    timeout /=10;
    uint16_t i;
        
    if(debug){
        //DEBUG Mostrando o que é enviado via modbus
        pc.printf("Frame enviado (hexa) <");
        for(i=0;i<tamBytes;i++){       
            pc.printf("%02x ",modBusMaster1::buffer[i]);                
        }                
        pc.printf(">.\n");
    }
    
    //osDelay(5);    
    
    modBusMaster1::pacoteEmEspera = false;
    modBusMaster1::index=0;
    *modBusMaster1::de=1;    
    //wait_us(1750);    
    osDelay(1);    
    for(i=0;i<tamBytes;i++){       
        modBusMaster1::serModBus->putc(modBusMaster1::buffer[i]);        
        //wait_us(750);            
        while( 
        ((LPC_UART1->LSR >> 6) &0x1)
         == 0 );
         //wait_us(modBusMaster1::T1_5);
    }                
    //wait_us(1750);    
    //osDelay(1);    
    *modBusMaster1::de=0;
    
    while((timeout>0)&&(modBusMaster1::pacoteEmEspera!=true)){
        osDelay(10);        
        //wait_us(1000);
        timeout--;   
    }         
    wait_us(modBusMaster1::T3_5*2);
    return timeout;
}

uint8_t modBusMaster1::readRegister16BIT(uint8_t enderecoSlave,uint8_t funcao,uint16_t registrador,uint16_t qtdRegistros,uint16_t *var){
    union{
       char c[2];
       uint16_t v; 
    }u;
    uint16_t crc;
    uint16_t qtd_dados_recebidos;    
    uint16_t i;
    uint8_t result;
    
    for(i=0;i<qtdRegistros;i++){
        var[i]=NULL;
    }

//-----------------Bloco de tentativas---------------------    
    uint16_t retentativas = maxRetentativas+1;
    uint16_t delayEntreTentativas = maxDelayEntreTentativas;
    while(retentativas){    
        modBusMaster1::buffer[0]=enderecoSlave;
        modBusMaster1::buffer[1]=funcao;
        modBusMaster1::buffer[2]=registrador>>8;
        modBusMaster1::buffer[3]=(registrador & 0xFF);
        modBusMaster1::buffer[4]=qtdRegistros>>8;
        modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
        
        crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
        
        modBusMaster1::buffer[6]=crc>>8;
        modBusMaster1::buffer[7]=(crc & 0xFF);       

        if(!modBusMaster1::sendFrame(8)){
            osDelay(delayEntreTentativas);
            retentativas--;
            if(debug){
                //DEBUG Mostrando o que é enviado via modbus
                pc.printf("Retentativa de comando modbus.\r\n");
            }
            if(retentativas==0){
                //erro de timeout certamente
                pc.printf("Erro de timeout.\n");
                modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
                modBusMaster1::index = 0; 
                return 254;                
            }            
        }else{
            //Chegou pacote, vamos ver se é valido
            retentativas = 0;            
         }
    }    
    if(!modBusMaster1::pacoteEmEsperaValido){
        pc.printf("Erro de CRC.\n");
        modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
        modBusMaster1::index = 0;
        return 255;    
    }
//-----------------Bloco de tentativas---------------------    
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
        qtd_dados_recebidos = modBusMaster1::buffer[2]/2;    
        for(i=0;i<qtd_dados_recebidos;i++){        
            u.c[1]=modBusMaster1::buffer[(i*2)+3];
            u.c[0]=modBusMaster1::buffer[(i*2)+4];
            var[i]=u.v;
        }
        result = 0;
     }
    
    
    
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;    
}

uint8_t modBusMaster1::writeSingleCoil(uint8_t enderecoSlave,uint16_t registrador,bool var){
    uint16_t crc;
    uint16_t estadoSetado;    
    uint8_t result = 0;
    //-----------------Bloco de tentativas---------------------    
    uint16_t retentativas = maxRetentativas+1;
    uint16_t delayEntreTentativas = maxDelayEntreTentativas;
    while(retentativas){
//------------Bloco de construcao de frame request----------    
        modBusMaster1::buffer[0]=enderecoSlave;
        modBusMaster1::buffer[1]=5;
        modBusMaster1::buffer[2]=registrador>>8;
        modBusMaster1::buffer[3]=(registrador & 0xFF);
        
        if(var){
            modBusMaster1::buffer[4]=0xFF;
            modBusMaster1::buffer[5]=0x00;
            estadoSetado = 0xFF00;
                
        }else{
            modBusMaster1::buffer[4]=0x00;
            modBusMaster1::buffer[5]=0x00;    
            estadoSetado = 0x0000;
         }
        
        
        crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
        
        modBusMaster1::buffer[6]=crc>>8;
        modBusMaster1::buffer[7]=(crc & 0xFF);       
//------------Bloco de construcao de frame request----------    
        if(!modBusMaster1::sendFrame(8)){
            osDelay(delayEntreTentativas);
            retentativas--;
            if(debug){
                //DEBUG Mostrando o que é enviado via modbus
                pc.printf("Retentativa de comando modbus.\r\n");
            }
            if(retentativas==0){
                //erro de timeout certamente
                pc.printf("Erro de timeout.\n");
                modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
                modBusMaster1::index = 0; 
                return 254;                
            }            
        }else{
            //Chegou pacote, vamos ver se é valido
            retentativas = 0;            
         }
    }    
    if(!modBusMaster1::pacoteEmEsperaValido){
        pc.printf("Erro de CRC.\n");
        modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
        modBusMaster1::index = 0; 
        return 255;    
    }
//-----------------Bloco de tentativas---------------------        
    

    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
        if(
            (((modBusMaster1::buffer[2]<<8)+(modBusMaster1::buffer[3]))==registrador)
                &&
            (((modBusMaster1::buffer[4]<<8)+(modBusMaster1::buffer[5]))==estadoSetado) 
        ){
            result=0;
         }else{
            result=253;   
          }
     }        
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;    
}

uint8_t modBusMaster1::readCoils(uint8_t enderecoSlave,uint16_t registrador,uint16_t qtdRegistros,bool *var){
    uint16_t crc;
    uint8_t result;    
    uint16_t i;
//-----------------Bloco de tentativas---------------------    
    uint16_t retentativas = maxRetentativas+1;
    uint16_t delayEntreTentativas = maxDelayEntreTentativas;
    while(retentativas){
//------------Bloco de construcao de frame request----------    
        
        modBusMaster1::buffer[0]=enderecoSlave;
        modBusMaster1::buffer[1]=1;
        modBusMaster1::buffer[2]=registrador>>8;
        modBusMaster1::buffer[3]=(registrador & 0xFF);
        modBusMaster1::buffer[4]=qtdRegistros>>8;
        modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);    
        
        crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
        
        modBusMaster1::buffer[6]=crc>>8;
        modBusMaster1::buffer[7]=(crc & 0xFF);       
    
//------------Bloco de construcao de frame request----------    
        if(!modBusMaster1::sendFrame(8)){
            osDelay(delayEntreTentativas);
            retentativas--;
            if(debug){
                //DEBUG Mostrando o que é enviado via modbus
                pc.printf("Retentativa de comando modbus.\r\n");
            }
            if(retentativas==0){
                //erro de timeout certamente
                pc.printf("Erro de timeout.\n");
                modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
                modBusMaster1::index = 0; 
                return 254;                
            }            
        }else{
            //Chegou pacote, vamos ver se é valido
            retentativas = 0;            
         }
    }    
    if(!modBusMaster1::pacoteEmEsperaValido){
        pc.printf("Erro de CRC.\n");
        modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
        modBusMaster1::index = 0; 
        return 255;    
    }
//-----------------Bloco de tentativas---------------------        
            
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{    
        if(
            modBusMaster1::buffer[2] == (1+((uint16_t)(qtdRegistros/8)))
        ){
            //Bloco de leitura das coils
            for(i=0;i<qtdRegistros;i++){
                var[i] = (
                            (modBusMaster1::buffer[(i/8)+3] & ( 0x1 << (i%8) )) >0
                         );    
            }
            result = 0;
         }else{            
            result = 253; 
          }
    }
    
    
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;    
}
uint8_t modBusMaster1::readRegister32BIT(uint8_t enderecoSlave,uint8_t funcao,uint16_t registrador,uint16_t qtdRegistros,uint32_t *var){
    union{
       char c[4];
       uint32_t v; 
    }u;
    uint16_t crc;
    uint16_t qtd_dados_recebidos;    
    uint16_t i;
    uint8_t result;
    
    for(i=0;i<qtdRegistros;i++){
        var[i]=NULL;
    }

//-----------------Bloco de tentativas---------------------    
    uint16_t retentativas = maxRetentativas+1;
    uint16_t delayEntreTentativas = maxDelayEntreTentativas;
    while(retentativas){
//------------Bloco de construcao de frame request----------    
        
        modBusMaster1::buffer[0]=enderecoSlave;
        modBusMaster1::buffer[1]=funcao;
        modBusMaster1::buffer[2]=registrador>>8;
        modBusMaster1::buffer[3]=(registrador & 0xFF);
        modBusMaster1::buffer[4]=qtdRegistros>>8;
        modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
        
        crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
        
        modBusMaster1::buffer[6]=crc>>8;
        modBusMaster1::buffer[7]=(crc & 0xFF);       
    
//------------Bloco de construcao de frame request----------    
        if(!modBusMaster1::sendFrame(8)){
            osDelay(delayEntreTentativas);
            retentativas--;
            if(debug){
                //DEBUG Mostrando o que é enviado via modbus
                pc.printf("Retentativa de comando modbus.\r\n");
            }
            if(retentativas==0){
                //erro de timeout certamente
                pc.printf("Erro de timeout.\n");
                modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
                modBusMaster1::index = 0; 
                return 254;                
            }            
        }else{
            //Chegou pacote, vamos ver se é valido
            retentativas = 0;            
         }
    }    
    if(!modBusMaster1::pacoteEmEsperaValido){
        pc.printf("Erro de CRC.\n");
        modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
        modBusMaster1::index = 0; 
        return 255;    
    }
//-----------------Bloco de tentativas---------------------        
            
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
    
        qtd_dados_recebidos = modBusMaster1::buffer[2]/4;    
        for(i=0;i<qtd_dados_recebidos;i++){        
            u.c[3]=modBusMaster1::buffer[(i*4)+3];
            u.c[2]=modBusMaster1::buffer[(i*4)+4];
            u.c[1]=modBusMaster1::buffer[(i*4)+5];
            u.c[0]=modBusMaster1::buffer[(i*4)+6];
            var[i]=u.v;
        }
        result =0;
     }
    
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;    
}

uint8_t modBusMaster1::writeRegister16BIT(uint8_t enderecoSlave,uint16_t registrador,uint16_t qtdRegistros,uint16_t *var){    
    uint16_t i;
    uint16_t crc;
    uint8_t result;

//-----------------Bloco de tentativas---------------------    
    uint16_t retentativas = maxRetentativas+1;
    uint16_t delayEntreTentativas = maxDelayEntreTentativas;
    while(retentativas){
//------------Bloco de construcao de frame request----------    
    
        modBusMaster1::buffer[0]=enderecoSlave;
        modBusMaster1::buffer[1]=16;
        modBusMaster1::buffer[2]=registrador>>8;
        modBusMaster1::buffer[3]=(registrador & 0xFF);
        modBusMaster1::buffer[4]=qtdRegistros>>8;
        modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
        modBusMaster1::buffer[6]=qtdRegistros*2;       
        
        for(i=0;i<qtdRegistros;i++){
            modBusMaster1::buffer[(i*2)+7]=var[i]>>8;
            modBusMaster1::buffer[(i*2)+8]=var[i]&0xFF;
        }
        
        crc=modBusMaster1::CRC16(modBusMaster1::buffer,((qtdRegistros)*2)+7);
        
        modBusMaster1::buffer[(qtdRegistros*2)+7]=crc>>8;;
        modBusMaster1::buffer[(qtdRegistros*2)+8]=(crc & 0xFF);
        
//------------Bloco de construcao de frame request----------    
        if(!modBusMaster1::sendFrame((qtdRegistros*2)+9)){
            osDelay(delayEntreTentativas);
            retentativas--;
            if(debug){
                //DEBUG Mostrando o que é enviado via modbus
                pc.printf("Retentativa de comando modbus.\r\n");
            }
            if(retentativas==0){
                //erro de timeout certamente
                pc.printf("Erro de timeout.\n");
                modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
                modBusMaster1::index = 0; 
                return 254;                
            }            
        }else{
            //Chegou pacote, vamos ver se é valido
            retentativas = 0;            
         }
    }    
    if(!modBusMaster1::pacoteEmEsperaValido){
        pc.printf("Erro de CRC.\n");
        modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
        modBusMaster1::index = 0; 
        return 255;    
    }
//-----------------Bloco de tentativas---------------------            
        
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0;
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
    
        //Interpratando resposta
        if(((modBusMaster1::buffer[4]<<8)+(modBusMaster1::buffer[5]))!=qtdRegistros){
            return 253;
        }else{
            result = 0;
         }
    }
    return result;
}

uint8_t modBusMaster1::writeRegister32BIT(uint8_t enderecoSlave,uint16_t registrador,uint16_t qtdRegistros,uint32_t *var){    
    uint16_t i;
    uint16_t crc;
    uint8_t result;
    
//-----------------Bloco de tentativas---------------------    
    uint16_t retentativas = maxRetentativas+1;
    uint16_t delayEntreTentativas = maxDelayEntreTentativas;
    while(retentativas){
//------------Bloco de construcao de frame request----------        
    
        modBusMaster1::buffer[0]=enderecoSlave;
        modBusMaster1::buffer[1]=16;
        modBusMaster1::buffer[2]=registrador>>8;
        modBusMaster1::buffer[3]=(registrador & 0xFF);
        modBusMaster1::buffer[4]=qtdRegistros>>8;
        modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
        modBusMaster1::buffer[6]=qtdRegistros*4;       
        
        for(i=0;i<qtdRegistros;i++){
            modBusMaster1::buffer[(i*4)+7]=(var[i]>>24)&0xFF;
            modBusMaster1::buffer[(i*4)+8]=(var[i]>>16)&0xFF;
            modBusMaster1::buffer[(i*4)+9]=(var[i]>>8)&0xFF;
            modBusMaster1::buffer[(i*4)+10]=var[i]&0xFF;
        }
        
        crc=modBusMaster1::CRC16(modBusMaster1::buffer,((qtdRegistros)*4)+7);
        
        modBusMaster1::buffer[(qtdRegistros*4)+7]=crc>>8;;
        modBusMaster1::buffer[(qtdRegistros*4)+8]=(crc & 0xFF);
    
//------------Bloco de construcao de frame request----------    
        if(!modBusMaster1::sendFrame((qtdRegistros*4)+9)){
            osDelay(delayEntreTentativas);
            retentativas--;
            if(debug){
                //DEBUG Mostrando o que é enviado via modbus
                pc.printf("Retentativa de comando modbus.\r\n");
            }
            if(retentativas==0){
                //erro de timeout certamente
                pc.printf("Erro de timeout.\n");
                modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
                modBusMaster1::index = 0; 
                return 254;                
            }            
        }else{
            //Chegou pacote, vamos ver se é valido
            retentativas = 0;            
         }
    }    
    if(!modBusMaster1::pacoteEmEsperaValido){
        pc.printf("Erro de CRC.\n");
        modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
        modBusMaster1::index = 0; 
        return 255;    
    }
//-----------------Bloco de tentativas---------------------        
    
        
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0;
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
    
        //Interpratando resposta
        if(((modBusMaster1::buffer[4]<<8)+(modBusMaster1::buffer[5]))!=qtdRegistros){
            return 253;
        }else{
            result = 0;   
         }
    }
    return result;
}

uint8_t modBusMaster1::writeFloat(uint8_t enderecoSlave,uint16_t registrador,uint8_t qtdRegistros,float *var){    
    union{
       char c[4];
       float v;        
    }u;    
    uint16_t i;
    uint16_t crc;
    uint8_t result;
//-----------------Bloco de tentativas---------------------    
    uint16_t retentativas = maxRetentativas+1;
    uint16_t delayEntreTentativas = maxDelayEntreTentativas;
    while(retentativas){
//------------Bloco de construcao de frame request----------    
        
        modBusMaster1::buffer[0]=enderecoSlave;
        modBusMaster1::buffer[1]=16;
        modBusMaster1::buffer[2]=registrador>>8;
        modBusMaster1::buffer[3]=(registrador & 0xFF);
        modBusMaster1::buffer[4]=qtdRegistros>>8;
        modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
        modBusMaster1::buffer[6]=qtdRegistros*4;       
        
        for(i=0;i<qtdRegistros;i++){
            u.v = var[i];
            modBusMaster1::buffer[(i*4)+7]=u.c[3];
            modBusMaster1::buffer[(i*4)+8]=u.c[2];
            modBusMaster1::buffer[(i*4)+9]=u.c[1];
            modBusMaster1::buffer[(i*4)+10]=u.c[0];
        }
        
        crc=modBusMaster1::CRC16(modBusMaster1::buffer,((qtdRegistros)*4)+7);
        
        modBusMaster1::buffer[(qtdRegistros*4)+7]=crc>>8;;
        modBusMaster1::buffer[(qtdRegistros*4)+8]=(crc & 0xFF);

//------------Bloco de construcao de frame request----------    
        if(!modBusMaster1::sendFrame((qtdRegistros*4)+9)){
            osDelay(delayEntreTentativas);
            retentativas--;
            if(debug){
                //DEBUG Mostrando o que é enviado via modbus
                pc.printf("Retentativa de comando modbus.\r\n");
            }
            if(retentativas==0){
                //erro de timeout certamente
                pc.printf("Erro de timeout.\n");
                modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
                modBusMaster1::index = 0; 
                return 254;                
            }            
        }else{
            //Chegou pacote, vamos ver se é valido
            retentativas = 0;            
         }
    }    
    if(!modBusMaster1::pacoteEmEsperaValido){
        pc.printf("Erro de CRC.\n");
        modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
        modBusMaster1::index = 0; 
        return 255;    
    }
//-----------------Bloco de tentativas---------------------            

        
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0;
   
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{ 
        //Interpratando resposta
        if(((modBusMaster1::buffer[4]<<8)+(modBusMaster1::buffer[5]))!=qtdRegistros){
            return 253;
        }else{
            result = 0;   
         }
     }
    return result;
}

uint8_t modBusMaster1::readFloat(uint8_t enderecoSlave,uint8_t funcao,uint16_t registrador,uint16_t qtdRegistros,float *var){
    union {
        char c[4];
        float v;
    }u;
    uint16_t crc;
    uint16_t qtd_dados_recebidos;
    //void *p;
    uint16_t i; 
    uint8_t result;
    
    for(i=0;i<qtdRegistros;i++){
        var[i]=0.0;
    }

//-----------------Bloco de tentativas---------------------    
    uint16_t retentativas = maxRetentativas+1;
    uint16_t delayEntreTentativas = maxDelayEntreTentativas;
    while(retentativas){
//------------Bloco de construcao de frame request----------           
       
        modBusMaster1::buffer[0]=enderecoSlave;
        modBusMaster1::buffer[1]=funcao;
        modBusMaster1::buffer[2]=registrador>>8;
        modBusMaster1::buffer[3]=(registrador & 0xFF);
        modBusMaster1::buffer[4]=qtdRegistros>>8;
        modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
        
        crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
        
        modBusMaster1::buffer[6]=crc>>8;
        modBusMaster1::buffer[7]=(crc & 0xFF);       
    
//------------Bloco de construcao de frame request----------    
        if(!modBusMaster1::sendFrame(8)){
            osDelay(delayEntreTentativas);
            retentativas--;
            if(debug){
                //DEBUG Mostrando o que é enviado via modbus
                pc.printf("Retentativa de comando modbus.\r\n");
            }
            if(retentativas==0){
                //erro de timeout certamente
                pc.printf("Erro de timeout.\n");
                modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
                modBusMaster1::index = 0; 
                return 254;                
            }            
        }else{
            //Chegou pacote, vamos ver se é valido
            retentativas = 0;            
         }
    }    
    if(!modBusMaster1::pacoteEmEsperaValido){
        pc.printf("Erro de CRC.\n");
        modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
        modBusMaster1::index = 0; 
        return 255;    
    }
//-----------------Bloco de tentativas---------------------    
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
        qtd_dados_recebidos = modBusMaster1::buffer[2]/4;    
        for(i=0;i<qtd_dados_recebidos;i++){
            u.c[3]=modBusMaster1::buffer[(i*4)+3];
            u.c[2]=modBusMaster1::buffer[(i*4)+4];
            u.c[1]=modBusMaster1::buffer[(i*4)+5];
            u.c[0]=modBusMaster1::buffer[(i*4)+6];
            var[i]=u.v;
        }    
        result = 0;
     }
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;
}