Há algum tempo venho pensado numa forma de transmitir um variável tipo float do PC para o arduino, com o menor número de bytes possível, e alguns da comunidade tem tido interesse em gravar na EEPROM do arduino um float. Cheguei a uma conclusão e queria compartilhar com os colegas.
Nesse texto mostrarei como usar essa estratégia para escrever na EEPROM do arduino um float de valor qualquer, e fazer a leitura.
Criei a seguinte função para escrita:
int escrita(float num,int endereco){
float *Pnum;
char *pont;
Pnum = #
pont = (char*)Pnum;
int j = 0;
for(int i = endereco; i<=endereco + 3; i++)
{
EEPROM.write(i,*(pont + j));
}
return (endereco + 4);
}
Essa função tem dois argumentos óbvios, o float a ser gravado e o endereço.
Só que na EEPROM só se pode gravar um byte de cada vez, assim como na comunicação serial, só se pode transmitir um byte de cada vez, Porém um float é representado por 4 bytes, o que fazer?
Que tal “quebrar” ou dividir o float em nível de bytes. É isso que a função faz.
Primeiro é declarado um ponteiro do tipo float que vai receber o endereço que corresponde aos 4 bytes da variável num.Se esse ponteiro for incrementado ele irá avançar 4 bytes.
Mas se for usado um cast (char*) e o resultado atribuído a outro ponteiro desta vez um do tipo char (1 byte), no caso com nome pont, o incremento deste ponteiro irá apontar para o segundo byte de num.
pont = endereço do 1º byte.
pont+1 = endereço do 2º byte.
pont +2 = endereço do 3º byte.
pont+3 = endereço do 4º byte.
Como o que nos interessa é o valor então:
*pont = valor do 1º byte.
*(pont+1) = valor do 2º byte.
*(pont +2) = valor do 3º byte.
*(pont+3) = valor do 4º byte.
Então seguindo essa ideia é usado o um laço for para gravar byte a byte na EEPROM.
A função retorna o próximo endereço livre.
float leitura(int endereco)
{
float num2 = 0;
float *Pnum2;
char *pont2;
Pnum2 = &num2;
pont2 = (char*)Pnum2;
int j = 0;
for(int i = endereco; i<=endereco + 3; i++)
{
*(pont2 + j) = EEPROM.read(i);
j++;
}
return num2;
}
Na leitura a ideia é a mesma. Aqui a variável num2 é composta byte a byte para formar o float resultante.
Essa estratégia funciona pra qualquer tipo, int, long, Double, etc. Basta adaptar os tipos dos ponteiros.
----
Tags:
Olha só um float é representado por 4 bytes se a intensão é transmitir este float usando a menor quantidade de bytes possível então a melhor forma seria transformar o float em uma sequencia de bytes e depois transmitir e em seguida fazer a conversão, veja como:
Também pode ser feito assim:
union acesso_float { float f ; int b[4]; }; //declaração de struct
union acesso_float x_f ;
uso: x_f .float = variavel_float;
but_tx[n+0] = x_f.b[0];
...
but_tx[n+3] = x_f.b[3];
Não tinha que ser byte b[4] ou char b[4]?
Digo isso porque um int tem mais de um byte.
me desculpe errei, é char b[4].
Sim foi o que fiz no código que postei no github
para falar a verdade só precisava de duas linhas para fazer isto:
char * floatb;
float number;
number = 100.25;
floatb = (char *)(&number);
Só isto já basta
Show isso mesmo,tambem achei bem interessante o método do Valter.
vlw pela força.
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por