Oi, boa noite, tenho um problema, estou recebendo um dado por serial,  e preciso separar esse dado en dois bytes.

vou colar parte do codigo:

por serial recebo:

unsigned int corriente_carga;

exemplo:

corriente_carga=45

esse valor vou converter em hexadecimal 45=0x2D, logo preciso separar para 2 bytes para enviar por can. 

con este codigo:

// Send CAN Message
int SendCAN(){
                        CAN_frame_t tx_frame;
                        tx_frame.FIR.B.FF = CAN_frame_std;
                        tx_frame.MsgID = 0x386;         // ID
                        tx_frame.FIR.B.DLC = 8; / 
                        tx_frame.data.u8[0] = corriente_desc_byte1; 
                        tx_frame.data.u8[1] = corriente_desc_byte2;
                        tx_frame.data.u8[2] = voltajemax_byte1;
                        tx_frame.data.u8[3] = voltajemax_byte2;
                        tx_frame.data.u8[4] = voltajemin_byte1;
                        tx_frame.data.u8[5] = voltajemin_byte2;
                        tx_frame.data.u8[6] = corrientecarga_byte1;
                        tx_frame.data.u8[7] = corrientecarga_byte2;
                      ESP32Can.CANWriteFrame(&tx_frame);

}

tem idea como fazer isso? agradeço sua ajuda!! 

Exibições: 687

Responder esta

Respostas a este tópico

Boa noite,

Não entendi.

0x2D corresponde à um byte. 

Coloca o primeiro Byte como 0x00. 

CAN-BUS Shield Hookup Guide

https://learn.sparkfun.com/tutorials/can-bus-shield-hookup-guide?_g...

Obrigado José Gustavo! é boa a informação, estou fazendo um projeto parecido, mas estou usando esp32.

0x2D corresponde à um byte.   ------------> foi um exemplo, mas não tenho conocimento bom de manipulação de dados em arduino. só queria demostrar que preciso separar o valor hexadecimal em 2 bytes e colocar em 2 variavel

diferentes.

de aqui a pouco daré aporte para este fórum, como vocês tambem fazen

olá novamente Gonzalez.

      Parece que vc tem feito seus Sistemas com uma boa quantidade de "fragmentos de código".  Não há nada de errado com isso. Mas também sempre irão aparecer alguns problemas os quais vc irá enfrentar, como é o caso desse atual. A impressão é que a parte que faz o que vc deseja, ficou em algum outro lugar no código original que vc usou como "base".

      Bem, de todo, essa é uma boa oportunidade de mostrar a forma como isso deve ser feito. Veja na figura  a seguir, onde ressalto na cor verde as duas linhas (a 14 e a 16), que vc precisa acrescentar:

(clique na figura para "zoom")

      Na figura anterior,  vc que na linha 14, antes da variável "corriente_carga",  há o "casting"  "byte" (entre parenteses).  Isto é necessário, pois torna a conversão independente de eventuais  "caprichos" do Compilador C++.   Já na linha 16antes da variável "corriente_carga",   há  o  "casting"  "unsigned int" (entre parenteses).  Isto também é necessário, pelo mesmo motivo anterior (tornar a conversão independente de eventuais "caprichos" do Compilador C++).

      E cada um dos Bytes a que vc se refere, são chamados de LSB (Least Significant Byte) e MSB (Most Significant Byte), escritos em letras maiúsculas.  Não confundir com as siglas em minúsculo  "lsb" e "msb",  onde o "b" se refere a "bit" e não a Byte.

      Espero ter ajudado.

      Abrçs,

      Elcids

Oi Elcids! muito obrigado pela ajuda, vou testar e te aviso. estou usando o codigo de exemplo da libraries esp32can-master (esp32can_basic.ino), preciso transmitir dados por CAN. tenho outra dúvida, tenho pouco conocimento teoricos em converter dados. coisas que fico confundido.

pergunto:

