Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

20/11/2013 #1

Avatar de jjcordoba

Modulos RF 315 Mhz y micro 16f887
He tratado realizar la comunicación de dos micros 16f887 mediante los módulos de RF y resulta que si conecto los dos micros con cable funciona todo muy bien, pero al poner los módulos RF no funciona.
Tengo un testigo para mirar que recibe y resulta que el led está parpadeando (otras señales o ruido).
No logro aún eliminar ese ruido. La idea es que al pulsar un botón el otro encienda un led y que al pusar otro botón se apague

PROGRAMA RECEPTOR
Código:
void main( void ){
 
//Declaración de variables.
char ARMADO;
 
//Configuración de puertos.
 
OSCCON = 0b01110110; //Oscilador interno a 4MHz
 
ANSEL = 0; //Configura portA como digital
ANSELH = 0; //configura los demas puertos como digitales
 
TRISA = 0xFF; // PORTA is input
TRISB = 0; // PORTB is output
TRISC = 0xFF; // PORTC is input
TRISD = 0xFF; // PORTD is input
 
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
 
//Configuración del puerto serial.
UART1_Init(9600);
 
do{ //Bucle infinito.
 
if(UART1_Data_Ready()==1){ //La sentencia if evalúa si un dato está listo para leer.
ARMADO = UART1_Read(); //Se lee el DATO del bufer.
 
if (ARMADO==30){
PORTB = 0B00001111;
Delay_ms(100); //tiempo de retardo
 
}
if (ARMADO==20){
PORTB = 0B00000000;
Delay_ms(100); //tiempo de retardo
}
}
if((PORTA.F7==0)&&(ARMADO==20)){ //Evalúa el estádo del pulsador por RA1, q se activado en bajo.
Delay_ms(2000); //tiempo de retardo
PORTB = 0B00001111;
}
} while(1);
}
PROGRAMA TRANSMISOR
Código:
void main( void ){
 
//Declaración de variables.
char ARMADO;
 
//Configuración de puertos.
 
OSCCON = 0b01110110; //Oscilador interno a 4MHz
 
ANSEL = 0; //Configura portA como digital
ANSELH = 0; //configura los demas puertos como digitales
 
TRISA = 0xFF; // PORTA is input
TRISB = 0; // PORTB is output
TRISC = 0xFF; // PORTC is input
TRISD = 0xFF; // PORTD is input
 
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
 
//Configuración del puerto serial.
UART1_Init(9600);
 
do{ //Bucle infinito.
 
if(UART1_Data_Ready()==1){ //La sentencia if evalúa si un dato está listo para leer.
ARMADO = UART1_Read(); //Se lee el DATO del bufer.
 
if (ARMADO==30){
PORTB = 0B00001111;
Delay_ms(100); //tiempo de retardo
 
}
if (ARMADO==20){
PORTB = 0B00000000;
Delay_ms(100); //tiempo de retardo
}
}
if((PORTA.F7==0)&&(ARMADO==20)){ //Evalúa el estádo del pulsador por RA1, q se activado en bajo.
Delay_ms(2000); //tiempo de retardo
PORTB = 0B00001111;
}
} while(1);
}
De ante mano muchas gracias por su ayuda. Trabajo en mikroC.
20/11/2013 #2

Avatar de Ajna

Esa frecuencia de 315Mhz es libre y usada por infinidad de aparatos por eso hay muchas señales por volando que puede detectar tu PIC he interpretarlas como validas, para poder asegurar de que funcione bien debes implementar rutinas de verificación de datos, ademas no esta de mas poner un filtro "acorde a la frecuencia con la que envías datos" para evitar que ese molesto ruido generado por el receptor, pueda estar disparando a tu micro receptor sin necesidad. Si conectas la salida del receptor a un osciloscopio veras como se generan picos de tensión. Yo use la codificación manchester, creo que da buenos resultados, envíe 2 bits de inicio que siempre son 1 para detectar si lo que viene después es valido, luego envíe 4 bits para identificar al transmisor que esta "valga la redundancia" transmitiendo, y luego envíe el byte de datos luego un bit de parada que siempre es cero, solo para validar que el mensaje llego completo.

Esto reduce mucho el ancho de banda, pero después de todos estos módulos están pensados para trabajar en aplicaciones de on/off.
20/11/2013 #3

Avatar de cosmefulanito04

Tenés que trabajar con tramas de datos y así descartar el ruido. Ejemplo, c/elemento es un byte:

Código PHP:
Código de mensaje DirDestino DirOrigen | .... Datos .... | Check-sum 
Entonces para tomar un dato válido, solo deberías esperar un código de mensaje válido y verificar el check-sum.

A nivel de hard, te recomiendo invertir la salida de la uart, cuando está en reposo la uart está en 1 lógico, eso es poco práctico en RF, ya que estas transmitiendo todo el tiempo la portadora.
20/11/2013 #4

Avatar de jjcordoba

entiendo que es una banda abierta y por tanto muchas mas señales interfieren y entiendo que debo lograr algún tipo de codificación, en realidad he buscado y no logro entenderlo bien la codificación en programación si no es muy atrevido de mi parte y me pueden permitir un código ejemplo con el cual guiarme les agradecería mucho.
20/11/2013 #5

Avatar de cosmefulanito04

Tenés que hacerte dos funciones, una de recepción y otra de transmisión, ejemplo de los prototipos:

Código PHP:
int transmitir_trama_rf(u8 codigo_mensaje,u8 dir_destino,u8 dir_origen,u8 buffer_datos[],u8 tamanio); 
Donde:
  • u8: es una variable del tipo unsigned char.
  • codigo_mensaje: un byte que indicará el tipo de mensaje, será un protocolo que vos definas.
  • dir_destino: dirección con el equipo que te vas a comunicar.
  • dir_origen: el equipo que envió el mensaje.
  • buffer_datos: será un vector del tipo unsigned char donde estarán los datos del mensaje.
  • tamanio: el tamaño del vector de datos.
  • Internamente se deberá generar un check_sum, es decir ir sumando en una variable todos los datos que se envían.
  • En caso de que la transmisión no tuvo inconvenientes, devolverá un 1, caso contrario -1 y se deberán tomar las medidas adecuadas en la rutina que llamo a la función.

Por el lado del receptor, luego de recibir el 1er byte del código de mensaje con un switch, tomás la decisión usando una función de este tipo:

Código PHP:
int recibir_trama_rf(u8 mi_dir,u8 *dir_origen,u8 buffer_datos_recibidos[],u8 tamanio); 
Donde:
  • mi_dir: será la dirección propia del equipo, verificará que el mensaje recibido sea para él.
  • *dir_origen: es una variable que la pasas por referencia por si resulta útil saber que equipo envió el mensaje (para un ACK a futuro).
  • buffer_datos_recibidos: un vector de datos adecuado según el mensaje a recibir, previamente pactado por el código de mensaje.
  • tamanio: el equipo que envió el mensaje.
  • Internamente se deberá generar un check_sum, es decir ir sumando en una variable todos los datos que se reciben y compararlo con el byte de check-sum que envió el transmisor.
  • En caso de que la transmisión no tuvo inconvenientes, devolverá un 1, caso contrario -1 y se deberán tomar las medidas adecuadas en la rutina que llamo a la función.

Las funciones son bastante sencillas de realizar, solo es enviar/recibir todos esos datos por una uart y verificar que dichos datos sean correctos.
20/11/2013 #6

Avatar de jjcordoba

muchas gracias por su ayuda me pondré a trabajar en las funciones
22/11/2013 #7

Avatar de jjcordoba

cosmefulanito04 dijo: Ver Mensaje
Tenés que trabajar con tramas de datos y así descartar el ruido. Ejemplo, c/elemento es un byte:

Código PHP:
Código de mensaje DirDestino DirOrigen | .... Datos .... | Check-sum 
Entonces para tomar un dato válido, solo deberías esperar un código de mensaje válido y verificar el check-sum.

A nivel de hard, te recomiendo invertir la salida de la uart, cuando está en reposo la uart está en 1 lógico, eso es poco práctico en RF, ya que estas transmitiendo todo el tiempo la portadora.


trate de simplificar un poco para hacer pruebas solo envio bit de inicio/dato/bit de fin resulta que no logro que se comuniquen ni conectados, si me puedes ayudar en algo adjunto los codigos de igual manera sigo trabajando en ellos, muchas gracias
Archivos Adjuntos
Tipo de Archivo: txt transmisor.txt (1,7 KB (Kilobytes), 61 visitas)
Tipo de Archivo: txt receptor.txt (3,5 KB (Kilobytes), 12 visitas)
22/11/2013 #8

Avatar de Ajna

.................................
22/11/2013 #9

Avatar de cosmefulanito04

Ok, no esta mal lo que intentas hacer, pero corregiría un par de cosas:

- Sacá los "Delay_ms (100)" del transmisor, directamente enviá la trama de una, es importante que los bytes lleguen juntos, que es cuando te "aislas" del ruido por la presencia de la portadora y no enviar bytes en forma esporádica en presencia de ruido.

- En el receptor el "if(temp = 0x0E)" está de más y no permite que recibas los datos. La correción sería esta:


Código PHP:
                  do{
                           
temp Man_Receive(&error);             // Intento recibir byte
                           
if (error) {                            // si hay error
                           
ErrorCount++;                           // aumento ErrorCount
                             
if (ErrorCount 20) {                // si el error es mayor a 20
                             
temp Man_Synchro();                 //Intente sincronizar nuevamente
                             //Man_Receive_Init();                 //Intento inicializar el receptor nuevamente
                             
ErrorCount 0;                       // Reset error
                             
}
                           }
                           else {
                           
                                    if (
temp==30){
                                    
PORTB 0B00001111;
                                    
                                    }
                                    
                                    if (
temp==20){
                                    
PORTB 0B00000000;
                                    
                                    }

                                    if((
PORTA.F7==0)&&(temp==20)){              //Evalúa el estádo del pulsador por RA1, q se activado en bajo.
                                    
                                    
PORTB 0B00001111;
                                    }
                            
                            
                           }
                       

                          
                          }while (
temp != 0x0E);       //hacer hasta recibir "fin" 
El foro levanto medio desprolijo el código, pero creo que se entiende, es solo anular ese if y los delay.

Esos módulos yo los usé con velocidades de 2400bps, a menor velocidad mejor sensibilidad hacia el ruido.
23/11/2013 #10

Avatar de jjcordoba

muchas gracias por su ayuda, el programa ya ha mejorado mucho ya logro que en ocasiones se active por el pulso que yo mando y estan en comunicación constante los pic, ya es cuestión de mejorar para que siempre se active al pulso enviado.
Recibo sugerencias de como puedo mejorar esto
23/11/2013 #11

Avatar de cosmefulanito04

Lo que mejoraría y mucho la comunicación, es una retransmisión de las tramas, de esa forma le das al receptor más oportunidades de recibir una trama válida.
24/11/2013 #12

Avatar de StrySG

Justamente trabajo en algo similar.
Lo que mejoraría y mucho la comunicación, es una retransmisión de las tramas, de esa forma le das al receptor más oportunidades de recibir una trama válida.
Creo que no es mala idea enviar 2 o 3 tramas para cada mensaje, si una trama recibida no es correcta las otras dos podrían ser las correctas habrá menos probabilidad de error.
25/11/2013 #13

Avatar de jjcordoba

StrySG dijo: Ver Mensaje
Justamente trabajo en algo similar.


Creo que no es mala idea enviar 2 o 3 tramas para cada mensaje, si una trama recibida no es correcta las otras dos podrían ser las correctas habrá menos probabilidad de error.

creo haberles entendido he hice lo siguiente en el codigo agregar 2 envios mas aun asi persiste el hecho de que en ocasiones se activa y en otras no, adjunto los códigos, y muchas gracias por sus sugerencias y ayuda
Archivos Adjuntos
Tipo de Archivo: txt recepto.txt (3,1 KB (Kilobytes), 20 visitas)
Tipo de Archivo: txt transmiso.txt (2,8 KB (Kilobytes), 17 visitas)
25/11/2013 #14

Avatar de cosmefulanito04

¡No seas cabezón!

¡Usá un for/while! y repetilo 5 o incluso 10 veces. Para darte una idea, el encoder HT12e envía 4 veces la trama de bits (no bytes, bits) y solo hablamos de 1 nibble datos con un byte de dirección.

Lo malo de estos módulos que es que necesitas 2 pares para realizar una comunicación con acuse de recibo, eso es lo que hacía yo, luego de no recibir ese ACK durante un tiempo aleatorio, volvía a enviar el dato.
25/11/2013 #15

Avatar de jjcordoba

cosmefulanito04 dijo: Ver Mensaje
¡No seas cabezón!

¡Usá un for/while! y repetilo 5 o incluso 10 veces. Para darte una idea, el encoder HT12e envía 4 veces la trama de bits (no bytes, bits) y solo hablamos de 1 nibble datos con un byte de dirección.

Lo malo de estos módulos que es que necesitas 2 pares para realizar una comunicación con acuse de recibo, eso es lo que hacía yo, luego de no recibir ese ACK durante un tiempo aleatorio, volvía a enviar el dato.
ok muchas gracias ya lo corrijo y agrego el for, lo pondre po ahora que lo mande 5 veces muchas gracias
27/11/2013 #16

Avatar de jjcordoba

cosmefulanito04 sus propuestas han sido un exito y me han ayudado bastante, al igual que las demas sugerencias ahora me encuentro como todo en la electronica con un problema en montaje que al igual considero puede ser solucionado con el codigo en C y es que trabaja todo muy bn pero si me alejo lo suficiente para que el control no transmita resulta q el receptor se deja afectar por otras señales, me hago entender si el control (transmisor) esta cerca al receptor todo muy bien pero si alejo el control o le quito la alimentación el receptor se ve afectado por otras señales. alguana sugerencia como eliminar este factor de antemano muchas gracias
27/11/2013 #17

