Autor Tema: Problema para distinguir datos enviados por RS232  (Leído 3115 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado George_cba

  • PIC10
  • *
  • Mensajes: 3
Problema para distinguir datos enviados por RS232
« en: 03 de Febrero de 2010, 15:06:50 »
Hola gente de todo pic, estoy haciendo una aplicacion con un pic 16f877A programado en ccs, el cual debe leer 3 canales del Adc con resolucion de 10 bits y enviar los datos a la pc por el protocolo RS232.
Yo leo el conversor en una variable de 16bits (word) y luego la desarmo en dos bytes con make8 para tener una parte alta y otra parte baja y luego envio los datos.
Hasta aqui mi programa funciona perfectamente, fue simulado en proteus y a los datos los envia bien.
Mi problema es que tengo tres datos distintos (por ejemplo, 3 sensores distintos de temperatura), pero cuando los envio a la pc no se como hacer para saber cuales son la parte alta y baja del sensor 1, la del sensor 2 y la del 3.
Yo pensaba en meterle unos bits a la parte alta y que la pc los teste y decida pero no se si esa es la forma.
Ustedes que tienen mas experiencia a lo mejor hicieron algo similar.
Les adjunto mi codigo, esta compilado en pic ccs. Gracias.
Código: [Seleccionar]
//Este Firmware lee 3 canales del ADC configurado con una resolucion de 10bits
//y luego envia por RS232 la parte baja y la parte alta del word adquirido
//Jorge Peirone
#include<16f877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP   
#device adc=10 //nos permite especificar el número de bits que la función read_adc() debe retornar.
#use delay(clock=4000000)
#use RS232(BAUD=9600, BITS=8 ,PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)

int16 conversion(int);
int16 ECG; //Variable para guardar la medicion para enviar.
int16 TORAX; //int16 es un word 16bits
int16 TEMP;

int HiByte,LoByte;// dos registros de 8 bits , 2 bytes.

void main()
{
setup_adc_ports(ANALOG_RA3_REF);//pongo todas las entradas como analogicas y Ra3 como Vref+
setup_adc(ADC_CLOCK_INTERNAL);//definimos la frecuencia de reloj empleada en la conversión.

 while(TRUE)
      {
         ECG=conversion(0);
         LoByte=make8(ECG,0); //La funcion make8 me devuelve la parte parte del word con el corrimiento que quiero, corrimiento 0 obtengo el primer byte
         HiByte=make8(ECG,1);//con el corrimiento 1 obtengo la parte alta es decir que me corro un bayte y guardo en la parte alta.
         printf("%u\r\n",LoByte); // primero enviamos la parte baja
         printf("%u\r\n",HiByte); // despues la parte alta
         LoByte=0x00; //los vuelvo a 0
         HiByte=0x00;
         
         delay_ms(2000); // solo para darme cuenta en la simulacion
         
         TORAX=conversion(1);
         LoByte=make8(TORAX,0);
         HiByte=make8(TORAX,1);
         printf("%u\r\n",LoByte);
         printf("%u\r\n",HiByte);
         LoByte=0x00; //los vuelvo a 0
         HiByte=0x00;
         
         delay_ms(2000);
         
         TEMP=conversion(2);
         LoByte=make8(TEMP,0);
         HiByte=make8(TEMP,1);
         printf("%u\r\n",LoByte);
         printf("%u\r\n",HiByte);
         LoByte=0x00; //los vuelvo a 0
         HiByte=0x00;
                           
         delay_ms(3000);
      }
}
int16 conversion (int canal)
{
   int16 value;
   set_adc_channel(canal);
   delay_us(20);
   value=read_adc();
   return(value);
}

Bueno muchas gracias y espero su respuesta.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema para distinguir datos enviados por RS232
« Respuesta #1 en: 03 de Febrero de 2010, 16:03:13 »
¿A la PC no te llegan en el mismo orden en que los transmitís? Según se vé en el código primero te llegaría la parte baja y luego la parte alta de cada dato.

¿Vos te referís al caso que se pierda alguna transmisión como hacer para que se vuelva a sincronizar cada variable con su respectiva parte?

Podrías primero enviar un primer "PrintF" con un byte específico para que el soft de la PC sepa que es desde ahí que comienza la transmisión y almacene los siguientes datos entrantes de forma adecuada.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Problema para distinguir datos enviados por RS232
« Respuesta #2 en: 03 de Febrero de 2010, 16:19:21 »
Todo dependerá de cómo o con qué lo recibas en el PC. Si tienes un programa hecho por tí puedes ponerle a cada printf un prefijo indicándote qué byte es el que estás enviando y tu programa sabrá que dato es el que está recibiendo.

Código: C#
  1. //Este Firmware lee 3 canales del ADC configurado con una resolucion de 10bits
  2. //y luego envia por RS232 la parte baja y la parte alta del word adquirido
  3. //Jorge Peirone
  4. #include<16f877A.h>
  5. #fuses HS,NOWDT,NOPROTECT,NOLVP    
  6. #device adc=10 //nos permite especificar el número de bits que la función read_adc() debe retornar.
  7. #use delay(clock=4000000)
  8. #use RS232(BAUD=9600, BITS=8 ,PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
  9.  
  10. int16 conversion(int);
  11. int16 ECG; //Variable para guardar la medicion para enviar.
  12. int16 TORAX; //int16 es un word 16bits
  13. int16 TEMP;
  14.  
  15. int HiByte,LoByte;// dos registros de 8 bits , 2 bytes.
  16.  
  17. void main()
  18. {
  19. setup_adc_ports(ANALOG_RA3_REF);//pongo todas las entradas como analogicas y Ra3 como Vref+
  20. setup_adc(ADC_CLOCK_INTERNAL);//definimos la frecuencia de reloj empleada en la conversión.
  21.  
  22.  while(TRUE)
  23.       {
  24.          ECG=conversion(0);
  25.          LoByte=make8(ECG,0); //La funcion make8 me devuelve la parte parte del word con el corrimiento que quiero, corrimiento 0 obtengo el primer byte
  26.          HiByte=make8(ECG,1);//con el corrimiento 1 obtengo la parte alta es decir que me corro un bayte y guardo en la parte alta.
  27.          printf("1L%u\r\n",LoByte); // primero enviamos la parte baja
  28.          printf("1H%u\r\n",HiByte); // despues la parte alta
  29.          LoByte=0x00; //los vuelvo a 0
  30.          HiByte=0x00;
  31.          
  32.          delay_ms(2000); // solo para darme cuenta en la simulacion
  33.          
  34.          TORAX=conversion(1);
  35.          LoByte=make8(TORAX,0);
  36.          HiByte=make8(TORAX,1);
  37.          printf("2L%u\r\n",LoByte);
  38.          printf("2H%u\r\n",HiByte);
  39.          LoByte=0x00; //los vuelvo a 0
  40.          HiByte=0x00;
  41.          
  42.          delay_ms(2000);
  43.          
  44.          TEMP=conversion(2);
  45.          LoByte=make8(TEMP,0);
  46.          HiByte=make8(TEMP,1);
  47.          printf("3L%u\r\n",LoByte);
  48.          printf("3H%u\r\n",HiByte);
  49.          LoByte=0x00; //los vuelvo a 0
  50.          HiByte=0x00;
  51.                            
  52.          delay_ms(3000);
  53.       }
  54. }
  55. int16 conversion (int canal)
  56. {
  57.    int16 value;
  58.    set_adc_channel(canal);
  59.    delay_us(20);
  60.    value=read_adc();
  61.    return(value);
  62. }


O como te dice AngelGris, usar un primer printf para enviar una sicronización y después el resto y sabrás que el primer byte que recibas tras la sincronización es el canal 1 byte low, el segundo el canal 1 byte hight, el tercero el canal 2 byte low ... etc.

Este sistema tiene el problema de que si tu PC puede empezar la recepción en cualquier momento tendrás que esperar a recibir un primera sincronización para empezar a recibir datos con sentido, que sepas a qué corresponde.

Código: C#
  1. //Este Firmware lee 3 canales del ADC configurado con una resolucion de 10bits
  2. //y luego envia por RS232 la parte baja y la parte alta del word adquirido
  3. //Jorge Peirone
  4. #include<16f877A.h>
  5. #fuses HS,NOWDT,NOPROTECT,NOLVP    
  6. #device adc=10 //nos permite especificar el número de bits que la función read_adc() debe retornar.
  7. #use delay(clock=4000000)
  8. #use RS232(BAUD=9600, BITS=8 ,PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
  9.  
  10. int16 conversion(int);
  11. int16 ECG; //Variable para guardar la medicion para enviar.
  12. int16 TORAX; //int16 es un word 16bits
  13. int16 TEMP;
  14.  
  15. int HiByte,LoByte;// dos registros de 8 bits , 2 bytes.
  16.  
  17. void main()
  18. {
  19. setup_adc_ports(ANALOG_RA3_REF);//pongo todas las entradas como analogicas y Ra3 como Vref+
  20. setup_adc(ADC_CLOCK_INTERNAL);//definimos la frecuencia de reloj empleada en la conversión.
  21.  
  22.  while(TRUE)
  23.       {
  24.          printf("SYNC\r\n"); // primero la sincronicazción
  25.          ECG=conversion(0);
  26.          LoByte=make8(ECG,0); //La funcion make8 me devuelve la parte parte del word con el corrimiento que quiero, corrimiento 0 obtengo el primer byte
  27.          HiByte=make8(ECG,1);//con el corrimiento 1 obtengo la parte alta es decir que me corro un bayte y guardo en la parte alta.
  28.          printf("%u\r\n",LoByte); // primero enviamos la parte baja
  29.          printf("%u\r\n",HiByte); // despues la parte alta
  30.          LoByte=0x00; //los vuelvo a 0
  31.          HiByte=0x00;
  32.          
  33.          delay_ms(2000); // solo para darme cuenta en la simulacion
  34.          
  35.          TORAX=conversion(1);
  36.          LoByte=make8(TORAX,0);
  37.          HiByte=make8(TORAX,1);
  38.          printf("%u\r\n",LoByte);
  39.          printf("%u\r\n",HiByte);
  40.          LoByte=0x00; //los vuelvo a 0
  41.          HiByte=0x00;
  42.          
  43.          delay_ms(2000);
  44.          
  45.          TEMP=conversion(2);
  46.          LoByte=make8(TEMP,0);
  47.          HiByte=make8(TEMP,1);
  48.          printf("%u\r\n",LoByte);
  49.          printf("%u\r\n",HiByte);
  50.          LoByte=0x00; //los vuelvo a 0
  51.          HiByte=0x00;
  52.                            
  53.          delay_ms(3000);
  54.       }
  55. }
  56. int16 conversion (int canal)
  57. {
  58.    int16 value;
  59.    set_adc_channel(canal);
  60.    delay_us(20);
  61.    value=read_adc();
  62.    return(value);
  63. }
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania