PIC12F675 y módulo de R.F, no recibe datos

#21
¿Existe forma de utilizar "GETS();" sin la interrupción externa, o de pasar strings y utilizar la función "KBHIT();" como ya lo estaba haciendo en los primeros codes?

Según el manual de CCS también podría utilizar la función "bit_test(var, bit);" de 0:15 bits para pasar palabras (strings) ¿Cómo sería esto? ¿Tenés algún ejemplo?
El problema de usar GETS() es que se queda en un bucle esperando un "\r" (ASCII 13 o Retorno de carro)
Entonces si se usa dentro del bucle del programa, éste se congelará hasta que GETS() retorne.
Y obviamente esto se hará indefinidamente, por eso de preferencia se usa GETS() por servicio de interrupción.

Sobre la instrucción BIT_TEST, podría funcionar realizando varias comparaciones.
No lo he hecho comparando las letras de una cadena pero tendría que ser una por una, realizando una especie de concatenación.

Como dato adicional:
El problema al usar 1200 Bps, no tan solo se presenta con PIC C Compiler, también sucede con el Basic de Proton IDE.
Con PIC C se presenta de una manera constante cada vez que se produce la interrupción externa y entra en ejecución la instrucción GETS.
Este problema de escritura indirecta hace que el programa deje de funcionar y no se puede solucionar aún utilizando punteros.

Con Proton IDE se presenta de vez en cuando, sin embargo el programa logra seguir su ejecución.
 
Última edición:
#22
D@rkbytes como va!

Se me ocurrió otra forma que creo podría funcionar, estoy por realizar las pruebas... Te copio los códigos, te parecen funcionales?

TX
PHP:
#include <12F675.h>
#fuses NOMCLR
#use delay(internal = 4MHz)
#use rs232(baud=2400, xmit=PIN_A2)

void menu()
{
   int contador = 0;  
   
   while (input(PIN_A3))
   {
      contador++;
      delay_ms(50);
   }  
    
   if (contador >= 1)
   {
      contador = 0;
      output_high(PIN_A5);
      puts("t");
      delay_ms(100);
      puts("e");
      delay_ms(100);
      puts("s");
      delay_ms(100);
      puts("t");
      delay_ms(100);      
      output_low(PIN_A5);
   }     
}

void main (void)
{
   putc(0x00);
   delay_ms(100);
   output_low(PIN_A5);
   
   while (true)
   { 
      menu();
   }
}
RX
PHP:
#include <12F675.h>
#include <stdio.h>
#include <string.h>
#fuses NOMCLR
#use delay(internal = 4MHz)
#use rs232(baud=2400, rcv=PIN_A2)

void main(void)
{
   char rcv_dato[10] = "";
   char buffer[10] = "";;
   
   output_low(PIN_A5);          
   
   while (true)
   {        
      if (kbhit())
      {
         buffer = getc();
         delay_ms(100);
         strcat(rcv_dato, buffer);
         
         if (rcv_dato == "test")
         {
            rcv_dato = "";
            output_high(PIN_A5);
         }         
      }
   }
}
Que te parecen? Se me ocurrió esto porque no logro comprender como enviar y recibir palabras/strings con "BIT_TEST"...

La idea del código es que TX envie una a una las letras o caracteres y en RX mediante la función "STRCAT" (según leí esta función sería algo parecido a concatenar ya que en C no existe "+" para hacerlo) la vaya almacenando en el array correspondiente para luego hacer la comparación con el condicional...

Saludos, AlanB! ;)
 
#23
No funcionará de esa forma porque GETC no puede guardar datos en un arreglo.
Se puede, pero indicando en que parte del arreglo se almacenará el dato, o sea, byte por byte.
Aparte, con tantos retardos no creo que se logre una buena sincronización.

Si ya estás usando 2400 Bps, ya no existe el problema de escritura indirecta que ocurre con 1200 Bps.

Mira el proyecto adjunto, está funcionando físicamente con comunicación bilateral a 4800 Bps.
Ahí se muestra lo que te mencionaba sobre monitorear el estado del pin de control en el receptor.

PD:
También adjunto el proyecto en Basic del Proton IDE.
 

Adjuntos

#24
D@rkbytes como va!

Logré el cometido gracias a tus explicaciones/ejemplos de código y a mis compañeros "Manual del Compilador CCS C" y "El Lenguaje de Programación en C SE" jajajaja :D ;)

Ya me funciona correctamente la conexión entre ambos pics y el bucle "FOR" no se queda permanentemente en ejecución, aún así tengo un par de dudas a consultarte... Para limpiar mi buffer ( char buffer[10]; ) se realiza de la siguiente forma ( buffer = ""; )???

Y otra consulta más, porque cuando acerco mis dedos sobre el pic que funciona como RX se apaga la función que se esta ejecutando en ese momento? Por ejemplo, si justo dejé el led encendido y acerco mi dedo este se apaga...

Además modifiqué un poco los códigos para optimizar un poco el consumo de la memoria ram del pic RX, bajando su consumo en un 10% aproximadamente...

Para aquellos que les pueda servir de ejemplo, pego mis códigos funcionales gracias a la ayuda de D@rknytes y mis compañeros manuales como mencioné jajaja ;)

TX
PHP:
#include <12F675.h>
#fuses NOMCLR
#use delay(internal = 4MHz)
#use rs232(baud=2400, xmit=PIN_A2)

void menu()
{
   char *On_Off = "on_off";
   char *Test_Con = "test_con";
   int contador = 0;  
   
   while (input(PIN_A3))
   {
      contador++;
      delay_ms(50);
   }  
    
   if (contador >= 1 && contador <= 10)
   {
      contador = 0;
      output_high(PIN_A5);
      printf("%s\r", On_Off);
      delay_ms(100);      
      output_low(PIN_A5);
   }
   
   if (contador > 10)
   {
      contador = 0;
      output_high(PIN_A5);
      printf("%s\r", Test_Con);
      delay_ms(100);      
      output_low(PIN_A5);   
   }
}

void main (void)
{
   putc(0x00);
   delay_ms(100);
   output_low(PIN_A5);
   
   while (true)
   { 
      menu();
   }
}
RX
PHP:
#include <12F675.h>
#include <stdio.h>
#include <string.h>
#fuses NOMCLR
#use delay(internal = 4MHz)
#use rs232(baud=2400, rcv=PIN_A2)

char buffer[10];
#INT_EXT
void RCV_BUFFER(void)
{
   gets(buffer);
}

void main(void)
{  
   char *fn_onoff = "on_off";
   char *fn_testc = "test_con";
   int i;
   
   output_low(PIN_A5);          

   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   ext_int_edge(H_TO_L);   
    
   while (true)
   {            
      if (strcmp(buffer, fn_onoff) == 0)
      {
         buffer = "";
         output_toggle(PIN_A5);
      }
      else if (strcmp(buffer, fn_testc) == 0)
      {
         buffer = "";
         for (i=0; i<10; i++)
         {
            output_high(PIN_A5);
            delay_ms(110);
            output_low(PIN_A5);
            delay_ms(60);          
            output_high(PIN_A5);
            delay_ms(110);
            output_low(PIN_A5);
            delay_ms(400);            
         }
      }      
   }
}
Saludos y como siempre gracias ;)
AlanB!
 
#25
¿Para limpiar mi buffer ( char buffer[10]; ) se realiza de la siguiente forma ( buffer = ""; )?
No. obtén la dimensión del buffer con strlen, ésta función te retornará la longitud ocupada del array.
Después realiza un bucle for que se repita las veces del resultado de strlen y lo limpias de esta forma:
buffer[x] = '\0';
También lo puedes hacer sin obtener la dimensión del buffer, pero así es mejor por si la cambias.
Y otra consulta más. ¿Por qué cuando acerco mis dedos sobre el pic que funciona como RX se apaga la función que se esta ejecutando en ese momento? Por ejemplo, si justo dejé el led encendido y acerco mi dedo éste se apaga?
Cuando la comunicación es de PIC a PIC eso no debería suceder, pero cuando se reciben datos de otro dispositivo, puede ser porque GP2 que es el pin de interrupción externa, esté detectando cambios de nivel.
Verifica que éste pin tenga un 1 lógico en estado de espera.
Al PIC12F675 se le pueden activar resistencias pull-up independientes a algunos pines.
Mira los registros OPTION_REG bit 7 y el registro WPU.
Por medio de la instrucción port_x_pullups(value/mask/unmask); puedes activar las que necesites. En este caso GP2.
Además modifiqué un poco los códigos para optimizar un poco el consumo de la memoria ram del pic RX, bajando su consumo en un 10% aproximadamente...

Para aquellos que les pueda servir de ejemplo, pego mis códigos funcionales gracias a la ayuda de D@rknytes y mis compañeros manuales como mencioné jajaja ;)
Que bien. (y) No he revisado los programas pero me daré un tiempo para ello.


Edit:
Ya revisé los programas y están funcionando bien.

Mira, esta es la forma que te mencioné acerca de limpiar el buffer:
Código:
[B]         x = strlen(buffer);
         
        [COLOR=Blue] for[/COLOR](i=[COLOR=SeaGreen]0[/COLOR];i<=x;i++)
         {
            buffer[i] = [COLOR=Purple]'\0[/COLOR]';
         }[/B]
Saludos.
 
Última edición:
#26
D@rkbytes como siempre gracias por tu enseñanza ;)

Estoy leyendo sobre las pullups! Y con respecto a la limpieza del buffer, esto estaría bien no?

Clear Buffer
PHP:
j = (strlen(buffer) - 1;

for (x=0; x<j; x++)
{
    buffer[x] = '\0';
}
Saludos y gracias amigo! ;)
AlanB!
 
#27
Si, pero quita el -1 para que se limpie bien el buffer o no se limpiará la última locación ocupada.

Sobre las pull-ups, no es complicado.
Aunque el 12F675 no tenga un puerto de 8 bits, debes considerarlo como si los tuviera.
Entonces si quieres activar la resistencia pull-up del bit 2, tendrías esto: "00000100" = 4 en decimal.
Por lo tanto, cargas el valor 4 en la instrucción: port_a_pullups (0x04);

PD:
Me di cuenta que el bit 0 (GP0) mantiene un estado lógico 1.
Esto lo provoca la directiva #USE RS232 (Options)
Aunque no tenga establecido el pin Tx (XMIT), toma GP0 como el pin de Tx.

Esto se puede evitar haciendo uso de #USE FAST_IO (Port)
Y estableciendo con SET_TRIS_X (Value); los pines de entrada y salida.
Por ejemplo: set_tris_a (0:LOL:F); // Únicamente GP5 como salida.

Otros detalles:
La librería stdio.c no se está usando, así que la puedes quitar.

En el inicio del programa y después del retardo de 100 ms, escribe lo siguiente:
printf("on_off\r");
Esto hará que no se tenga que presionar dos veces el pulsador cuando inicie el programa y se active el pin de control en el receptor.
 
Última edición:
#28
D@rkbyes como va!

Consulta algo que nunca entendi muy bien, set_tris_a(0xdf), es lo mismo si lo pongo en binario "set_tris_a(0b11011111);" o si lo pongo en decimal asi "set_tris_a(223);"?

Hex = 0x00
Bin = 0b00000000
Dec = 000

Lo de las pullups no me funcionó, si acerco mi dedo sigue haciendo lo mismo, se apaga la funcion que se esta ejecutando en el momento... Igual sigo haciendo las pruebas...

Saludos AlanB ;)
 
#29
Si. Para el compilador es lo mismo que escribas en binario, decimal o hexadecimal.

Se me hace extraño que te suceda eso, yo tengo montado el circuito en protoboard y eso no sucede.
Incluso puedo tocar directamente todos los pines y el PIC sigue funcionando perfectamente.
No hace ninguna cosa extraña, ni en estado de espera y tampoco cuando está encendido el LED.

La prueba la hice con el último código que pusiste, solo con el agregado para limpiar el buffer.
De hecho desde las primeras pruebas nunca se ha presentado lo que mencionas.

Lo que si te puedo decir, es que únicamente cuando GP2 se encuentra en estado flotante, sucede lo que mencionas.
Con acercare unos cuantos centímetros al PIC, éste ya detecta cambios de estado.
 
#31
¿En estado flotante? ¿Cómo sería eso?
Estado flotante es cuando un pin no tiene ninguna referencia lógica.
O sea, cuando el pin está configurado como entrada y carece de una resistencia pull-up o pull-down.
También se puede dar el caso en las salidas, cuando son con drenador o colector abierto.
¿Además de bucle para limpiar el buffer, agregaste otro código más?
Pues no, solo que te mencioné anteriormente.
Este es el código del receptor con los agregados mencionados:
PHP:
#include <12F675.h>
#include <string.h>
#fuses   NOMCLR
#use     delay(internal = 4MHz)
#use     rs232(baud=2400, rcv=PIN_A2)
#use     fast_io(a)

char buffer[10];

#INT_EXT
void RCV_BUFFER(void)
{
   gets(buffer);
}