Avatar de StrySG

¿A que frecuencia de reloj trabaja el micro? Leí que con estos módulos RF es preferible usar un clock < 4Mhz para que el propio uc no añada ruido en exceso al RX.
¿Le colocaste antena a los módulos? una antena de ~ 23 cm mejoraría la reccepcción, si nada de eso funciona como dice un mensaje más arriba habrá que filtrar o limitar el ancho de banda del receptor... podría ser con un circuito tanque.
27/11/2013 #18

Avatar de cosmefulanito04

jjcordoba dijo: Ver Mensaje
...es que trabaja todo muy bn pero si me alejo lo suficiente para que el control no transmita resulta q el receptor se deja afectar por otras señales, me hago entender si el control (transmisor) esta cerca al receptor todo muy bien pero si alejo el control o le quito la alimentación el receptor se ve afectado por otras señales. alguana sugerencia como eliminar este factor de antemano muchas gracias
A ver, tenés varios problemas por lo que comentas:
  1. Distancia entre Tx y Rx no muy grande.
  2. Señales que intervienen en la comunicación.

El primer problema lo podés atacar de la siguiente forma:
  • Usar buenas antenas en ambos lados, en este tipo de transmisores la antena debe presentar una impedancia de 50Ohms. Por experiencia te puedo decir que un cable coaxil funciona bastante bien.
  • Usar la máxima tensión de fuente permitida en el transmisor. En los que yo usé la tensión de alimentación podías llevarla a 12v, esto requiere hacer un cambio de nivel de tensión a 12v en el la uart del transmisor.
  • Como mencioné antes, la uart en estado de reposo deja el bit de transmisión en un "1" lógico, esto implica que reposo tu módulo de transmisión está todo el tiempo enviando la portadora, esto es un problema ya que estas contaminando el espectro en esa frecuencia impidiendo que otro transmisor pueda trabajar. En otras palabras, si todos los transmisores están en "1" lógico, todos se interfieren, mala idea para múltiples puntos de transmisión. Esto se soluciona con el cambio de nivel explicado en el punto anterior.
  • Reducir la velocidad de la uart.
  • Mejorar el PCB lo máximo posible, separando bien las masas de alta frecuencia del transmisor/receptor con las masas digitales.

Con todo eso, yo usando unos módulos de 433MHz, conseguí una distancia máxima de 30mts indoor a 2400bps, mucho más no le podes pedir a esos módulos.

Sobre el segundo problema:

Siempre vas a estar recibiendo datos, ya sean válidos o no. Tu objetivo en el receptor es diferenciar bien cual es un dato válido de uno que no lo es, para eso usaste las tramas que te mencioné. Mientras más complejas sean esas tramas, menos probabilidad de tomar un dato inválido como válido.

En tu caso, como usas 3 bytes para diferenciar dato válido de dato inválido, dándote una probabilidad de tomar un dato inválido como válido de:

P(error en el descarte)=1/256*2/256*1/256*100=0,00001 %

O sea, probabilidad de tomar una trama inválida como válida es bastante baja.

Ahora el problema que tiene tu protocolo de comunicación es que no distingue el transmisor/receptor que se verá involucrado en la comunicación, esto es válido si solo tenes un transmisor y un receptor, pero obviamente deja de ser útil cuando hay múltiples transmisores/receptores.
28/11/2013 #19

Avatar de jjcordoba

voy a intentar las soluciones que me plantean, lo de la antena y aumentar el voltaje en el transmisor. de igual manera adjunto imágenes del circuito como lo tengo montado y tratare de mejorar la trama. muchas gracias
Imágenes Adjuntas
Tipo de Archivo: png receptor.PNG (36,0 KB (Kilobytes), 28 visitas)
Tipo de Archivo: png transmisor.PNG (49,1 KB (Kilobytes), 25 visitas)
28/11/2013 #20

Avatar de cosmefulanito04

La trama modificala solo si vas a trabajar con múltiples transmisores/receptores. De lo contrario, dejala así.

¿Qué módulos usas, podes subir su hoja de datos?

Del esquemático que vi, salvo que los módulos recomienden eso, colocar un capacitor de 100nF a derivación en la salida/entrada de la antena es muuuuuuy raro, más si ese capacitor (idealmente) presenta una impedancia de 5mOhms a 315MHz .

Si me parece correcto colocar ese capacitor de 100nF entre Vcc del módulo y GND.
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.