Comunicación de PIC a PIC por radio frecuencia con módulos de 434MHz
Comunicación de PIC a PIC por radio frecuencia con módulos de 434MHz
Hola a todos. Estoy realizando un
proyecto para la facultad en la cátedra de técnicas digitales 2
utilizando el compilador C de CCS. Consiste en comunicar dos pic con
los módulos transmisor y receptor de 434Mhz. Hemos avanzado bastante
en el código pero a la hora de probar todo casi nunca se recibe una
señal correctamente. El ruido hace casi imposible la comunicación.
Cuando se conecta el pin del pic transmisor al pin del pic receptor
por medio de un cable la comunicación es perfecta, pero no así con
los módulos RF.
La codificación consiste en enviar una trama
de 8, 12 o 16 bit de 1 y 0 al principio, que sirven para
estabilizar el sistema receptor y luego sigue una clave de 8 o 14
bits mas 4 u 8 bits de datos.
Cada bit de la señal dura 500us
por lo que en teoría se estaría trabajando a 1/500us = 2000baudios.
Entre la trama de estabilización y la
clave de 8 bits existe un retardo intermedio de 500us que podría ser
interpretado como un 0, pero ese no es el caso, este retardo sirve
para sincronizar el receptor con el emisor, ¿Como?, simple con un:
Y así sucesivamente con los 8 bits de
la clave y los 4 bits de datos.
Las líneas "clave_1_ =
pin_receptor;" demoran 7us en ejecutarse (medidos con
mplab-sim), por eso se dejan pasar 246us luego 7us para guardar el
bit en la variable "clave_x_" y al final 247us mas para
sumar así un total de 500us que dura cada bit.
Bueno les dejo el código que estoy
probando para ver como si le anda a alguien o si encuentra algún
error o tiene alguna sugerencia. En este punto estoy estancado y
sinceramente pensé que iba a ser mas sencillo, no me imagine que iba
a haber tanto ruido.
Bueno saludos a todos y al que le
interese este proyecto podemos trabajar en conjunto!!!. Saludos.
El código esta en C del compilador CCS y es para un pic 12F629, pero
puede ser adaptado con mínimos cambios para cualquier otro pic. (No
he visto la necesidad de utilizar un pic mas potente y por ende mas
caro).
"Este código de prueba consiste 16 bits para
la trama de estabilización + 6 bits para la clave y 2 bits de
datos."
proyecto para la facultad en la cátedra de técnicas digitales 2
utilizando el compilador C de CCS. Consiste en comunicar dos pic con
los módulos transmisor y receptor de 434Mhz. Hemos avanzado bastante
en el código pero a la hora de probar todo casi nunca se recibe una
señal correctamente. El ruido hace casi imposible la comunicación.
Cuando se conecta el pin del pic transmisor al pin del pic receptor
por medio de un cable la comunicación es perfecta, pero no así con
los módulos RF.
La codificación consiste en enviar una trama
de 8, 12 o 16 bit de 1 y 0 al principio, que sirven para
estabilizar el sistema receptor y luego sigue una clave de 8 o 14
bits mas 4 u 8 bits de datos.
Cada bit de la señal dura 500us
por lo que en teoría se estaría trabajando a 1/500us = 2000baudios.
- Código:
Señal de ejemplo:
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0--1 0 0 1 1 1 0 1--0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0--delay_us(500)--1 0 0 1 1 1 0 1--0 1 0 1
------------------------------- ---------------- --------
Trama de estabilización de señal Clave 8 bits Dato
Entre la trama de estabilización y la
clave de 8 bits existe un retardo intermedio de 500us que podría ser
interpretado como un 0, pero ese no es el caso, este retardo sirve
para sincronizar el receptor con el emisor, ¿Como?, simple con un:
- Código:
while(pin_receptor==0)
{
}
- Código:
delay_ms(8); //Tiempo que se demora en recibir la trama de estabilización.
While(pin_receptor==0) //While encargado de la sincronización.
{
}
delay_us(246);
clave_0_ = pin_receptor; //Se muestrea el 1° bit en la mitad de su tiempo de duración.
delay_us(247);
delay_us(246);
clave_1_ = pin_receptor; //Se muestrea el 2° bit
delay_us(247);
.
.
.
.
.
.
Y así sucesivamente con los 8 bits de
la clave y los 4 bits de datos.
Las líneas "clave_1_ =
pin_receptor;" demoran 7us en ejecutarse (medidos con
mplab-sim), por eso se dejan pasar 246us luego 7us para guardar el
bit en la variable "clave_x_" y al final 247us mas para
sumar así un total de 500us que dura cada bit.
Bueno les dejo el código que estoy
probando para ver como si le anda a alguien o si encuentra algún
error o tiene alguna sugerencia. En este punto estoy estancado y
sinceramente pensé que iba a ser mas sencillo, no me imagine que iba
a haber tanto ruido.
Bueno saludos a todos y al que le
interese este proyecto podemos trabajar en conjunto!!!. Saludos.
El código esta en C del compilador CCS y es para un pic 12F629, pero
puede ser adaptado con mínimos cambios para cualquier otro pic. (No
he visto la necesidad de utilizar un pic mas potente y por ende mas
caro).
"Este código de prueba consiste 16 bits para
la trama de estabilización + 6 bits para la clave y 2 bits de
datos."
- Código:
Código para el PIC Transmisor:
=============================================================================
#include <12F629.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES CPD //Data EEPROM Code Protected
#FUSES PROTECT //Code protected from reads
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES PUT //Power Up Timer
#FUSES BROWNOUT //Reset when brownout detected
#use delay(clock=4M)
#byte IOC = 0x96 //Registro de configuración de interrupción in_RA para cada pin individual.
//Se nombran los pines usados.
#bit pin_data = 0x05.0 //Pin 0 es salida de datos, conectado directo a la entrada del módulo transmisor.
#bit pin_1 = 0x05.1
#bit pin_2 = 0x05.2
#bit pin_3 = 0x05.3
#bit boton_1_ = 0x05.4 //Pin 4 es el boton 1.
#bit boton_2_ = 0x05.5 //Pin 5 es el boton 2.
//Variables.
int8 i;
//Funciones.
void boton_1_presionado(void);
void boton_2_presionado(void);
#int_RA
void RA_isr() //Función de atención a la interrupción por cambio de nivel.
{
#ASM //Código necesario para prevenir falla en una interrupción por cambio de nivel.
movf 0x05,0
clrw
#ENDASM
pin_data = 0;
delay_ms(50); //Previene rebotes.
if(boton_1_==1) //Si el boton 1 fue presionado se manda la señal boton_1_presionado();.
{
for(i=0; i<5; i++) //Cada señal se envía 5 veces.
{
boton_1_presionado();
delay_ms(5); //Se envían 5 veces una cada 5ms.
}
}
else //Si no se manda boton_2_presionado();.
{
for(i=0; i<5; i++) //Cada señal se envía 5 vaces.
{
boton_2_presionado();
delay_ms(5); //Se envían 5 veces una cada 5ms.
}
}
pin_data = 0;
while(boton_1_==1) //Se sale de la interrupción cuando se suelta el botón.
{
}
while(boton_2_==1) //Se sale de la interrupción cuando se suelta el botón.
{
}
delay_ms(50); //Previene rebotes.
}
void main() //Programa principal.
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_comparator(NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RA); //Interrupción por cambio de nivel en algún pin.
IOC = 0b00110000; //Habilita interrupciones por cambio de nivel solo en pin_4 y pin_5_.
enable_interrupts(GLOBAL);
set_tris_A(0b00111110); //Todas entradas pin_0_ como salida.
port_a_pullups(TRUE); //Habilita resistencias de pull_up en puertos configurados como entradas.
pin_data = 0;
while(TRUE)
{
sleep();
}
}
void boton_1_presionado(void) //Función para enviar señal 1.
{
pin_data = 1; //Inicio y estabilización de la transmisión, 16 bits (1010101010101010).
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 0; //500us para sincronización.
delay_us(500);
pin_data = 1; //1º bit de la clave.
delay_us(500);
pin_data = 0; //2º bit de la clave.
delay_us(500);
pin_data = 1; //3º bit de la clave.
delay_us(500);
pin_data = 0; //4º bit de la clave.
delay_us(500);
pin_data = 1; //5º bit de la clave.
delay_us(500);
pin_data = 1; //6º bit de la clave.
delay_us(500);
pin_data = 1; //1º bit de dato.
delay_us(500);
pin_data = 0; //2º bit de dato.
delay_us(500);
}
void boton_2_presionado(void) //Función para enviar señal 2.
{
pin_data = 1; //Inicio y estabilización de la transmisión, 16 bits (1010101010101010).
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 1;
delay_us(500);
pin_data = 0;
delay_us(500);
pin_data = 0; //500us para sincronización.
delay_us(500);
pin_data = 1; //1º bit de la clave.
delay_us(500);
pin_data = 0; //2º bit de la clave.
delay_us(500);
pin_data = 1; //3º bit de la clave.
delay_us(500);
pin_data = 0; //4º bit de la clave.
delay_us(500);
pin_data = 1; //5º bit de la clave.
delay_us(500);
pin_data = 1; //6º bit de la clave.
delay_us(500);
pin_data = 0; //1º bit de dato.
delay_us(500);
pin_data = 1; //2º bit de dato.
delay_us(500);
}
=============================================================================
- Código:
Código para el PIC Receptor:
=============================================================================
#include <12F629.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES CPD //Data EEPROM Code Protected
#FUSES PROTECT //Code protected from reads
#FUSES MCLR //Pin 3 usado como recet.
#FUSES PUT //Power Up Timer
#FUSES BROWNOUT //Reset when brownout detected
#use delay(clock=4M)
#byte IOC = 0x96 //Registro de configuración de interrupción in_RA para cada pin individual.
//Se nombran los pines usados.
#bit LED_0 = 0x05.0 //1º LED
#bit LED_1 = 0x05.1 //2º LED
#bit pin_2 = 0x05.2
#bit pin_recet = 0x05.3
#bit pin_4 = 0x05.4
#bit pin_receptor = 0x05.5 //Pin receptor conectado directamente al módulo receptor.
//Variables.
int1 clave_0_, clave_1_, clave_2_, clave_3_, clave_4_, clave_5_, dato_0_, dato_1_, correcta;
int8 contador, i;
//Constantes.
int1 const clave__0_ = 1, clave__1_ = 0, clave__2_ = 1, clave__3_ = 0, clave__4_ = 1, clave__5_ = 1;
#int_RA
void RA_isr()
{
#ASM
movf 0x05,0
clrw
#ENDASM
i = 0;
for(i=0; i<5; i++)
{
delay_ms(8); //Tiempo que tarda en recibirse la trama de estabilización.
While(pin_receptor==0) //Se sincroniza la recepción.
{
}
delay_us(246);
clave_0_ = pin_receptor; //Se muestrea el 1º bit.
delay_us(247);
delay_us(246);
clave_1_ = pin_receptor; //Se muestrea el 2º bit.
delay_us(247);
delay_us(246);
clave_2_ = pin_receptor; //Se muestrea el 3º bit.
delay_us(247);
delay_us(246);
clave_3_ = pin_receptor; //Se muestrea el 4º bit.
delay_us(247);
delay_us(246);
clave_4_ = pin_receptor; //Se muestrea el 5º bit.
delay_us(247);
delay_us(246);
clave_5_ = pin_receptor; //Se muestrea el 6º bit.
delay_us(247);
delay_us(246);
dato_0_ = pin_receptor; //Se muestrea el 7º bit.
delay_us(247);
delay_us(246);
dato_1_ = pin_receptor; //Se muestrea el 8º bit.
delay_us(247);
contador = 0;
if(clave__0_==clave_0_) //Si el 1º bit es correcto se incrementa el contador.
{
contador++;
}
if(clave__1_==clave_1_) //Si el 2º bit es correcto se incrementa el contador.
{
contador++;
}
if(clave__2_==clave_2_) //Si el 3º bit es correcto se incrementa el contador.
{
contador++;
}
if(clave__3_==clave_3_) //Si el 4º bit es correcto se incrementa el contador.
{
contador++;
}
if(clave__4_==clave_4_) //Si el 5º bit es correcto se incrementa el contador.
{
contador++;
}
if(clave__5_==clave_5_) //Si el 6º bit es correcto se incrementa el contador.
{
contador++;
}
if(contador==6) //Si contador es 6 la clave es correcta.
{
i = 5; //Entonces se sale del for.
correcta = 1;
}
delay_ms(5); //Cada repetición de la señal se envía cada 5ms.
}
if(correcta==1) //Si la clave era correcta se presentan los 2 bits recibidos.
{
LED_0 = dato_0_;
LED_1 = dato_1_;
correcta = 0;
}
delay_ms(500);
}
void main() //Programa principal.
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_comparator(NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RA);
IOC = 0b00100000; //Habilita interrupciones por cambio de nivel solo pin_5_.
enable_interrupts(GLOBAL);
set_tris_A(0b00111100); //Todas entradas, pin_0_ y pin_1_ entradas.
port_a_pullups(TRUE); //Habilita resistencias de pull_up en puertos configurados como entradas.
LED_0 = 0;
LED_1 = 0;
correcta = 0;
while(TRUE)
{
sleep();
}
}
=============================================================================
0110110h- Participante