void main(void)
{  
   char *fn_onoff = "on_off";
   char *fn_testc = "test_con";
   int i,x;
   
   set_tris_a(0xDF);
   output_low(PIN_A5);
   port_a_pullups(0x04);

   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   ext_int_edge(H_TO_L);   
    
   while (true)
   {            
      if (strcmp(buffer, fn_onoff) == 0)
      {
         x = strlen(buffer);
         
         for(i=0;i<=x;i++)
         {
            buffer[i] = '\0';
         }
         
         output_toggle(PIN_A5);
      }
      else if (strcmp(buffer, fn_testc) == 0)
      {
         x = strlen(buffer);
         
         for(i=0;i<=x;i++)
         {
            buffer[i] = '\0';
         }
         
         for (i=0; i<10; i++)
         {
            output_high(PIN_A5);
            delay_ms(110);
            output_low(PIN_A5);
            delay_ms(60);          
            output_high(PIN_A5);
            delay_ms(110);
            output_low(PIN_A5);
            delay_ms(400);            
         }
      }      
   }
}
Si continúas con el problema, adjunta el archivo ejecutable para realizar una prueba.
Eso también sirve para analizar los registros.

Una pregunta: ¿La comunicación es directa entre los PICs, o por medio de otro dispositivo?
 
Última edición:
#32
D@rkbytes antes que nada gracias por tu tiempo!

Te comento, en estos momentos tengo compilado y cargado en el pic RX el source que publiaste con las modificaciones mencionadas "clear buffer", "port_a_pullups", "set_tris_a" y sigo teniendo el bug que te mencioné... La comunicación por ahora es de pic a pic, aún espero que me lleguen los modulos RF...

¿Cuál sería el ejecutable para analizar los registros?

Saludos, AlanB! ;)
 
#33
Si. Lo supuse, porque esos agregados no solucionan el problema que tienes.

El archivo ejecutable es el archivo *.hex que grabas en el PIC.
 
#34
D@rkbytes como va!

Te dejo adjunto el HEX del RX!

Saludos, AlanB! ;)

EDITADO:

Me llegaron los modulos rf RWS-371 y TWS-433 del fabricante "Whenshing", pero al conectarlos no existe comunicación con los pics :( vi en un montón de webs que todo el mundo los usa mediante el rs232... Porque no se comunican? Estan a unos 10cm uno del otro y nada... Alguna vez utilizaste estos?
 

Adjuntos

Última edición:
#35
Me llegaron los modulos rf RWS-371 y TWS-433 del fabricante "Whenshing", pero al conectarlos no existe comunicación con los pics :( vi en un montón de webs que todo el mundo los usa mediante el rs232... Porque no se comunican? Estan a unos 10cm uno del otro y nada... Alguna vez utilizaste estos?
Fijate en las hojas de datos del receptor de qué ancho es la banda de recepción y si puede recibir
algo en la frecuencia del transmisor.
Hojas de datos: https://www.forosdeelectronica.com/f22/rws-433-tws-433-modular-voz-98273/
Segun tengo entendido el receptor tiene una banda ancha o se puede sintonizar en algún rango con
la bobina atornillable.
También podés usar el buscador por si alguien ha tenido un problema similar.
Fijate de usar la salida digital del RX, la otra tiene un comportamiento "lineal" que nunca entendí.

Saludos.
 
Última edición:
#36
Te dejo adjunto el HEX del RX!
OK. Ya revisé el archivo .hex y es correcto en cuanto a los registros. AlanB Rx Registros 12F675.jpg
No sé si cambiaste los Baudios o hay algo diferente en tu programa, porque no pude establecer comunicación.

Con el programa del post #31 si logro la comunicación. O sea, el receptor sí responde.
Puede ser que el valor de OSCCAL del PIC receptor sea algo incorrecto, así que se me ocurre que hagas una prueba con oscilador a cristal. (Misma frecuencia, 4MHz.)
Obviamente tendrás que cambiar el pin de control, pero es para salir de dudas.

Ésta es la configuración de registros que tengo en el PIC receptor con el programa del post #31: D@rkvytes Rx Registros 12F675.jpg
Si te fijas, tienen el mismo valor, pero algo diferente tiene tu programa que no me funciona. :unsure:
 
#37
D@rkbytes como va!

Los baudios estan en 2400, a lo mejor el problema es que los strings enviados los cambie a "test" y "test2" y ese debe ser el problema de que no se comunican, perdón por olvidar mencionarlo... Según leí en la web muchos ponen al pin GP3 con una resistencia pullup externa ya que este pin carece de la misma de forma interna en este pic, justo ahora estoy haciendo la prueba, ademas cambie de pic y sigo teniendo el problema nose ya a que se debe, ya que en tu prueba no sucede lo mismo, será ruido por la protoboard?

Otra cosa, mis modulos son del tipo ASK y según leí también es muy dificil que me funcione el proyecto con ellos ya que el RS323 es de tipo NRZ, asi que me encuentro buscando una forma de que se comuniquen mediante algun dato preciso y que no tomen cualquier dato para asi evitar que el proyecto se encienda con cualquier señal que recibe...

Existe alguna librería para este proposito? Vi que un usuario de otro foro lo solucionó haciendo su propio protocolo... Alguna vez trabajaste con modulos rf con modulacion ASK?

Saludos, AlanB! ;)
 
#38
Los baudios están en 2400, a lo mejor el problema es que los strings enviados los cambie a "test" y "test2" y ese debe ser el problema de que no se comunican, perdón por olvidar mencionarlo.
He ahí el detalle. :rolleyes:
Pero bueno, como quiera los valores de los registros es lo que importaba saber, y son idénticos al que tengo.
Según leí en la web muchos ponen al pin GP3 con una resistencia pull-up externa ya que este pin carece de la misma de forma interna en este PIC.
Justo ahora estoy haciendo la prueba, ademas cambié de PIC y sigo teniendo el problema.
Así es, el pin 4 o GP3 no tiene resistencia interna.
Cuando se usa normalmente como pin de reset, la resistencia obviamente debe ser pull-up.
Pero cuando se usa como pin de entrada (MCLR deshabilitado), la resistencia externa puede ser pull-up o pull-down, ya que eso depende de la programación del código.
No sé ya a qué se debe, ya que en tu prueba no sucede lo mismo. ¿Será ruido por la protoboard?
Si. si puede deberse a ruido.
Yo le conecto un capacitor de 470 uF a cada lado del mismo. (Sobre las líneas VDD y VSS)
Otra cosa. Mis módulos son del tipo ASK y según leí también es muy difícil que me funcione el proyecto con ellos ya que el RS323 es de tipo NRZ.

¿Existe alguna librería para este propósito? Vi que un usuario de otro foro lo solucionó haciendo su propio protocolo.
¿Alguna vez trabajaste con módulos R.F con modulación ASK?
No creo que tengas problemas por el tipo de modulación.
He visto ejemplos que usan ese tipo de módulos y se comunican por RS-232.

Y no. No he usado ese tipo de módulos, pero he visto por aquí en el Foro que si han tenido problemas con ellos.
Problema PICs + Módulos RF ASK
Duda sobre transmisor y receptor rf 7000 a 433MHz arlex
Modulos radiofrecuencia ASK y pic
Control remoto RF para alarma con pic ¿como?
 
Última edición:
#39
D@rkbytes!

Leyendo un poco sobre el tema... Tenés algun ejemplo sobre este pic y su timer, se me ocurrio hacer algo que entienda un pulso alto y un pulso bajo leyendo el timer, de esta forma podria enviar datos con pulsos y lograr decodificar estos basándome en sus tiempos y generando una onda cuadrada (creo que estoy en lo correcto no?), podria enviar los siguientes valores...

| DEC | HEX | BIN |
| 0 | 0 | 0000 |
| 1 | 1 | 0001 |
| 2 | 2 | 0010 |
| 3 | 3 | 0011 |
| 4 | 4 | 0100 |
| 5 | 5 | 0101 |
| 6 | 6 | 0110 |
| 7 | 7 | 0111 |
| 8 | 8 | 1000 |
| 9 | 9 | 1001 |
| 10 | A | 1010 |
| 11 | B | 1011 |
| 12 | C | 1100 |
| 13 | D | 1101 |
| 14 | E | 1110 |
| 15 | F | 1111 |

Donde 0 seria bajo y 1 alto...

Enviar un "0" podria ser por ejemplo
PHP:
void Send0()
{
  output_high(PIN_AX);
  delay_ms(1);
  output_low(PIN_AX);
  delay_ms(3);
}
Y enviar un "1" podria ser por ejemplo
PHP:
void Send1()
{
  output_high(PIN_AX);
  delay_ms(3);
  output_low(PIN_AX);
  delay_ms(1);
}
Y para enviar por ejemplo "3 (0011)" seria
PHP:
while (true)
{
  Send0();
  Send0();
  Send1();
  Send1();
}
Y con esto mis modulos se podrian comunicar... Nose realmente si se entiende lo que quiero hacer pero renegando con mi proyecto se me acaba de ocurrir y no encuentro algun ejemplo que me ayude a entender el timer... Desde ya muchas gracias por tu tiempo!

AlanB! ;)
 

Temas similares

Arriba