Pessoal,

 

Estou com uma dúvida aqui: como eu envio um valor, por exemplo: 1.4523344 do arduino para uma linguagem de programação, no caso Java.

Eu já consegui com valores inteiros, mas com float não dá muito certo... o valor é quebrado em dois, na transmissão.

Você poderia me ajudar ?

 

Estou fazendo um projetinho com sensor de corrente eletétrica...

 

Obrigado...

 

Marcelo Cuin

Exibições: 8024

Responder esta

Respostas a este tópico

Oi Marcelo,

 

Também estou com esta dúvida. Estava pensando em interpretar o float como um array de bytes e enviar este array pela serial. Porém, não achei funções prontas para isso.

 

Nesta semana vou mexer nisso e se tiver algum avanço eu posto aqui.

 

Abs,

Fernando Gil

Legal Fernando... vamos trocando idéias...

 

eu fiz assim: no Arduino:

void setup() {
  Serial.begin(9600);

  x = 1.4523344;
}

void loop() {

  Serial.print(x, DEC);

}

 

no JAVA: (apenas o código do recebimento):

byte[] readBuffer = new byte[20];

int numBytes = input.read(readBuffer);

String a = new String(readBuffer,0,numBytes);

System.out.println(a);

 

a Saída no console fica assim:

1.452

3344

 

é essa quebra de informação que está acontecendo...

se alguém já passou por isso... ajude-nos.. !!!

 

abraços

 

Marcelo Cuin | @marcelocuin | facebook.com/marcelocuin

Oi Marcelo,

 

Qual é o tipo da variável X? Pelo que eu vi, o tipo dela determina qual função print será usada. Se for float ou double, o sgundo argumento da funcão seria o número de dígitos que vc quer imprimir, e não a base do número, caso fosse int.

 

Abs!

Tive uma idéia meio besta...

 

Será que não rola (para efeito simplório) multiplicar a variável por 10.000 e enviar como se fosse um número inteiro? Simplifica alguma coisa pra vocês?

O problema é que assim você perde precisão, mas não sei se é crítico.

 

    float a = 10,235;

    long int b = a * 10000; //usar long pra garantir boa quantidade de digitos;

rodrigo, mas aí vc so trabalharia com até 3 casas decimais... e pra um numero como o do exemplo x = 1.4523344;?

é só multiplicar por uma potência de 10 adequada. Pro exemplo vc poderia usar 1.4523344 * 10.000.000.

O problema é que a quantidade de casas decimais ficaria sempre fixa.

Poisé, é isso que eu estou dizendo, nao rola trabalhar com um numero especifico de casas decimais...

problemão pra quem quer transmitir um valor FLOAT, e com VARIAVEIS... vc nunca sabe com quantas casas decimais uma variavel vai ficar dependendo de algum estado, por exemplo, um sensor de distancia, pode ser 1.5, pode ser 1.5768768763 e se o cara quer e precisa da precisão(que redundancia), o truque da multiplicação não rola :P

vc pode até escolher uma potencia de 10 alta, pra ter 10, 20 casas decimais de folga, mas é uma gambiarra que deve ter jeito de contornar...

 

Rodrigo Maximiano A de Almeida disse:

é só multiplicar por uma potência de 10 adequada. Pro exemplo vc poderia usar 1.4523344 * 10.000.000.

O problema é que a quantidade de casas decimais ficaria sempre fixa.

Oi Marcelo e pessoal,

Estudei um pouco da biblioteca do Arduino e percebi que todas as funções print convertem os dados para caracteres ASCII e depois enviam byte a byte pela serial. A única que não faz isso, é a print(byte, BYTE).

A solução que eu encontrei foi fazer uma função SerialPrintFloat, que pega uma variável float, que ocupa 4 bytes na memória, e a interpreta como bytes para enviar pela serial:

 

void SerialPrintFloat(float f)
{
    byte* a = (byte*)&f;
   
    Serial.print(*a++,BYTE);
    Serial.print(*a++,BYTE);
    Serial.print(*a++,BYTE);
    Serial.print(*a,BYTE);
}


Dessa forma, no lado do PC, no caso eu usei C#, basta ler a sequência de bytes e convertê-la usando alguma função da linguagem:

byte[] numero = new byte[4];
serialPort1.Read(numero, 0, 4);
float dado = System.BitConverter.ToSingle(numero, 0);

 

Assim, não se perde em nada na precisão do float, já que são enviados todos os bytes que o representam.

 

Qualquer dúvida postem aqui que continuamos conversando!

Abs,

Fernando

Olá pessoal...

 

Fernando, muito legal sua função, testei ela com Arduino e Java... e deu certinho !

 

Mas antes disso, eu estava pensando da mesma maneira que o Rodrigo e o Wagner, ou seja, converter o valor float em inteiro, e transmitir via serial como inteiro... e realmente é mais fácil.

 

no meu projeto é o seguinte: tenho um sensor de corrente elétrica (http://www.pololu.com/catalog/product/1187) e com isso, consigo medir, por exexmplo a corrente que passa para ligar uma lâmpada de 60W... essa corrente é baixa, em uma tensão de 127 volts. Algo em torno de 0,4724 ampres...

então como eu fiz: o sensor faz a leitura, e o arduino vai armazenando essa informação durante 10 segundos.. depois dividi pelo número de leituras e transmite para o PC, onde utilizo o Java para interpretar os dados.

mas antes de transmitir, multiplico a média calculada pelo sensor por 10.000, com isso eu consigo um nível de casa decimais que satisfaz o projeto, no exemplo da lâmpada de 60W, -> 0,4724 x 10.000 = 4724,40 .. mas quando converto para inteiro, fica somente 4724 (que no caso de projeto, já resolve)...

depois no Java eu pego esse valor e divido por 10.000 - facilitando a comunicação serial...  a transmissão é feita byte a byte.. e o Java recebe esses dados como String.

 

no Arduino:

final = (int) (media/leituras)*10000;
Serial.print(final);

 

no Java:

int num = input.available();
byte readBuffer[] = new byte[num];
input.read(readBuffer, 0, num);

media = new String(readBuffer);

float final = (float) (Float.parseFloat(b) / 10000);

 

Assim, ficou resolvido !!.. rsrs

 

logo, mostro pra vocês como ficou o projetinho... ok.....

e valeu pelas idéias trocadas !! #tamojunto..

 

Marcelo Cuin - @marcelocuin | facebook.com/marcelocuin

Pessoal,

 

Só para complementar, quando vc for transmitir um valor float, ou seja, jogar este valor em um buffer, para transmissão serial por exemplo. Pense na representação deste número na memória que é feita com formato IEEE-756-1985.

Segue o link na wiki:

http://en.wikipedia.org/wiki/IEEE_754-1985

 

At,

Rogério

http://www.esd-talk.com/

 

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço