Autor Tema: Como recibir un float utilizando int_rda()  (Leído 6560 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Como recibir un float utilizando int_rda()
« Respuesta #15 en: 20 de Octubre de 2011, 11:11:16 »
:x Me olvide lo importante, el operador &

Es así por ejemplo:

*((char)&Data+1)

Agregarle a todos. Disculpas.

Saludos!

Finalmente en la simulacion de proteus va bien con este codigo:

codigo emisor:

#include <16f88.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,NOWRT,NODEBUG,NOMCLR
#use delay(internal=8M)
#use rs232(baud=38400,xmit=PIN_B5,rcv=PIN_B2)
#use fast_io(a)
#use fast_io(b)

#define LCD_DB4 PIN_A0
#define LCD_DB5 PIN_A1
#define LCD_DB6 PIN_A7
#define LCD_DB7 PIN_A6

#define LCD_RS PIN_B7
#define LCD_E PIN_B6

#include "flex_lcd420.c"

void main(){
float Data;
set_tris_a(0b00000000);
set_tris_b(0b00000000);
setup_adc_ports(NO_ANALOGS);
lcd_init();
lcd_gotoxy(1,1);
printf(lcd_putc("Inicio Bluetooth"));
delay_ms(2000);
while(1){
Data=2.6;
putc(*((char *)&Data));
putc(*((char *)&Data+1));
putc(*((char *)&Data+2));
putc(*((char *)&Data+3));
delay_ms(1000);
}
}


codigo receptor:

#include <16f88.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,NOWRT,NODEBUG,NOMCLR
#use delay(internal=8M)
#use rs232(baud=38400,xmit=PIN_B5,rcv=PIN_B2)

#use fast_io(b)
#use fast_io(a)

#define LCD_DB4 PIN_A0
#define LCD_DB5 PIN_A1
#define LCD_DB6 PIN_A2
#define LCD_DB7 PIN_A3

#define LCD_RS PIN_A4
#define LCD_E PIN_A6

#include "flex_lcd.c"

int kbhit_data_serial;
float Data;
#int_rda //vector de interrupción al recibir por la UART
RDA_isr(){
  *((char *)&Data)=getc();
  *((char *)&Data+1)=getc();
  *((char *)&Data+2)=getc();
  *((char *)&Data+3)=getc();
   kbhit_data_serial=1;
}
void main(){
setup_adc_ports(NO_ANALOGS);
set_tris_a(0x00);
set_tris_b(0b00000100); // Rx entrada
output_b(0x00);
output_a(0x00);
lcd_init();
enable_interrupts(INT_RDA); //habilita interrupción por recepción
enable_interrupts(global);

while(1){
   if(kbhit_data_serial==1){
      kbhit_data_serial=0;
      lcd_gotoxy(1,1);
      printf(lcd_putc,"\fRecibiendo %01.2f",Data);
      }
   }
}

En proteus envia bien el float pero cuando monto el hardware solo se ve en la lcd receptora 0.00.
El envio se hace atraves de un bluetooth BTM-5 que lleva la conexion rs232 ya incluida y con los pines listos para utilizar. En principio si en proteus va bien deberia funcionar con el hardware real.

Es posible que el bluetooth codifique los datos de algun modo?. segun el manual es comunicacion rs232 con lo que tendria que funcionar.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Como recibir un float utilizando int_rda()
« Respuesta #16 en: 20 de Octubre de 2011, 11:24:43 »
  En este punto creo que conviene aplicar el principio de "divide y reinarás". Me parece que sería bueno realizar la prueba entre pics sin modulo de bluetooth de por medio. O sea, conectas el pin TX de pic transmisor al pin RX del receptor y verificas que es lo que ocurre y si así funciona bien pues habrá que observar bien el tema con el módulo. Tal vez pueda ser algún inconveniente con la velocidad o alguna configuración extra que haya que enviarle al módulo.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Como recibir un float utilizando int_rda()
« Respuesta #17 en: 20 de Octubre de 2011, 11:28:00 »
:x Me olvide lo importante, el operador &

Es así por ejemplo:

*((char)&Data+1)

Agregarle a todos. Disculpas.

Saludos!

Finalmente en la simulacion de proteus va bien con este codigo:

codigo emisor:

#include <16f88.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,NOWRT,NODEBUG,NOMCLR
#use delay(internal=8M)
#use rs232(baud=38400,xmit=PIN_B5,rcv=PIN_B2)
#use fast_io(a)
#use fast_io(b)

#define LCD_DB4 PIN_A0
#define LCD_DB5 PIN_A1
#define LCD_DB6 PIN_A7
#define LCD_DB7 PIN_A6

#define LCD_RS PIN_B7
#define LCD_E PIN_B6

#include "flex_lcd420.c"

void main(){
float Data;
set_tris_a(0b00000000);
set_tris_b(0b00000000);
setup_adc_ports(NO_ANALOGS);
lcd_init();
lcd_gotoxy(1,1);
printf(lcd_putc("Inicio Bluetooth"));
delay_ms(2000);
while(1){
Data=2.6;
putc(*((char *)&Data));
putc(*((char *)&Data+1));
putc(*((char *)&Data+2));
putc(*((char *)&Data+3));
delay_ms(1000);
}
}


codigo receptor:

#include <16f88.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,NOWRT,NODEBUG,NOMCLR
#use delay(internal=8M)
#use rs232(baud=38400,xmit=PIN_B5,rcv=PIN_B2)

#use fast_io(b)
#use fast_io(a)

#define LCD_DB4 PIN_A0
#define LCD_DB5 PIN_A1
#define LCD_DB6 PIN_A2
#define LCD_DB7 PIN_A3

#define LCD_RS PIN_A4
#define LCD_E PIN_A6

#include "flex_lcd.c"

int kbhit_data_serial;
float Data;
#int_rda //vector de interrupción al recibir por la UART
RDA_isr(){
  *((char *)&Data)=getc();
  *((char *)&Data+1)=getc();
  *((char *)&Data+2)=getc();
  *((char *)&Data+3)=getc();
   kbhit_data_serial=1;
}
void main(){
setup_adc_ports(NO_ANALOGS);
set_tris_a(0x00);
set_tris_b(0b00000100); // Rx entrada
output_b(0x00);
output_a(0x00);
lcd_init();
enable_interrupts(INT_RDA); //habilita interrupción por recepción
enable_interrupts(global);

while(1){
   if(kbhit_data_serial==1){
      kbhit_data_serial=0;
      lcd_gotoxy(1,1);
      printf(lcd_putc,"\fRecibiendo %01.2f",Data);
      }
   }
}

En proteus envia bien el float pero cuando monto el hardware solo se ve en la lcd receptora 0.00.
El envio se hace atraves de un bluetooth BTM-5 que lleva la conexion rs232 ya incluida y con los pines listos para utilizar. En principio si en proteus va bien deberia funcionar con el hardware real.

Es posible que el bluetooth codifique los datos de algun modo?. segun el manual es comunicacion rs232 con lo que tendria que funcionar.

he probado a conectar los dos pic directamente Tx de uno con Rx del otro y funciona en determinados momentos. A veces aparece 0.00 y a veces el float que le mando desde el pic transmisor. Quizas sea un problema de ajustar los tiempos cuando recibe el float ó cuando se envia.

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Como recibir un float utilizando int_rda()
« Respuesta #18 en: 20 de Octubre de 2011, 11:59:13 »
Hola!! Yo implemente facilmente esto pasando el float como un string y convirtiendolo con la funcion atof. Les dejo un ejemplo.
Código: C
  1. #int_rda
  2. void serial_isr(){
  3.   char key[16];
  4.  
  5.   if(kbhit()){
  6.     gets(key);
  7.     switch(key[0]){
  8.          case 'p':
  9.             if(key[1]!=0)
  10.                Kp = atof((key+1));
  11.             printf("Kp = %.4f\r\n",Kp);
  12.             break;
  13.          case 'i':
  14.             if(key[1]!=0)
  15.                Ki = atof((key+1));
  16.             printf("Ki = %.4f\r\n",Ki);
  17.             break;
  18.          case 'd':
  19.             if(key[1]!=0)
  20.                Kd = atof((key+1));
  21.             printf("Kd = %.4f\r\n",Kd);
  22.             break;
  23.          case 'r':
  24.             if(key[1]!=0)
  25.                PID.rT = atof((key+1));
  26.             printf("rT = %.4f\r\n",PID.rT);
  27.             break;
  28.          default:
  29.             printf("error: comando desconocido\r\n");
  30.             break;
  31.       }
  32.   }
  33. }

Lo que hace es verificar la primera letra para saber qué variable modificar, y luego modifica el valor de esa variable por el numero que acompaña a la letra. Entonces desde una consola ponemos por ej:
p3.51\r
y ahora la variable kp va a tener el valor 3.51
saludos!!!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Como recibir un float utilizando int_rda()
« Respuesta #19 en: 21 de Octubre de 2011, 17:17:18 »
Estoy pensando que quizas al declarar asi la variable Data

float Data;

putc(*((char *)&Data));

ahi se utiliza como puntero. Es posible que el problema este en usarlo de este modo?

Suky, no hay otra alternativa para enviar el float sin utilizar punteros ?

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Como recibir un float utilizando int_rda()
« Respuesta #20 en: 21 de Octubre de 2011, 17:32:31 »
Estoy pensando que quizas al declarar asi la variable Data

float Data;

putc(*((char *)&Data));

ahi se utiliza como puntero. Es posible que el problema este en usarlo de este modo?

Suky, no hay otra alternativa para enviar el float sin utilizar punteros ?

no leiste lo que puse arriba no? funciona perfectamente, yo ya lo probe.

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Como recibir un float utilizando int_rda()
« Respuesta #21 en: 21 de Octubre de 2011, 18:40:38 »
puedes usar uniones:

union {
char bytes[4];
float Data;
}datos;

lo que guardes en byte
  • comparten la misma direccion de memoria que Data por lo cual cuando tengas los 4bytes escritos tendras un float en Data.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Como recibir un float utilizando int_rda()
« Respuesta #22 en: 21 de Octubre de 2011, 18:44:41 »
Otra forma es como lo muestra Gera... Aunque no veo porque pueda fallar  :o Otra forma:

Código: C
  1. typedef union{
  2.     float Val;
  3.     unsgined char V[4];
  4. }DATA_FLOAT;
  5.  
  6.  
  7. DATA_FLOAT Data;
  8.  
  9. Data.Val=2.356;
  10.  
  11. putc(Data.V[0]);
  12. putc(Data.V[1]);
  13. putc(Data.V[2]);
  14. putc(Data.V[3]);

Y después:

Código: C
  1. DATA_FLOAT Data;
  2.  
  3. Data.V[0]=getc();
  4. Data.V[1]=getc();
  5. Data.V[2]=getc();
  6. Data.V[3]=getc();


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Como recibir un float utilizando int_rda()
« Respuesta #23 en: 21 de Octubre de 2011, 19:47:16 »
me acabo de dar cuenta de que la velocidad de transmision por defecto de fabrica para este modelo es 115200 y no 38400 como yo habia puesto en el codigo del pic. mañana comprobaré el hardware de nuevo pero sí, llevais razon, deberia funcionar porque en proteus no da ningun problema.


 

anything