eu defino a variavel "corriente_carga" como

unsigned int corriente_carga;    (ela é uma variavel de 16 bits (2 bytes) ou uma variavel de 1 bytes?)

nota: em meu codigo já esta definido unsigned int corriente_carga;

obrigado pela ajuda

Anexos

olá Gonzalez.

 

      Sobre sua dúvida:  na Linguagem C/C++,  o "tamanho" do tipo "unsigned int", é dependente da Plataforma para a qual o Compilador  foi escrito.  No Arduino, normalmente o "unsigned int"  tem o tamanho de 16 bits (dois Bytes). O mesmo vale para o tipo original "int".  Mas isso pode gerar alguma confusão, pois afinal o ESP32 (além dos ARMs implementados no Arduino) é uma CPU de 32 bits.  Para independer da Plataforma,  a Linguagem C/C++  padrão  tem o tipo  "short",  que será sempre de 16 bits (seja um código escrito para um Arduino, para um PIC, ou mesmo para um sofisticadíssimo x86).  Ou seja,  se vc quer garantir que sua variável seja sempre de 16 bits, use o tipo "short"  ou "unsigned short".  O "short" representa números entre -32768 e +32767, enquanto o "unsigned short" representa números entre  0  e 65535.  Ou seja, no Arduino é a mesma faixa de representação do "int" e "unsigned  int", respectivamente.

      Sobre a conversão para os dois bytes separados,  faça como mostrei na figura do post anterior, que deverá funcionar perfeitamente.  Mas caso vc deseje, pode também mudar o tipo da sua variável "corriente_carga"  para "unsigned short",  que o resultado final será o mesmo.

      Abrçs

      Elcids

Oi Elcids, muito obrigado, ficou claro sua explicação.

outra coisa: 

Eu preciso que "corriente_carga_byte1" seja hexadecimal para poder enviar por CAN.

NOTA: JÁ FIZ ASIM PARA TUDOS OS DADOS QUE VOU ENVIAR E SEPARA EM DOIS BYTES:

volt_celda_maxByte1=(byte)tempvolt_celda_max;
volt_celda_maxByte2=(unsigned short)tempvolt_celda_max>>8;

Gostaria saber se posso converter short para hexadecimal asim:

int SendCAN(){
CAN_frame_t tx_frame;
tx_frame.FIR.B.FF = CAN_frame_std;
tx_frame.MsgID = 0x386;                            // ID
tx_frame.FIR.B.DLC = 8;  
tx_frame.data.u8[0] = String(corriente_descByte1,HEX); 
tx_frame.data.u8[1] = String(corriente_descByte2,HEX); 
tx_frame.data.u8[2] = String(corriente_cargaByte1,HEX);
tx_frame.data.u8[3] = String(corriente_cargaByte2,HEX); 
tx_frame.data.u8[4] = String(volt_celda_minByte1,HEX);
tx_frame.data.u8[5] = String(volt_celda_minByte2,HEX);
tx_frame.data.u8[6] = String(volt_celda_maxByte1,HEX) ;
tx_frame.data.u8[7] = String(volt_celda_maxByte2,HEX);
ESP32Can.CANWriteFrame(&tx_frame);

}

