Autor Tema: Problema en comunicacion PIC<>PIC RS-232  (Leído 3272 veces)

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

Desconectado BURZUM

  • PIC10
  • *
  • Mensajes: 7
Problema en comunicacion PIC<>PIC RS-232
« en: 29 de Julio de 2011, 14:03:25 »
Hi aqui yo de nuevo desde el post Problema con programa para proyecto de grado, y como sabrán ya termine el diseño completo tanto hardware como software del sistema el cual esta destinado a controlar u a simple bomba hidráulica mediante comandos como cadenas de caracteres para activarla, desactivarla, alarmas de: mal funcionamiento, problemas con la comunicación, etc; todo esto mediante adaptadores rs-232 de comunicación inalambrica.

En pocas palabras dos sistemas transceptores (uno en el tanque elevado "sistema de control" y otro en la central de bombeo "sistema de mando" a 370m de distancia). Entonces me dispuse a realizar las pruebas en protoboard de todo el sistema, tanto: sensores, alarmas, arreglos de luces pilotos y por supuesto "comunicación"  :shock:. Este ultimo con resultados desastrosos puesto que las otras pruebas las podría realizar individualmente (sin necesidad de comunicación entre el sistema de control y el sistema de mando), esta depende del envió de comandos entre Pics.

El problema es que no parece que se envié ningún comando por comunicación serial, incluso e resumido el código lo bastante para probar la comunicación y el efecto de los comandos entre el sistema de control y mando; e realizado la simulación en Proteus y todo OK como con el sistema completo.

Pero al probarlo en la practica huy es la misma cantaleta, reviso y reviso el circuito real y no encuentro falla alguna. Si así estoy con problemas siendo que la comunicación es mediante conductores imaginence cuando los conecte a los adaptadores de RF.

Aca les dejo adjunto el programa tx y rx con la simulación en Proteus 7.6 SP0 y detallando lo siguiente:

TXC- es el sistema de control que detecta el estado de los sensores de nivel (no están implementados en el programa de prueba); al presionar el botón del pin RB6 envía el comando de encendido de la bomba "ONBB".
al presionar el botón del pin RB5 envia el monando de apagado para la bomba "OFFB" y al presionar el botón del pin RB4 envia el comando de falla (ya sea de comunicación, alimentación, etc) solo como prueba. Y despues espera para recibir el comando de confirmación por el RXC o sistema de mando.

RXC- es el sistema de mando que activa y desactiva la bomba esta al recibir los comandos correspondientes realiza la tarea que se designa a cada comando, después al presionar el pin RB0 realiza una revisada en el estado de los auxiliares del sistema de fuerza del motor y consecuentemente envía la confirmación del estado actual hacia el TXC.

Para aclarar mas dudas dejo comentarios en el código fuente.

PDT: Perdón por crear otro post y no seguir el anterior, pues en el anterior ya había solucionando la problemática que ademas era otra.

Desconectado BURZUM

  • PIC10
  • *
  • Mensajes: 7
Re: Problema en comunicacion PIC<>PIC RS-232
« Respuesta #1 en: 04 de Agosto de 2011, 19:43:48 »
Hi, acabo de darme cuenta de muchas cosas o mejor dicho problemas que rodean mi diseño; para empezar debo decirles que la interrupción INT_RDA no realiza el weak up o despertar del PIC cuando se encuentra en el estado SLEEP y esto era lo que me generaba el problema anterior, inclusive realizando modificaciones en la recepción de datos seriales con estas modificaciones del codigo:

Código: [Seleccionar]
//al detectarce la recepcion de datos la interrupcion llama la función de recepción
//para la captura y salvado de la cadena comando
#INT_RDA                                
void D_IN_RS()            
{
GET_CADENA();
}

//Esta función captura carácter por carácter que es enviado desde el TX mediante putc();
//y va almacenando en la variable de tipo char COMANDO[5];
void GET_CADENA()
{
int8 i;          
if(kbhit())                  
{                      
for(i=0;i<4;i++)
{                
COMANDO[i]=getc();      
}
}
COMANDO[4]=0; //el ultimo carácter le asigno el valor de 0 solo por seguridad
}

Código: [Seleccionar]
//Tampoco funcionó de esta manera, situando una variación de la función GET_CADENA
//dentro de la función de interrupción INT_RDA  
#INT_RDA                                
void D_IN_RS()            
{
do  
{            
if(kbhit())      
{    
COMANDO[i]=getc();
i++;                                  
}
}while(i<4);        
COMANDO[4]=0;
}

Para colmo ni siquiera enviando solo un byte y recibiéndolo con la rutina siguiente dentro de la interrupción RDA:
if(kbhit())
{
COM=getc();//la variable COM es un entero de 8 bits
TAREA=1; //es una tarea a realizar después de recibir un dato. SIENDO QUE FUNCIONE LA INTERRUPCIÓN
}

Por lo que deduje que la interrupcion RDA solo sirve en Proteus o que estoy haciendo algo mal.
 
La única forma es situando la rutina anterior dentro de un bucle do-while en la función main, en otras palabras el microcontrolador nunca estará en estado SLEEP aunque como sabrán mi intención es que después de realizar alguna tarea, el sistema (tanto el sistema de control TX como el sistema de mando RX) se sitúe en modo SLEEP y solo reaccione mediante interrupciones COMP, EXT, RB y RDA, etc.


Ahora me encamino a dictarles el otro problema que surge al comunicarme vía RF mediante los adaptadores RS-232 de tipo transceptor; cuando comunico los pics por conductores la comunicación funciona de maravillas, el dato llega limpio y sin errores, realizando las tareas que debería hacer el RX con cada dato que envia el TX, pero al comunicarme con los adaptadores existe comunicación y de eso no hay duda pero los datos llegan erróneos y ni siquiera muestran un patrón (por así decirlo) del desvío numérico en hexadecimal si no que para cada dato enviado existe un valor de desviación por ejemplo:

Cuando enciendo todo el sistema, el adaptador RX me envía al microcontrolador receptor el dato 00 por lo que el PIC me indica que recibió un dato (ver código fuente del RX) entonces envío el numero decimal 50 (h32) desde el pic TX por primera vez y el pic RX me recibe el numero 153 (h99) por parte del adaptador RX que luego me envía otra vez el dato 00 al pic RX y como consecuencia el pic cuenta que ya va recibiendo 3 datos; luego vuelvo a enviar el numero 50 (h32) pero el adaptador RX ahora me envía al pic RX el dato 102(h66) y esta vez ya no vuelve a enviarme 00 (parece que sucede la primera vez que se envía un dato) entonces el pic me cuenta que va recibiendo asta ahora 4 datos, entonces calculo la diferencia entre 102-50 resultandome 52 (h34); para el caso del numero 60 (h3C) me recibe el numero 14 (h0E) y poniendo en claro de que tanto la variable transmitida y la variable receptora son de tipo unsigned int8 la diferencia no puede ser negativa por lo tanto h0E-h3C= hD2, y así con cualquier otro dato que envíe entonces me doy cuenta que no existe un patrón de desvió si no que para cada dato existe un valor de desvió propio.

Interior de la EEPROM del microcontrolador receptor:



Creo que esto se debe a la conexión entre los pics y los adaptadores de RF puesto que solo en cableado el RX del adaptador con el TX del pic y viceversa tal como se realiza cuando se comunican los pics entre si por medio de cables nada mas; sin realizar puentes como lo muestra la siguiente figura la cual es la forma de conectar el PIC con la PC:


  
Puesto que son dispositivos DTE (como en el caso de la PC), las conexiones del cable de comunicación debería estar configurado de esa manera, no lo he echo así ni lo e intentado por la razón de que estos adaptadores son costosos y no quisiera hacer algo indebido que resulte en un desperfecto de los dispositivos. Como verán no implemente un driver de linea como un max232 por que supuse que los niveles lógicos de Voltaje para la comunicación era monopolar 0V +5V no como en el caso de conectarlos a la PC u otros estándares que manejan -6V 0V +6V, -12V +12V info RS232, en tal caso la hoja de datos de los adaptadores  no indica nada de esto - datasheet.


Debido a esto se plantea otra problematica ya que en el caso de realizar las interconexiones del cable en la configuración "sin control de flujo" como lo muestra la imagen anterior, se solucione la recepción de datos erróneos; tanto el sistema de mando como el de control no quedarían en reposo o SLEEP, si no esperando que el registro serial se llene con algún comando proveniente de ambas partes ya sea del sistema de mando hacia el sistema de control o viceversa con la rutina Kbhit(); en un bucle do-while, razón de esto es la ineficiente interrupción RDA. Pero si me dispongo a realizar el control de flujo (cosa que nunca e echo anteriormente) utilizando los pines 7 (RTS) y 8 (CTS) del adaptador, ademas con lo que tengo mas o menos en claro asta ahora es que si envió una trama o según mi idea un pulso continuo de 100ms por un pin del PIC hacia el pin 8 (CTS) del adaptador transceptor perteneciente al sistema de control, resultaría en una trama o un pulso continuo de 100ms proveniente del pin 7 (RTS) del otro adaptador perteneciente al sistema de mando hacia el pic del mismo sistema.



mas o menos asi:



Entonces envió por el puerto B6 del microcontrolador en el sistema de control un pulso en alto; el cual se refleja en un pulso en alto también en el puerto B7 del microcontrolador en el sistema de mando configurado como entrada e interrupción por cambio de estado, así de esta forma despierto al microcontrolador y ademas le indico que se prepare para recibir datos, lo mismo en el sistema de mando hacia el sistema de control. Aunque La verdad creo que no funcionaría ya que esto supondría que los adaptadores sean dispositivos DCE siendo en realidad DTE pero respecto al los niveles de tensión que manejan en la comunicación mas bien parecen DCE.

Bueno asta aquí con los problemas, y me despido esperando sus criticas y sugerencias respecto a lo que estoy haciendo o mejor dicho tratando de hacer.

Programa de prueba en la comunicación:
//////////////////TX////////////////////
Código: [Seleccionar]
#include <16F628A.h>                              
                
#USE delay (CLOCK = 4MHz, INTERNAL)                
                                          
#fuses INTRC_IO, NOWDT, PUT, NOPROTECT,NOLVP, MCLR
                                                      
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)
                            
//PROTOTIPO DE FUNCIONES////////
void CONFIG();                //
void CPILOTOS(int16 LIGTHS);  //
////////////////////////////////          
                                        
////DECLARACIONES DE VARIABLES GLOBALES///
int8 NIVEL=0;
int16 PILOTOS=0;                
                                                  
                  
                 /*INTERRUPCIONES POR CAMBIO DE ESTADO  
                    RA 4-5-6-7 CUALES SON LOS SENSORES
       DE NIVEL ALTO B7 Y DE NIVEL BAJO B6 COM TAMBIEN EL BOTON START*/
#INT_RB                                          
void INT_B4_7()              
{
IF(INPUT(PIN_B6))
{
COM=50;
}
ELSE IF(INPUT(PIN_B5))        
{      
COM=60;
}  
ELSE IF(INPUT(PIN_B4))  
{
COM=70;
}
}                            
                                            
                    
             /*PROGRAMA PRINCIPAL DEL SISTEMA uCONTROLADO*/
void main ()                                
{                    
CONFIG(); /*SE EJECUTA LA FUNCION DE CONFIGURACION DE PUERTOS*/
CPILOTOS(0);
do
{
if(NIVEL!=0)
{
PILOTOS++;
CPILOTOS(PILOTOS);
delay_ms(100);
putc(COM);
delay_ms(100);
nivel=0;
}
sleep();
}while(true);            
}                                        
                                        
                    
        
             //////////////////////////////////////////////                                          
             /*FUNCION DESTINADA A CONFIGURAR LOS PUERTOS*/
             //////////////////////////////////////////////
                                          
void CONFIG()                                
{                  
SET_TRIS_A(0b00000000);                                              
SET_TRIS_B(0b01110010);              
CLEAR_INTERRUPT(INT_RB);  
ENABLE_INTERRUPTS(INT_RB);
enable_interrupts(GLOBAL);
}          


/*FUNCION ENCARGADA DE SELECCIONAR LAS LUCES PILOTOS*/    
   //REALIZA LA TAREA DE SET Y RESET PARA LAS LUCES PILOTOS
   //DEPENDIENDO DEL VALOR QUE SE LE ASIGNE A LA VARIABLE LIGHTS  
   //Y UTILIZANDO LOS RESPETCIVOS PINES PARA EL CONTROL DE
   //RC2 DATO DE PILOTOS        
   //RC3 RELOJ DE PILOTOS                
                      
void CPILOTOS(int16 LIGHTS)        
{                                      
signed int8 C=15;                
do
{                          
OUTPUT_BIT(PIN_A0, BIT_TEST(LIGHTS, C));                              
OUTPUT_BIT(PIN_A1, 1);
DELAY_US(30);            
OUTPUT_BIT(PIN_A1, 0);
C--;                
}while(C>=0);
}



/////////////////RX/////////////////////
Código: [Seleccionar]
#INCLUDE <16f628A.h>
#USE delay (CLOCK = 4MHz, INTERNAL)
#FUSES INTRC_IO, NOWDT, PUT, NOPROTECT, NOLVP, MCLR                                        
#USE rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)
                                                                                                            
//PROTOTIPO DE FUNCIONES////////                                                      
void CONFING();               //    
void CPILOTOS(int8 LIGTHS);   //
void COMP_COM();              //
////////////////////////////////                              

int8 PILOTOS=0;
INT8 DIRECCION=0x05;
int16 COM=0;
INT8 NIVEL;
///////////////////////////////////////                  

  
void main()                  
{          
CONFING();    
CPILOTOS(0);        
do          
{
IF(KBHIT())  ///SEMPRE ESPERANDO UN DATO          
{            
COM=GETC();          
COMP_COM();  
PILOTOS++; //INCREMENTA LA VARIABLE DE CONTEO POR ADA DATO RECIBIDO
CPILOTOS(PILOTOS);
}          
}while(true);              
}
            
                
                    
             /*FUNCION DESTINADA A CONFIGURAR LOS PUERTOS*/
void CONFING()                                
{
SET_TRIS_A(0b11100000);    //TODOS LOS PUERTOS A COMO SALIDA
PORTA=0;        
                                            
SET_TRIS_B(0b01110011);    //B0, B1, B4, B5, B6, B7 ENTRADA
                           //B2, B3 SALIDA
}                            
                          
             /*FUNION ENCARGADA DEL COMPROBACION DE COMANDOS
            PARA EL CONTROL DE LAS BOMBAS HIDRAULICAS*/
                      //RA2 PULSADOR DE MARCHA                                                      
                      //RA3 PULSADOR DE PARADA
          
void COMP_COM()          
{                            
write_eeprom(DIRECCION, COM); //ESCRIBO EN LA EEPROM EL DATO QUE RECIBIO
DIRECCION++;                  //INCREMENTO LA DIRECCION DE EEPROM                                        
int8 C=0;
if(COM==50)
{              
do      
{
output_high(PIN_A2);          
DELAY_MS(150);      
output_low(PIN_A2);        
C++;
DELAY_MS(150);
}while(C<3);
NIVEL=0;
}                          

if(COM==60)
{    
do                    
{                  
output_high(PIN_A3);
DELAY_MS(100);      
output_low(PIN_A3);
C++;          
DELAY_MS(100);
}while(C<3);  
NIVEL=1;    
}
else                    
{
break;        
}
}                              
              
                      
void CPILOTOS(int8 LIGHTS)        
{                        
signed int8 C=7;                
do
{                          
OUTPUT_BIT(PIN_A0, BIT_TEST(LIGHTS, C));                              
OUTPUT_BIT(PIN_A1, 1);
DELAY_US(30);  
OUTPUT_BIT(PIN_A1, 0);
C--;                  
}while(C>=0);                                                                                              
}  
« Última modificación: 04 de Agosto de 2011, 20:15:49 por BURZUM »

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Problema en comunicacion PIC<>PIC RS-232
« Respuesta #2 en: 04 de Agosto de 2011, 19:59:44 »
Hola, no he leido todo tu post, pero antes tengo una duda, estas conectado tu conector DB9 de la compu directamente al pic? asi como lo muestras en proteus?
"Nada es imposible, no si puedes imaginarlo"

Desconectado BURZUM

  • PIC10
  • *
  • Mensajes: 7
Re: Problema en comunicacion PIC<>PIC RS-232
« Respuesta #3 en: 04 de Agosto de 2011, 20:13:09 »
Hola, no he leido todo tu post, pero antes tengo una duda, estas conectado tu conector DB9 de la compu directamente al pic? asi como lo muestras en proteus?

Bueno en primera agradecerte por responder, en segunda no conecto mi PIC a ninguna PC solo lo conecto con los transceptores adaptadores rs-232 que tienen un conector db9 del mismo estándar de los dispositivos DTE (como la PC).

Ahora si lees el segundo mensaje que puse veras que e resuelto el problema de la comunicación (osea que por lo menos se manden y reciban datos) ahora estoy con problemas de los datos erróneos y la forma de solucionarlos.   

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Problema en comunicacion PIC<>PIC RS-232
« Respuesta #4 en: 04 de Agosto de 2011, 20:14:14 »
Hola, por lo que veo el error esta en tu velocidad de transmicion, tus pics si los conectas directamente se comunican bien, pero cuando lo haces con los modulos se pierde.

como sabes a que velocidad deben de recibir los datos tus modulos?. no se tienen que configurar o programar para que trabajen a la misma que velocidad de transmicion de tus pics?
« Última modificación: 04 de Agosto de 2011, 20:27:22 por rivale »
"Nada es imposible, no si puedes imaginarlo"

Desconectado BURZUM

  • PIC10
  • *
  • Mensajes: 7
Re: Problema en comunicacion PIC<>PIC RS-232
« Respuesta #5 en: 05 de Agosto de 2011, 18:23:55 »
Después de probar con varios estándares de Baudios como ser 1200, 2400, 4800, 5700, 9600, 19200, etc; no e podido lograr una comunicación limpia, puesto que con cada baudio que cambiaba el dato que enviaba como ejemplo (h32) variaba,  pero por fin encontré un buen manual que es de la manufactura XBee ya que estos módulos son los utilizados en la fabricación de los adaptadores DigiMesh 900 RS-232 Adapter, y revisando pude ver que es necesario un control de flujo (de todas formas lo iba a implementar) aunque estoy pensando primero en realizar la conexión o mejor dicho el puenteo de los pines dentro del cable usado para la comunicación entre el pic y el adaptador tal como se lo hace al conectar el PIC a la PC, esto debido ha que en el manual me describe los valores lógicos de tensión que maneja el adaptador (gracias al manual) si aun no funciona entonces lo probare con control de flujo.



Así se muestra un ejemplo de conexión según el manual entre el PIC y el adaptador


Como dije, en eso del control de flujo no tengo mucha experiencia pero encontré este antiguo post control de flujo y me di cuenta que funciona como lo pensé, así que mi problema esta relativamente resuelto a menos que los métodos de conexión que quiero implementar (dictados arriba) me fallen.