- Cantidad de envíos: 11
Fecha de inscripción: 05/01/2009
Edad: 23
Localización: Argentina
Re: Comunicación de PIC a PIC por radio frecuencia con módulos de 434MHz
Wowwww, que interesante, estare pendiente del avance. Yo la verdad no tengo que aportar mas que los animos xD, pues aun voy por USB, pero muy interesante lo que estas haciendo y tiene mucho nicho de aplicacion. Saludos.

kainalu- Participante

- Cantidad de envíos: 14
Fecha de inscripción: 11/07/2009
Edad: 22
Localización: Medellin, Colombia
Re: Comunicación de PIC a PIC por radio frecuencia con módulos de 434MHz
Si.. muy interesante, y yo aquí lo más que puedo hacer es intentar aprender algo, pero como soy un atrevido y siempre me meto aunque no sepa mucho... pues me resulta extraño que con un módulo de 434Mhz y mandando datos a una velocidad tan lenta el ruido sea un problema.
Lo único que se me ocurre, así por decir algo es si podría haber algún fallo de sintonización entre los módulos... no sé si tendrán algún ajuste de sintoía o algo por el estilo.
...O que hay otra fuente de RF por ahí cerca...
Solo por curiosidad... has mirado en un osciloscopio la señal recibida?
No sé... cosas que se me ocurren:
-filtrar la señal del módulo a la entrada del pic.
-Hacer varias lecturas de cada bit. Usando delays se complica la cosa, pero otra opción es no usar delays sino usar una base de tiempo con timer0+interrupciones (por ejemplo) que haga lecturas a 1/10 de bit (por ejemplo) y luego si el nº de lecturas > 5 el bit es un 1, sinó es un 0.
La verdad es que tengo ganas de probar alguna cosa de estas en vez de estar con un cable entre pic y pc (por ejemplo), pero por lo que leo por ahí, suele haber bastantes problemas con esto del ruido, y hacer una transmisión a velocidades rapidas no es facil.
saludos y suerte con eso.
EDITO:
Perdonen mi ignorancia: esos módulos eliminan la portadora?... el receptor me refiero.
Supongo que sí, pero la verdad es que no tengo ni idea.
Lo único que se me ocurre, así por decir algo es si podría haber algún fallo de sintonización entre los módulos... no sé si tendrán algún ajuste de sintoía o algo por el estilo.
...O que hay otra fuente de RF por ahí cerca...
Solo por curiosidad... has mirado en un osciloscopio la señal recibida?
No sé... cosas que se me ocurren:
-filtrar la señal del módulo a la entrada del pic.
-Hacer varias lecturas de cada bit. Usando delays se complica la cosa, pero otra opción es no usar delays sino usar una base de tiempo con timer0+interrupciones (por ejemplo) que haga lecturas a 1/10 de bit (por ejemplo) y luego si el nº de lecturas > 5 el bit es un 1, sinó es un 0.
La verdad es que tengo ganas de probar alguna cosa de estas en vez de estar con un cable entre pic y pc (por ejemplo), pero por lo que leo por ahí, suele haber bastantes problemas con esto del ruido, y hacer una transmisión a velocidades rapidas no es facil.
saludos y suerte con eso.
EDITO:
Perdonen mi ignorancia: esos módulos eliminan la portadora?... el receptor me refiero.
Supongo que sí, pero la verdad es que no tengo ni idea.

Pikitin- veterano

- Cantidad de envíos: 329
Fecha de inscripción: 26/11/2008
Re: Comunicación de PIC a PIC por radio frecuencia con módulos de 434MHz
Hola pikitin estoy muy corto de tiempo esta semana pero la semana que viene voy a estar probando unas placas de prueba RF que diseñe con la esperanza que se reduzca el ruido ya que las pruebas anteriores las hice en unas placas de prueba con los modulos RF cableados. Estube mirando por el foro y encontre esto:
http://pic-linux.foroactivo.net/robotica-f13/vickymi-primer-pojecto-t173.htm
Donde para comunicar el robot con la PC Alejandro utiliza los mismos módulos RF que yo utilizo, solo que creo que el a programado en basic. Me acabo de bajar el codigo y voy a tratar de pasarlo a C. Saludos, en cuanto tenga algo nuevo les comento.
http://pic-linux.foroactivo.net/robotica-f13/vickymi-primer-pojecto-t173.htm
Donde para comunicar el robot con la PC Alejandro utiliza los mismos módulos RF que yo utilizo, solo que creo que el a programado en basic. Me acabo de bajar el codigo y voy a tratar de pasarlo a C. Saludos, en cuanto tenga algo nuevo les comento.
0110110h- Participante

- Cantidad de envíos: 11
Fecha de inscripción: 05/01/2009
Edad: 23
Localización: Argentina
Re: Comunicación de PIC a PIC por radio frecuencia con módulos de 434MHz
Acabo de ver el código a muy grandes rasgos y no caso una, espero tener suerte. Si alguno lo entiende soy todo oídos. Saludos.
0110110h- Participante

- Cantidad de envíos: 11
Fecha de inscripción: 05/01/2009
Edad: 23
Localización: Argentina
Permiso de este foro:
No puedes responder a temas en este foro.





