Comunicación por Radiofrecuencia entre PICs y nRF24L01

Buen día amigos, espero estén muy bien.

El día de hoy he decidido compartir con ustedes mi experiencia con los famosos módulos NRF24L01 de Nordic Semiconductor.
2n16ykh.jpg
Por lo visto no hay un tema conciso y concreto sobre el uso de estos módulos en el foro, así que fundado en lo aprendido en la web y mi propia experiencia, me di a la tarea de redactar un tema sobre como dominar un poco estos bichitos :)

Ante todo me considero un aprendiz mas, la idea es que con base en esta información, entre todos logremos ampliar aun mas el conocimiento sobre estos grandes módulos.

Para tomar en cuenta:

  • Los módulos NRF24L01 son transceptores ya que cada uno puede ser emisor o receptor en el momento que deseemos, esto se controla por software y resulta muy útil, ya que existe una comunicación bidireccional.

  • Estos módulos NRF24L01 SOLO trabajan entre 1.9 y 3.6v según la hoja de datos, pero ellos recomiendan un voltaje de 3.3v, así que para fines prácticos usaremos esta tensión, y para evitar errores relacionados a los niveles TTL en la comunicación con el micro, inicialmente el pic que usemos que en este caso sera un 16F876A, lo alimentaremos también a 3.3v.

  • Algo fundamental a la hora de alimentar los módulos, es que trabajemos inicialmente con baterías o una fuente de alimentación muy bien filtrada, idealmente una vieja fuente de PC ya que estos módulos son muy sensibles a nuestro gran dolor de cabeza las interferencias por parte del ruido de naturaleza analógica.

  • La comunicación de estos módulos con el pic es por medio del puerto SPI, y como recomendación personal a la hora de montar el Cto en la protoboard, peinen muy bien los puentes, ser ordenados en eso les ahorrara tiempo a la hora de hacer verificaciones y evitaran errores de conexión que pueden terminar dañando el modulo.

  • La configuración de el modulo, y su relativamente sencillo acoplamiento con el microcontrolador, se lo debemos a esta gran libreria, lib_rf2gh4_10.h propiedad de Bizintek Innova, S.L. el cual puede ser usada, modificada y distribuida bago licencia GNU, Por ultimo agradecer a Océano y a Biblioman de la web "aquí hay apuntes" ya que gracias a ellos logre avanzar con estos módulos

No siendo mas empecemos.


El cto a usar es el siguiente:

Emisor:

34j7k7s.jpg


Receptor:

30wtfs0.jpg


El código en CCS para el cto emisor es el siguiente:

Código:
#include <16F876A.h>

#fuses    NOWDT
#fuses    XT
#fuses    PUT
#fuses    NOPROTECT
#fuses    NODEBUG
#fuses    NOBROWNOUT
#fuses    NOLVP
#fuses    NOCPD
#fuses    NOWRT

#use delay(clock=4000000)

#include "lib_rf2gh4_10.h"

#byte porta=0x05
#byte portb=0x06

#int_ext                     // Esta rutina está para un futuro si haces comunicaciones bidireccionales.
void int_RB0()               // No tiene efecto en el programa principal, ya que sólo emite.
{                            // Se encargaría de la recepción de datos.
   int8 ret1;
  
   ret1 = RF_RECEIVE();
   if ( (ret1 == 0) || (ret1 == 1) )
   {
      do
      { 
         ret1 = RF_RECEIVE();
      }  while ( (ret1 == 0) || (ret1 == 1) );
   } 
}

void main()
{ 
    port_b_pullups(FALSE);         // Todo digital... etc.
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_CLOCK_DIV_2);
    setup_spi(SPI_SS_DISABLED);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_comparator(NC_NC_NC_NC);
    setup_vref(FALSE);

   int8 ret2;

   RF_INT_EN();              // Habilitar interrupción RB0/INT.
   RF_CONFIG_SPI();          // Configurar módulo SPI del PIC.
   RF_CONFIG(0x40,0x01);     // Configurar módulo RF canal y dirección de recepción. Para recibir datos tiene la dirección 0x01.
   RF_ON();                  // Activar el módulo RF.
  
   delay_ms(5);              // Le damos un mínimo de 2.5 milisegundos para que se ponga en marcha.
  
   set_tris_a(0b111111);     // Todo el puerto A como entradas.
 
     
   while(true)               // Bucle infinito.
   {
  
      RF_DATA[0]= porta;     // Cargamos el dato en RF_DATA[0].
      RF_DIR=0x08;           // Dirección del receptor.
      ret2=RF_SEND();        // Enviar datos.
  

  
   if(ret2==0){
      //Envio realizado y ACK recibido
      }

   else if(ret2==1){
      //Envio realizado y ACK no recibido
      }

   else{
      //Envio no realizado
      }
   }
}


Y el código para el receptor es:

Código:
#include <16F876A.h>

#FUSES     NOWDT
#FUSES     XT
#FUSES     PUT
#FUSES     NOPROTECT
#FUSES     NODEBUG
#FUSES     NOBROWNOUT
#FUSES     NOLVP
#FUSES     NOCPD
#FUSES     NOWRT
#use delay(clock=4000000)

#include "lib_rf2gh4_10.h"

#byte porta=0x05           // Dirección del puerto A.

#int_ext                   // Interrupción del módulo RF.

void int_RB0()
{
   int8 ret1;

   ret1 = RF_RECEIVE();
   if ( (ret1 == 0) || (ret1 == 1) ) // Tanto si hay recepción simple o múltiple, leer datos.
   {
      do
      {   
         porta=RF_DATA[0];           // El puerto A contendrá el valor que le llegue del emisor, a través de RF_DATA[0].
         ret1 = RF_RECEIVE();        // "ret1" nos dirá si hay recepción simple, múltiple o no hay datos para leer.
      } while ( (ret1 == 0) || (ret1 == 1) ); // Mientras haya datos para leer, seguir leyendo.
   } 
}

void main()                  // Programa principal.
{
   port_b_pullups(FALSE);         // Todo digital... etc.
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
  
   set_tris_a(0b000000);     // Todo el puerto A como salida.
   porta=0;                  // Inicialmente lo ponemos a cero.
  
   RF_INT_EN();              // Habilitar interrupción RB0/INT.
   RF_CONFIG_SPI();          // Configurar módulos SPI del PIC.
   RF_CONFIG(0x40,0x08);     // Configurar módulo RF (canal y dirección).
   RF_ON();                  // Activar el módulo RF.
  
   while(true);              // Bucle infinito.            
      
}

Expliquemos brevemente algunas sentencias del los programas así entender un poco el código.