olá novamente Gonzalez.

      Rapaz, agora vc fez uma confusão daquelas.

      Vou tentar esclarecer, e tentarei fazer isso via alguns exemplos simples. Mas não é uma tarefa tão fácil mostrar isso, porque pelo que vc postou acima,  fica claro que vc não conhece os formatos binários básicos que são codificados em Linguagens como C/C++ (e uma infinidade de outras). Mas vamos ver.

      Veja a linha a seguir, que está dentro da sua função "SendCAN" conforme eu te mostrei no post inicial:

      tx_frame.data.u8[6] = corrientecarga_byte1;

      Nesta linha Gonzalez,  o "tx_frame.data.u8[6]"   já está recebendo um valor Hexadecimal,  e este valor vem da variável "corrientecarga_byte1".  Eu sei que para vc pode parecer estranho, mas vou tentar esclarecer.  Este valor Hexadecimal  é um "binário puro", ou seja composto de "1s" e "0s". Ocorre que um valor Hexadecimal só existe para facilitar para nós humanos, a representação dessa composição de "1s" e "0s". Para uma Máquina,  valores Hexadecimais não tem sentido.  A representação Hexadecimal só "existe" para nós humanos.

      Em outras palavras:  nós humanos é que "enxergamos" um valor em Hexadecimal, pois dentro de uma Máquina Digital,  este valor sempre estará em Binário.

      E no caso do "tx_frame.data.u8[6]",  só é possível armazenar um único Byte.  Eu posso afirmar isso, porque já olhei a definição do "CAN_frame_t"  na biblioteca onde este "tipo" é definido (no arquivo "CAN.h").  Não vou colocar a definição do "CAN_frame_t"  aqui, pois provavelmente só irá trazer outras dúvidas desnecessárias neste momento, e não irá ajudar.

      Mas vc não irá obter o resultado que vc espera, quando vc faz o que vc postou acima, que mostro a seguir:

    tx_frame.data.u8[6] = String( volt_celda_maxByte1, HEX );

      Ocorre que o resultado de String( volt_celda_maxByte1, HEX ), poderá resultar em um Byte, ou dois Bytes, ou mesmo três ou mais Bytes. Não posso afirmar quantos Bytes serão, por dois motivos:  primeiro não sei qual o tipo da variável "volt_celda_maxByte1" pois vc não informou, segundo: o número de Bytes resultantes depende do próprio valor armazenado na variável.  Vc pode conferir isso neste link do Arduino:   "tipo String"

      Mas o importante aqui, é vc perceber que como o resultado de String(volt_celda_maxByte1, HEX)  pode ter tamanhos diferentes, já levanta a bandeira de que não tem muito sentido tentar armazenar este resultado em "tx_frame.data.u8[6]",  pois este último só comporta um único Byte.  Mas não é isso o mais trágico da coisa.  Ocorre que o valor resultante será uma representação ASCII do valor Hexadecimal,  e não o valor Hexadecimal "real" (ou "binário puro").  Estes valores ASCII  só acabam tendo sentido quando se manipulam caracteres, seja para efeito de representar mensagens escritas, seja para exibir estas mensagens em alguma tela qualquer (papel ou Display).

      Então Gonzalez,  o caminho não é por aí.  E se eu entendi o que vc precisa fazer,  então basta vc fazer como no exemplo que mostrei no primeiro post.   Nada a ver com essa conversão para String.

      Há até uma possibilidade de se usar o formato ASCII, e dessa forma usar a conversão para String.  Porém seria tremendamente limitado para armazenar isso em  um "CAN_frame_t",  tornando a coisa muito inadequada.

      E afinal de contas,  CAN  é usado para comunicação entre Máquinas.  Então o formato mais adequado é de fato em "binário puro".  Ou seja, basta que vc faça como mostrei desde o início.

      Um conselho:  busque um livro de Sistemas Digitais para que vc possa aprender e se familiarizar com a codificação binária e afins.  Há inúmeros livros disponíveis na Internet gratuitamente.  Todos eles mostram os diversos "formatos"  que usamos na codificação binária, e geralmente isto é sempre no primeiro capítulo destes livros (ou seja, vc não precisa ler o livro inteiro, apenas o primeiro capítulo).

      Um livro da minha época que recomendo,  é o "Elementos de Eletrônica Digital"  dos autores "Capuano/Idoeta".  Mas este não é gratuito, embora vc encontre o download do PDF dele na Internet.

      Abrçs,

      Elcids

Eu gostei da sua explicação,! Obrigado ficou claro!

já programei pic em ensamblador a quase 15 anos, agora estou començando de novo em arduino, agora sou um menino programando.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço