Autor Tema: Comunicacion IR en rs232  (Leído 2450 veces)

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

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Comunicacion IR en rs232
« en: 13 de Junio de 2005, 06:58:00 »
Trato de hacer un termostato con pics que comunique mediante rs232 a un receptor pic que sera quien active el calefactor.
Es simple en principio pero no estoy seguro de que esto vaya a funcionar
El sistema lleva un 16F84 que al detectar por una entrada el cierre de un contacto manda un caracter a un receptor por medio de un diodo IR. MAndaria A o E en funcion de si el contacto cierra o abre.
El receptor abrira o cerrara un contacto a su vez en funcion del caracter que le llegue. Por seguridad si pasado un tiempo no ha recibido nada en el puerto abriria el contacto hasta que vuelva a recibir orden de cerrar.
Os pego lo que tengo hecho y antes de seguir me decis si voy bien o no, os estaria agradecido.
Emisor
//***************************************************************************
//******
//******
//****** NOTE: usa compilador: PCW v2.619
//******
//******
//******
//****************************************************************************

#include <16F84A.H>
#fuses XT,NOWDT
#use delay(clock=4000000,RESTART_WDT)

// define el puerto serie como 9660. 8 bits sin paridad y
// salida por pin RB0 y entrada de datos por pin RB6

#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_B4, RCV=PIN_B6, RESTART_WDT)

#use fast_io(B)

                     // definiciones de  posiciones de memoria

#byte TMR0=0x01
#byte PORTA=0x05
#byte PORTB=0x06
#byte INTCON=0x0b
#byte OPTION_REG=0x81

// el emisor usa la entrada RB7 como deteccion de puesta en marcha y paro
// la salida RB0 es la salida de datos al diodo IR

//*********************
// PROGRAMA PRINCIPAL *
//*********************

void delay_seconds(int n)
   {
  for (;n!=0; n--)
  delay_ms( 1000 );
   }

void main()
      {
      set_tris_b(0b10000000);  // PIN_B0 = Salida(TxD)
      While(1)
         {
         // cada 10 segundos

         delay_seconds(10);

         // si esta activa RB7 envia por el puerto E de Encender
         // si Rb7 esta a cero envia por el puerto A de Apagar

         if(input(PIN_B1))
            {
            putc("E");
            }
         else
            {
            putc("A");
            }
         }
      }


Receptor

#include <16F84A.H>
#fuses XT,NOWDT
#use delay(clock=4000000,RESTART_WDT)

// define el puerto serie como 9660. 8 bits sin paridad y
// salida por pin RB0 y entrada de datos por pin RB6

#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_B0, RCV=PIN_B6, RESTART_WDT)

#use fast_io(B)

                     // definiciones de  posiciones de memoria

#byte TMR0=0x01
#byte PORTA=0x05
#byte PORTB=0x06
#byte INTCON=0x0b
#byte OPTION_REG=0x81

// la entrada RB6 como entrada de datos del receptor
// la salida  RA1 sera la que active el rele


//*********************
// PROGRAMA PRINCIPAL *
//*********************

void delay_seconds(int n)
   {
  for (;n!=0; n--)
  delay_ms( 1000 );
   }

byte int_count;    // Numero de interrupciones antes de apagar



// esta funcion se llama cada vez que el timer rebosa
// se decrementa en 1 int_cont y si llega a cero
// entonces se pone a cero la salida del rele

#int_rtcc                        
clock_isr()
   {                                            
   if(--int_count==0)
       {          
       int_count=255;
       output_bit(PIN_A1,0);
       }
   }  


void main()
      {
     short Salida;

   int_count=255;
   set_rtcc(0);
   setup_counters( RTCC_INTERNAL, RTCC_DIV_256);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   
     Salida=0;
     set_tris_b(0b10000000);  // PIN_B6 = Entrada(RxD)
     set_tris_a(0b01000000);  // PIN_A0 = Salida al rele

     While(1)
         {
         switch(getch())
            {
            case "E": Salida  = 1;     break;
            case "A": Salida  = 0;     break;
            }
         int_count=255;
         output_bit(PIN_A1,Salida);
          }
      }


Nota el tiempo de espera de la interrupcion no esta aun ajustado
Opiniones por favor, es que el Proteus no me funciona asi que no puedo chequear el codigo

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: Comunicacion IR en rs232
« Respuesta #1 en: 13 de Junio de 2005, 11:31:00 »
He conseguido simularlo en Proteus, aunque el enlace es directo sin IR pero funciona. Pero aun tengo algunos problemas.
El dioso led del emisor se queda encendido despues de enviar el mensaje y eso gasta bateria.
Ademas no se si funcionara el tiempo de espera del receptor para que me pare si no detecta mensaje en un tiempo prudencial. Vuelvo a pegar el codigo que ya funciona en proteus y si alguie quiere el fichero de proteus que me lo pida a masmontero@hotmail.com
LA idea es hacer un sistema de calefaccion en que el sensor de temperatura este alejado del radiador para que este no falsee la medida y que el enlace no sea por cables.
Emisor
//***************************************************************************
//******
//******
//****** NOTE: usa compilador: PCW v2.619
//******
//******
//******
//****************************************************************************

#include <16F84A.H>
#fuses XT,NOWDT
#use delay(clock=4000000,RESTART_WDT)

// define el puerto serie como 9660. 8 bits sin paridad y
// salida por pin RB0 y entrada de datos por pin RB6

#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_B4, RCV=PIN_B6, RESTART_WDT)

#use fast_io(B)

                     // definiciones de  posiciones de memoria

#byte TMR0=0x01
#byte PORTA=0x05
#byte PORTB=0x06
#byte INTCON=0x0b
#byte OPTION_REG=0x81

// el emisor usa la entrada RB1 como deteccion de puesta en marcha y paro
// la salida RB4 es la salida de datos al diodo IR

//*********************
// PROGRAMA PRINCIPAL *
//*********************
void delay_seconds(int n) {

  for (;n!=0; n--)

  delay_ms( 1000 );

}

 


void main()
      {
      set_tris_b(0x0f);  //
      output_low(PIN_B4);
      While(1)
         {

         // el retardo se usa para no estar enviando permanentemente en mensaje y conservar la bateria del emisor

         delay_seconds(5);
         
         // si esta activa RB1 envia por el puerto E de Encender
         // si Rb1 esta a cero envia por el puerto A de Apagar

        if(input(PIN_B1))
            {
            putc("E");
            }
        else
            {
            putc("A");
            }
         }
      }


Receptor
//***************************************************************************
//******
//******
//****** NOTA: usa compilador: PCW v2.619 o posterior
//******
//******
//******
//****************************************************************************

#include <16F84A.H>
#fuses XT,NOWDT
#use delay(clock=4000000,RESTART_WDT)

// define el puerto serie como 9660. 8 bits sin paridad y
// salida por pin RB0 y entrada de datos por pin RB6

#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_B0, RCV=PIN_B6, RESTART_WDT)

#use fast_io(B)

                     // definiciones de  posiciones de memoria

#byte TMR0=0x01
#byte PORTA=0x05
#byte PORTB=0x06
#byte INTCON=0x0b
#byte OPTION_REG=0x81

// la entrada RB6 como entrada de datos del receptor
// la salida  RA1 sera la que active el rele


//*********************
// PROGRAMA PRINCIPAL *
//*********************

void delay_seconds(int n)
   {
  for (;n!=0; n--)
  delay_ms( 1000 );
   }


byte int_count;    // Numero de interrupciones antes de que el segundo contador este a cero



// esta funcion se llama cada vez que el timer rebosa
// se decrementa en 1 int_cont y si llega a cero
// entonces se pone a cero la salida del rele

#int_rtcc
clock_isr()
   {
   if(--int_count==0)
       {
       int_count=255;
       output_bit(PIN_A1,0);
       }
   }


void main()
      {
     short Salida;

   int_count=255;
   set_rtcc(0);
   setup_counters( RTCC_INTERNAL, RTCC_DIV_256);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

     Salida=0;
     set_tris_b(0x00);  // PIN_B6 = Entrada(RxD)
     set_tris_a(0xff);  // PIN_A0 = Salida al rele

     While(1)
         {
         switch(getch())
            {
            case "E": Salida  = 1;     break;
            case "A": Salida  = 0;     break;
            }
         int_count=255;
         output_bit(PIN_A1,Salida);
          }
      }



Desconectado gustav03

  • PIC10
  • *
  • Mensajes: 31
RE: Comunicacion IR en rs232
« Respuesta #2 en: 18 de Junio de 2005, 22:08:00 »
**hola Algec yo tengo algo similar comunico dos 16F84A con protocolo serie .Pero primero veo cosas que son innecesarias como:

#byte TMR0=0x01
#byte PORTA=0x05
#byte PORTB=0x06
#byte INTCON=0x0b
#byte OPTION_REG=0x81
estos byte ya estan definidos en 16F84A.h

**otra cosa que te puede ayudar es usar la interrupción externa para tomar los datos del otro pic :
#define Tx PIN_B1 // PIN de Transmisión (acá podes usar cualquiera)
#define Rx PIN_B0 // PIN de Recepción    (este activa la recepción por INT_EXT)
#use rs232(baud=9600, xmit=Tx, rcv=Rx)

para recivir los datos seria algo asi:
#int_EXT
EXT_isr1()
{
byte a=0;
   if(kbhit()) {   //Esto es para que no se te cuelgue el pic
      a = getc();
         puerto_a=0;
         output_high(PIN_B2);           // prendo led
         delay_ms(50);
         output_low(PIN_B2);           // apago led
         bit_clear(a,7);
         funcion(a);    // en lugar de esto pones lo que quieras
   }
}

haciéndolo de esta forma podrías poner el pic a dormir mientras no lleguen nuevas ordenes y no tendrías que tener corriendo una rutina infinita-
En cuanto a hacerlo por IR tendrías que tener en claro la frecuencia de trabajo del IR .
 podrías usar mas recursos del ccs y establecer una comunicación bilateral para saber que todo salio bien en el otro pic luego de mandar los bytes.

En el manual de ccs que me recomendó pikman hay un ejemplo poco explicado de como hacer una comunicación con un solo pin :
#use rs232(baud=9600, float_high, bits=9, xmit=PIN_B0, rcv=PIN_B0)
en los ejemplos que trae el ccs esta (EX_PBUSM.C and EX_PBUSR.C)
yo todavía no logro mucho con este método pero seria muy interesante poder hacerlo con un solo pin.
suerte






 

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: Comunicacion IR en rs232
« Respuesta #3 en: 19 de Junio de 2005, 14:15:00 »
Gracias por responderme, ya tengo el sistema funcionando al menos en Proteus, y las placas diseñadas.
En principio sirve por IR, ya te digo que en Proteus funciona, te paso si quieres el codigo que utilizo y el diseño de hard, y cuando lo tenga funcionando te digo si va y donde estan los posibles problemas que surjan.


 

anything