Para el emisor:

  • En este segmento:
    Código:
    RF_INT_EN();              // Habilitar interrupción RB0/INT.
    RF_CONFIG_SPI();          // Configurar módulo SPI del PIC.
    Como su descripción lo indica son funciones incluidas en la libreria lib_rf2gh4_10.h que de modo simple, permiten la activación del la interrupción por cambio de estado en RB0 en el micro, y la configuración correcta del puerto SPI en este

  • En este otro segmento:
    Código:
    RF_CONFIG(0x40,0x01);     // Configurar módulo RF canal y dirección de recepción. Para recibir datos tiene la dirección 0x01.
    RF_ON();                  // Activar el módulo RF.
    Se configura el modulo, la función RF_CONFIG permite seleccionar el CANAL de comunicación y la dirección de recepción, con esto quiero decir que para que exista una comunicación entre dos o mas módulos, todos deben de estar exactamente en el mismo canal de transmision, pero la dirección es útil en el momento del recibir un dato, y este se debe ser especificado por el modulo emisor en el momento del envió, por ejemplo:

    Modulo 1:

    canal de transmision = 10
    dirección de recepción = 1
    enviar dato [$#] a "2"


    Modulo 2

    canal de transmision = 10
    dirección de recepción = 2
    Dato [$#] recibido
    Enviar confirmación de recepción a "1"


    Modulo1

    canal de transmision = 10
    dirección de recepción = 1
    Dato [Confirmación] recibido

  • Para este segmento:
    Código:
    RF_DATA[0]= porta;     // Cargamos el dato en RF_DATA[0].
    RF_DIR=0x08;           // Dirección del receptor.
    ret2=RF_SEND();        // Enviar datos.
    La función RF_DATA es un array de 8 bytes y podemos notar que solo se usara un byte para guardar el estado del puerto A del micro.
    RF_DIR es la función que asina la dirección de recepción en el momento del envió que mencionábamos anteriormente, es la dirección a donde se enviara el dato del array.
    por ultimo la función RF_SEND() esta es la que fuerza el envió del dato, y tiene capacidad de acuse de recibo o ACK, asi que la variable ret2 se carga con 3 valores posibles:

    0 si el envió fue correcto y se ha recibido el ACK
    1 si el envió fue correcto pero no se recibió el ACK
    2 si se produjo algún error u el envió no fue posible


    Para el receptor:

  • En el receptor no cambia mucho el programa, vasta con decir que la función principal es un bucle infinito el cual se ve interrumpido por la recepción de un dato, en cuyo caso entra la función de interrupción por cambio de estado en RB0, y su función mas importante destacaríamos RF_RESEIVE el cual se encarga de guardar los datos entrantes en el array RF_DATA[0], posteriormente tratamos los datos recibidos, y el valor es asignado al puerto A del micro


Algunas especificaciones a resaltar del modulo son que usa modulación GFSK a 2.4 Ghz, una velocidad de datos configurable entre 1mbps y 2 mbps para el modelo "NRF24L01".

Existe una tercera velocidad de 250kbps para el modelo "NRF24L01+" y el consenso no es unánime a la hora de dar un alcance máximo de transmision, algo muy importante a tener en cuenta cuando construimos un proyecto de RF, según el dataaheet el alcance es de 100mts, sin embargo según las experiencias de muchas personas, esa distancia esta lejos del valor real, así que les diré el alcance logrado dependiendo de su configuración, y basado en mis experiencias

Bueno el alcance depende fundamentalmente de tres cosas:


  • La libertad de la señal entre los módulos, con eso me refiero a si esta en linea de visión, o con muchos obstáculos como paredes que la señal tiene que atravesar.

  • La potencia de salida de la señar preconfigurada en el modulo.

  • La velocidad de datos:

    Experimentalmente logre a 2Mbps un alcance de unos 11 metros en linea de visión, pero si se enfrentaba a 2 paredes no pasaba de 6 metros :(

    A 1Mbps el asunto mejoro, ahora alcanzaba unos 40 metros en linea de visión, y la señal expuesta a 5 paredes sobrevivía hasta unos 18 metros.

    finalmente a una velocidad de datos de 250Kbps, el modulo a linea de visión logro unos cómodos 150 metros de alcance, algo mas que inesperado considerando el costo de estos módulos, en cuanto a los obstáculos, logro transmitir de un lado de la casa al otro, el cual son 7 paredes y logro una distancia de 25 mts antes de perder la señal


Ahora les explicare como modificar la libreria para cambiar la velocidad de transmision de datos:

  • primero que todo deben pegar la libreria lib_rf2gh4_10.h que dejo adjunta, en la carpeta en donde guardaran su proyecto en CCS.
    Ya estando en el programa CCS y ya habiendo escrito el código correspondiente a cualquiera de los módulos damos click derecho sobre la sentencia "#include "lib_rf2gh4_10.h"" y le damos "Open file at cursor", de inmediato nos saldrá una pestaña en donde esta todo el código correspondiente a la libreria, buscamos el registro RF_SETUP que esta en fila 231 y aparece lo siguiente:

    Código:
    //RF_SETUP
    //Configuración aspectos RF.
    //Ganancia máxima de LNA, 0dBm potencia de salida y 2Mbps de velocidad.
    output_low(RF_CS);
    spi_write(0x26);
    spi_write(0x27);
    output_high(RF_CS);
    La linea que nos interesa es la que dice "spi_write(0x27);" pues este numero hexadecimal es el que permite configurar los aspectos de RF del modulo: tomemos un momento para explicar el como y porque, para eso nos vamos al registro RF_SETUP del datasheet del modulo:

    1199c9d.jpg


    Como podemos ver es un registro que se configura con un numero binario de 8 bits, en donde los bits 5, 3 , 2, 1, y 0 son los que nos interesan.

    si el bit 5 esta a "0" queda desactivado el modo de transmisión con velocidad de datos a 250kbps

    si el bit 3 esta a "0" configuramos el modulo a 1Mbps
    si el bit 3 esta a "1" configuramos el modulo a 2Mbps

    Para dejar el modulo con una velocidad de datos de 250kbps, ha que poner el bit 5 a "1" y el bit 3 a "0"

    Los bits 2 y 1 configura la potencia del modulo

    si los bits 2 y 1 están a "00" configuramos el modulo a -18dDm
    si los bits 2 y 1 están a "01" configuramos el modulo a -12dDm
    si los bits 2 y 1 están a "10" configuramos el modulo a -6dDm
    si los bits 2 y 1 están a "11" configuramos el modulo a 0dDm

    Esta ultima es la de mayor potencia de salida.

    Aunque el bit 0 de este registro en este modulo se desprecie, debemos tenerlo en cuenta ya que existe una version mas potente de este, mas precisamente es el modulo "nrf24l01+pa+lna" el cual cuenta con un amplificador de salida para la antena, y un pre-amplificador para la entrada de la señal.

    La disposición de pines de este modulo exactamente igual al del NRF menos potente, por lo cual también puede ser usado por esta libreria sin ningún problema.

    En fin Como decía, el bit 0 debemos tenerlo en cuenta ya que si decidimos usar el modulo "nrf24l01+pa+lna"

    si el bit 0 esta a "0" apagamos el pre-amplificador de la antena
    si el bit 0 esta a "1" encendemos el pre-amplificador de la antena


    Finalmente teniendo en cuenta la tabla, los valores validos para los 3 modos de transmision del modulo son:
    1. Para 2Mbps y maxima potencia el byte sera 00001111 entonces la linea de la libreria sera "spi_write(0x0f);"
    2. Para 1Mbps y maxima potencia el byte sera 00000111 entonces la linea de la libreria sera "spi_write(0x07);"
    3. Para 250Kbps y maxima potencia el byte sera 00100111 entonces la linea de la libreria sera "spi_write(0x27);"



Para Finalizar adjunto los archivos correspondientes a este miniproyecto espero les sean de utilidad, cualquier duda, por este hilo :)
 

Adjuntos

  • Proyecto.rar
    1.2 MB · Visitas: 588
Gracias por al aporte. Es muy bueno.

Sólo diría que yo cambiaría las líneas
PHP:
   while(true);              // Bucle infinito.
por
PHP:
   while(true) {             // A dormir
        sleep();
        delay_cycles(2);     // (por seguridad, algo opcional) Esperamos un poco
    }
Para probar a ver si el consumo del PIC baja al mínimo (con el ahorro consiguiente).
 
Última edición por un moderador:
Gracias joaquin efectivamente se puede hacer, el código es lo mas simplificado posible para evitar errores, ya que estos módulos a veces resultan bastante caprichosos.
 
gracias luvhines por el aporte, y que casualidad, yo también empezaba a estudiar estos módulos y no encontré mucho en el foro.

quería preguntar si alguien puede aclararme cuál es la diferencia entre estos módulos y los módulos nrf24l01+ , es que voy a hacer el pedido y no quiero quedarme con un dispositivo que no pueda usar, me sale muy caro hacer traer algo por internet.

me olvidaba: qué programa puedo usar para simular el uso de los módulos? es que en el proteus creo que no tienen el modelo del nrf24l01. gracias de antemano.
 
Última edición:
Hola luvhines mi pregunta es como puedo hacer ese mismo proyecto pero usando el 18f4550 como podras comprobar mi nivel es bastante bajo y como no tengo el 16f876 y si varios 18f4550 es por lo que necesito este cambio gracias y espero tu respuesta, un saludo.
 
pense que esos modulos solo tenian un alcance de 20 metros como mucho, sin la posibilidad de atravezar pared, como los modulos rf 433hz, pero ahora con la informacion planteada sera motivo para probarlos, mas aun con esa cantidad de datos de transmision, le gana por mucho a los 433mhz.
 
Hola luvhines mi pregunta es como puedo hacer ese mismo proyecto pero usando el 18f4550 como podras comprobar mi nivel es bastante bajo y como no tengo el 16f876 y si varios 18f4550 es por lo que necesito este cambio gracias y espero tu respuesta, un saludo.
Hola compa me encuentro bastante ocupado en la u pero cuando pase tanta cosa, pienso hacer un tuto para los pics de la familia 18F y tips para que adapten la librería a cualquier pic que soporte comunicación SPI, solo es cuestión de retocar algunos datos de la librería lib_rf2gh4_10.h. Saludos
 
Última edición:
gracias luvhines por el aporte, y que casualidad, yo también empezaba a estudiar estos módulos y no encontré mucho en el foro.

quería preguntar si alguien puede aclararme cuál es la diferencia entre estos módulos y los módulos nrf24l01+ , es que voy a hacer el pedido y no quiero quedarme con un dispositivo que no pueda usar, me sale muy caro hacer traer algo por internet.

me olvidaba: qué programa puedo usar para simular el uso de los módulos? es que en el proteus creo que no tienen el modelo del nrf24l01. gracias de antemano.

yo tambien quisiera saber como hiciste para simularlo.
Gran aporte a la comunidad, muchos te lo agradecemos!
 
gracias luvhines por el aporte, y que casualidad, yo también empezaba a estudiar estos módulos y no encontré mucho en el foro.

quería preguntar si alguien puede aclararme cuál es la diferencia entre estos módulos y los módulos nrf24l01+ , es que voy a hacer el pedido y no quiero quedarme con un dispositivo que no pueda usar, me sale muy caro hacer traer algo por internet.

me olvidaba: qué programa puedo usar para simular el uso de los módulos? es que en el proteus creo que no tienen el modelo del nrf24l01. gracias de antemano.

Hola compa este tuto es sobre los módulos NRF24l01+ creo que hay que corregir eso para evitar confusiones, y físicamente no tienen ninguna diferencia, pero si difieren en su funcionamiento, por ejemplo los módulos que usan el chip nrf24l01 no pueden configurarse a 250kbps, pero estos si, aca puedes verlo:

Datasheet nrf24L01: ve a la pagina 23 en la dirección "06" y veras el registro RF_SETUP y podras notar que solo hay 2 posibles configuraciones para 1Mbps y para 2Mbps.
https://www.sparkfun.com/datasheets/Components/nRF24L01_prelim_prod_spec_1_2.pdf

Datasheet nrf24L01+: ve a la pagina 55 en el mismo registro RF_SETUP podrás notar que posee las 3 posibles configuraciones para, 1Mbps, 2Mbps y 250Kbps
https://www.sparkfun.com/datasheets/Components/SMD/nRF24L01Pluss_Preliminary_Product_Specification_v1_0.pdf

te recomiendo que busques específicamente los NRF24L01+ y los compres por ebay, yo compre 10 unidades y en total me costo 9 dolares, no salen tan costosos.

Por ultimo amigo no existe ningún programa que pueda simular estos módulos, lo mejor que puedes hacer es traer mas de 2 por si te equivocas y te tires el modulo, después de eso probar con lo que esta en este tuto y te garantizo que si lo haces tal cual te van a funcionar =D
De los diez que yo pedi dañe 2 por conectarlos al revés D: pero valieron la pena, ahora tengo 8 que me funcionan al pelo ;D



yo tambien quisiera saber como hiciste para simularlo.
Gran aporte a la comunidad, muchos te lo agradecemos!
jajajaja no amigo no lo simule, yo solo cree el nuevo componente en proteus para poder hacer las conexiones y crear fácilmente un PCB, pero no es simulable.
 
Última edición:
Hola compa me encuentro bastante ocupado en la u pero cuando pase tanta cosa, pienso hacer un tuto para los pics de la familia 18F y tips para que adapten la librería a cualquier pic que soporte comunicación SPI, solo es cuestión de retocar algunos datos de la librería lib_rf2gh4_10.h. Saludos

Te cuento que hice funcionar los transceptores con dos PIC18F4550, es cuestión de cambiar algunas definiciones en la librería y algunas consideraciones en los pines de acuerdo a la familia de microcontroladores. por cierto, tengo los nrf24l01+ y no he tenido problemas por el "signo más", es cuestión de velocidad de transmisión, pero funcionan con la misma librería, no afecta en nada y no hay que modificar nada para eso.
 
Hola buenas tardes a todos.

Yo estoy usando estos módulos para un proyecto para hacerme la casa domotica.
ya e echo pruebas con tres modulo a la vez.

Pero tengo la duda, que no acabo de entender cuantos canales y módulos se pueden usar a la vez.

Por lo que e entendido en la hoja de características(no se me da muy bien el ingles).
-que tiene una banda de frecuencia 125Mhs,
-1Mhz por canal a una velocidad de transmisión de 1Mbps.(125/1=125 canales)
-2Mhz por canal a una velocidad de transmisión de 2Mbps.(125/2=62.5 canales)

y me a parecido entender que se puede conectar 6 direcciones por canal.

haber si me podéis aclarar el tema. Si estoy en lo correcto o no.
Ya que en mi proyecto habrán bastantes módulos. y tengo que tener este tema claro.

muchas gracias a todos
 
Hola buenas tardes a todos.

Yo estoy usando estos módulos para un proyecto para hacerme la casa domotica.
ya e echo pruebas con tres modulo a la vez.

Pero tengo la duda, que no acabo de entender cuantos canales y módulos se pueden usar a la vez.

Por lo que e entendido en la hoja de características(no se me da muy bien el ingles).
-que tiene una banda de frecuencia 125Mhs,
-1Mhz por canal a una velocidad de transmisión de 1Mbps.(125/1=125 canales)
-2Mhz por canal a una velocidad de transmisión de 2Mbps.(125/2=62.5 canales)

y me a parecido entender que se puede conectar 6 direcciones por canal.

haber si me podéis aclarar el tema. Si estoy en lo correcto o no.
Ya que en mi proyecto habrán bastantes módulos. y tengo que tener este tema claro.

muchas gracias a todos



hola zeusjorg, mira los módulos funcionan en la banda de 2.4 a 2.525 Ghz dejando 125Mhz para los canales de comunicación, en teoría pueden ser 125 canales para 1Mbps y 62 canales para 2Mbps pero en la practica se recomienda dejar 2 canales de "distancia" entre canales de comunicación para evitar las interferencias, por lo que en realidad quedan 31 canales disponibles para su uso.

Para que dos módulos se comuniquen, el canal debe ser el mismo, pero cada modulo debe tener su respectiva dirección ‘broadcast". Esta dirección debe ser única para cada dispositivo en un mismo canal, y debe tener un valor entre 0.01 y 0.FE es decir 254 direcciones. Así, resumiendo, en el canal 1 tienes 254 direcciones en el canal 4 "recuerda que se espacian por 2 canales" otras 254 direcciones etc etc.. con esto te quiero decir 254 dispositivos y no 6, se pueden comunicar en un mismo canal.
 
Acabo de adquirir un par de estos modulos y me costaron 12k pesos (COL), algo asi como 5,5 dolales c/u....

Es factible/viable/posible redefinir/cambiar/pasar los pines que se usan del "Puerto C" al "Puerto B" teniedo en cuenta que la libreria usa la configuracion SPI por Hardware?

Haciendo solo lo siguente...

Cambiar esto:
Código:
// PORTB
#define   RF_IRQ   PIN_B0
#define   RF_CS    PIN_C1

// PORTC
#define   RF_CE    PIN_C2
#define   SCK      PIN_C3
#define   SDI      PIN_C4
#define   SDO      PIN_C5

// PORTB
#define   RF_IRQ_TRIS   TRISB,0
#define   RF_CS_TRIS    TRISB,7   // ***

// PORTC
#define   RF_CE_TRIS    TRISC,2
#define   SCK_TRIS      TRISC,3
#define   SDI_TRIS      TRISC,4
#define   SDO_TRIS      TRISC,5
Por esto:
Código:
// PORTB
#define   RF_IRQ   PIN_B0
#define   RF_CS    PIN_[B]B[/B]1
#define   RF_CE    PIN_[B]B[/B]2
#define   SCK      PIN_[B]B[/B]3
#define   SDI      PIN_[B]B[/B]4
#define   SDO      PIN_[B]B[/B]5

// PORTB
#define   RF_IRQ_TRIS   TRISB,0
#define   RF_CS_TRIS    TRISB,7   // ***
#define   RF_CE_TRIS    TRIS[B]B[/B],2
#define   SCK_TRIS      TRIS[B]B[/B],3
#define   SDI_TRIS      TRIS[B]B[/B],4
#define   SDO_TRIS      TRIS[B]B[/B],5
***Porque se nombra el bit 7 del Puerto B?

Para poder usar solo un puerto "completo" del uC y no dejar dos puertos "a medio usar".

¿Seria correcto hacer esto?
¿Habria que cambiar algo mas?
 
Acabo de adquirir un par de estos modulos y me costaron 12k pesos (COL), algo asi como 5,5 dolales c/u....

Es factible/viable/posible redefinir/cambiar/pasar los pines que se usan del "Puerto C" al "Puerto B" teniedo en cuenta que la libreria usa la configuracion SPI por Hardware?

Haciendo solo lo siguente...

Cambiar esto:
Código:
// PORTB
#define   RF_IRQ   PIN_B0
#define   RF_CS    PIN_C1

// PORTC
#define   RF_CE    PIN_C2
#define   SCK      PIN_C3
#define   SDI      PIN_C4
#define   SDO      PIN_C5

// PORTB
#define   RF_IRQ_TRIS   TRISB,0
#define   RF_CS_TRIS    TRISB,7   // ***

// PORTC
#define   RF_CE_TRIS    TRISC,2
#define   SCK_TRIS      TRISC,3
#define   SDI_TRIS      TRISC,4
#define   SDO_TRIS      TRISC,5
Por esto:
Código:
// PORTB
#define   RF_IRQ   PIN_B0
#define   RF_CS    PIN_[B]B[/B]1
#define   RF_CE    PIN_[B]B[/B]2
#define   SCK      PIN_[B]B[/B]3
#define   SDI      PIN_[B]B[/B]4
#define   SDO      PIN_[B]B[/B]5

// PORTB
#define   RF_IRQ_TRIS   TRISB,0
#define   RF_CS_TRIS    TRISB,7   // ***
#define   RF_CE_TRIS    TRIS[B]B[/B],2
#define   SCK_TRIS      TRIS[B]B[/B],3
#define   SDI_TRIS      TRIS[B]B[/B],4
#define   SDO_TRIS      TRIS[B]B[/B],5
***Porque se nombra el bit 7 del Puerto B?

Para poder usar solo un puerto "completo" del uC y no dejar dos puertos "a medio usar".

¿Seria correcto hacer esto?
¿Habria que cambiar algo mas?


Hola compa te respondo:

Es factible/viable/posible redefinir/cambiar/pasar los pines que se usan del "Puerto C" al "Puerto B" teniedo en cuenta que la libreria usa la configuracion SPI por Hardware?

No entiendo muy bien lo que quieres decir, si bien la comunicación es por hardware se tiene que configurar desde la libreria, ten en cuenta que cada pic tiene destinado ciertos pines para la comunicación SPI, (SCK, SDI, SDO) esos pines son el 14 , 15 y 16 o RC3, RC4 y RC5 para este pic en particular, así que son intocables, no puedes simplemente cambiarlos a RB3, RB4 y RB5 puesto que esos pines no soportan la comunicación SPI ¿ya ves?

mira, para este pic estos son los pines que no debes cambiar:

El pin 21 o el famoso pin por interrupción externa RB0, y a menos que tengas otro pin para las interrupciones no debe ser cambiado.
Código:
#define   RF_IRQ   PIN_B0

#define   RF_IRQ_TRIS   TRISB,0

Los siguientes 3 pines, el 14, 15, 16 o RC3, RC4 y RC5 son, como te mencione anteriormente, los que tiene este pic para la comunicación SPI y como no existen en el otros pines para tal tarea, tampoco podemos cambiarlos.
Código:
#define   SCK      PIN_C3
#define   SDI      PIN_C4
#define   SDO      PIN_C5

#define   SCK_TRIS      TRISC,3
#define   SDI_TRIS      TRISC,4
#define   SDO_TRIS      TRISC,5


Pero estos 2 si los puedes cambiar solo son de activación/desactivación, pero ojo, estas cambiando dos pines del micro, si los cambias no olvides cambiar también conexión en el circuito.
Código:
#define   RF_CS    PIN_C1
#define   RF_CE    PIN_C2

#define   RF_CS_TRIS    TRISC,1  
#define   RF_CE_TRIS    TRISC,2


Espero haber aclarado tu duda, ahora:
***Porque se nombra el bit 7 del Puerto B?
gracias por notarlo, la verdad es que retocando la libreria debí pasarlo por alto, y aunque me funciono sin problema, no es así como debe quedar, lo correcto seria:

Código:
#define   RF_CS    PIN_C1
#define   RF_CS_TRIS    TRISC,1
si es que vas a usar el RC1, y si vas a usar el RC0, RC6 ó RC7 O del RB1 al RB7 ya que te mencione anteriormente que este si lo puedes cambiar, podría quedar así:

Código:
#define   RF_CS    PIN_B7
#define   RF_CS_TRIS    TRISB,7

ó

Código:
#define   RF_CS    PIN_C0
#define   RF_CS_TRIS    TRISC,0

y asi mismo con RF_CE, yo creo que ya me entiendes :D
 
No se muccho de SPI....
Pero lo que si sé es que si configuras por Softward puedes asignar CSL/SDI/SDO a los pines que quieras...

En estos momentos estoy haciendo los cambios en un programita de prueba donde pongo el SPI en el puerto y finciona (ISIS) en unos minutos lo subo...

Mira, esto solo hace que se muetre el valor de "tabla" del Master en el PuertoC del Slave...
El SPI estan en el PuertoB de ambos micros y funciona como veras en la imagen que adjunto...

Para usar SPI con Software (sw) se usa "#USE SPI (ta,ta,...,ta)"
Para usar SPI con Hardware (hw) se usa "setup_spi (ta,ta,...,ta)"

Master [16F886]:
Código:
#include <Comunicacion SPI [16F886] [Master].h>
 
#byte    porta= 0x005
#byte    portb= 0x006
#byte    portc= 0x007
 
//#USE SPI (MASTER, CLK=PIN_C3, DI=PIN_C5, DO=PIN_C4, BAUD=2000, MODE=0, BITS=8, STREAM=SPI_1, force_sw)
#USE SPI (MASTER, CLK=PIN_B1, DI=PIN_B3, DO=PIN_B2, BAUD=2000, MODE=0, BITS=8, STREAM=SPI_1, force_sw)
 
int8 tabla [16]= {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int8 i;
 
void main()
{
 set_tris_b (0b00001000);
 set_tris_c (0b00100000);
 portb= 0x00;
 portc= 0x00;
 
   while(TRUE)
   {
      //TODO: User Code
      for (i=0;i<16;i++)
      {
         spi_xfer (spi_1, tabla[i]);
         delay_ms (500);
      }
   }
}
Slave [16F887]:
Código:
#include <Comunicacion SPI [16F887] [Slave].h>
 
#byte    porta= 0x005
#byte    portb= 0x006
#byte    portc= 0x007
 
//#USE SPI (SLAVE, CLK=PIN_C3, DI=PIN_C5, DO=PIN_C4, BITS=16, STREAM=SPI_1, force_sw)
#USE SPI (SLAVE, CLK=PIN_B1, DI=PIN_B3, DO=PIN_B2, BITS=8, STREAM=SPI_1, force_sw)
 
void main()
{
 set_tris_b (0b00001010);
 set_tris_c (0b00000000);
 portb= 0x00;
 portc= 0x00;
 
   while(TRUE)
   {
      //TODO: User Code
      portc= spi_xfer(spi_1);
   }
}
A esto es a lo que me refieria, pero sinceramente, no se como aplicar (en caso de que se pueda) esa configuracion por software a la libreria y tampoco estou seguro que se pueda hacer el cambio que dije antes....
 

Adjuntos

  • SPI PuertoB SW.jpg
    SPI PuertoB SW.jpg
    120.1 KB · Visitas: 110
Última edición por un moderador:
No se muccho de SPI....
Pero lo que si sé es que si configuras por Softward puedes asignar CSL/SDI/SDO a los pines que quieras...

En estos momentos estoy haciendo los cambios en un programita de prueba donde pongo el SPI en el puerto y finciona (ISIS) en unos minutos lo subo...

Mira, esto solo hace que se muetre el valor de "tabla" del Master en el PuertoC del Slave...
El SPI estan en el PuertoB de ambos micros y funciona como veras en la imagen que adjunto...

Para usar SPI con Software (sw) se usa "#USE SPI (ta,ta,...,ta)"
Para usar SPI con Hardware (hw) se usa "setup_spi (ta,ta,...,ta)"

A esto es a lo que me refieria, pero sinceramente, no se como aplicar (en caso de que se pueda) esa configuracion por software a la libreria y tampoco estou seguro que se pueda hacer el cambio que dije antes....

La verdad, poco sé sobre la emulación del puerto SPI, pero por lo que sé, no deja de ser una emulación de dicho protocolo, así que no cuentas con la misma velocidad.
Además para que dicho protocolo funcione bien en ese modo, tanto el master como el esclavo deben usar la misma librería, por eso es posible entre dos PICs, ya que ambos los puedes programar del mismo modo.

Ahora, el PIC en este caso es el master y el módulo NRF el slave, así que no creo que pueda ser posible una comunicación emulada de un solo lado, pues el tema de la sincronización es fundamental para la comunicación SPI.
Sin embargo, es algo que supongo. Habría que hacer pruebas para ver como se comporta.
 
Última edición por un moderador:
Te entiendo, y hasta donde tengo entendido, la configuración por hardware permite una mayor velocidad de transferencia que por software.

En cuanto pueda (quién sabe) me dispondré a hacer las pruebas pertinentes y si es posible, una librería de uso por software para "aprovechar mejor" los recursos y pines del microcontrolador.
 
Última edición por un moderador:
Buen día amigos, espero estén muy bien.

El día de hoy he decidido compartir con ustedes mi experiencia con los famosos módulos NRF24L01 de Nordic Semiconductor...


Me falto la lista de materiales.

2 módulos Nrf24L01
2 Pic´s 16f876a
2 cristales 4mhz
4 condensadores cerámicos de 22pf
1 Dipswich de 8 pines o bien 6 pulsadores
8 resistencias de 1 kΩ
6 resistencias de 220 kΩ
6 leds

2 conectores ribbon de este tipo:
bus.jpg

Este ultimo lo podrían cortar para insertar los módulos NRF24L01 soldar cables he insertarlos fácilmente en el protoboard, ya que la separación entre los pines del modulo no permite insertarlos en la proto, y tampoco recomiendo para nada soldar cables directamente a los pines del modulo ya que lo podrían dañar.

Por ultimo, en el esquemático que postee yo creé el componente del nrf24L01 en proteus solo para poder ilustrar la conexión, pero no tuve en cuenta los números de los pines, así en esa imagen solo tengan en cuenta el nombre de los pines según la siguiente imagen lo pueden conectar tal cual al pic.
24L01Pinout.jpg
 
if(ret2==0){
//Envio realizado y ACK recibido
}

else if(ret2==1){
//Envio realizado y ACK no recibido
}

else{
//Envio no realizado
}

buen dia amigos del foro es que tengo duda de como utilizar el modo de confirmacion de estos modulos. mi pregunta es como se hace para que el receptor conteste automaticamente que recibio el dato y sino el transmisor vuelva a enviar el dato. agradeceria su ayuda
 
Hola tengo un inconveniente, compre estos modulos y la verdad no puedo hacerlos funcionar trate de utilizar el ejemplo por donde comenzaron este foro y no logro nada, estoy utilizando un pic16f887 y un pic16f818, que son los que tengo para hacerlos funcionar como ejemplo, lo que quiero es precionar un botoen en el 887 que seria el TX, y el 818 que es el RX enciende un led, no logro hacerlo. Me pueden explicar por favor ese simple ejemplo que quiero a ver si puedo hacerlo funcionar, estoy utilizando un protoboard no simulo.
Subi los dos archivos zip del TX y RX modificando la libreria del 818 porque SDI, SCK y demas son otros pines, pero no entiendo la verdad? precionar un boton y el receptor encender un led Una verguenza preguntar esto pero no me sale. Por favor si hay alguien que con un simple ejemplo asi lo cargo y lo puedo probar muchas Gracias.

Otra cosa capaz este bien y lo que este mal son los modulos pero nose como chequearlos! Pero me inclino mas que es problema en la programacion.

Tengo dos pic16f819 por si quieren utilizar estos para explicarme tambien

es uno de los progrogramas porque lo voy variando a cada rato. la verdad no entiendo alguien tiene un programa o me ayuda hacerlo? de ultima que prenda un led de un lado y lo repita en el otro pero algo.

lo peor que me puede pasar que no me funcione los modulos pero nose? hay alguna manera de testearlo?

lo que si antes aclaro logre comunicar los dos pic mediante spi osea uno enciende el led (maestro) y el esclavo hace lo mismo. fue todo un logro jeje
 

Adjuntos

  • trx con modulo rf.zip
    101.7 KB · Visitas: 127
Última edición:
Atrás
Arriba