PIC18FxxKxx & XC8: Probando los módulos nRF24L01+


Hace ya tiempo que tenia ganas de testear estos módulos, no había tenido la oportunidad hasta un par de días. debo mencionar que no soy el autor de la librería y tampoco del demo que les muestro aquí, lo único que realice fue las adecuaciones para trabajar con el PIC18F25K22 y PIC18F46K22, como transmisor y receptor respectivamente, puedes revisar el código original aquí (actualmente ya no esta disponible el repositorio original).
Circuitos:
En la fuente original no se muestra esquemático alguno, pero checando el código, un poco de teoría y las hojas de datos se puede montar el circuito sin ningún problema, otra modificación realizada es el oscilador, la versión original usa un cristal externo de 16MHz, yo he usado el oscilador interno a la misma frecuencia.

A continuación muestro el esquemático que use para el transmisor, dedo comentar que modifique el pin del LED debido a que use el PIC18F25K22 y este no cuenta con un PORTD (en donde estaba originalmente), en cuanto a la alimentación de ambos circuitos es a 3.3 volts.

Como ya mencione he usado el PIC18F46K22 para el receptor, y el circuito usado es el siguiente:


Como el circuito lo monte sobre la protoboard y es notable que los nRF no los podía colocar directamente, realice unas pequeñas adecuaciones con tiras de pines y headers dobles, a continuación las fotos.

   


Listo los módulos se pueden colocar sin conflicto alguno.


Para el transmisor quedo de la siguiente forma:

El archivo main.c para el transmisor es el siguiente:
/*
* 2013 Elia Ritterbusch
* http://eliaselectronics.com
*
* This work is licensed under the Creative Commons Attribution 3.0 Unported License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/
*/
/*******************************************************************************
*
* XC8_006: Probando modulos nRF24L01+
*
*******************************************************************************
* FileName: main.c
* Processor: PIC18F25K22
* Complier: XC8 v1.30
* Author: Pedro Sánchez (MrChunckuee)
* Blog: http://mrchunckuee.blogspot.com/
* Email: mrchunckuee.psr@gmail.com
* Description: Probando libreria para los modulos nRF24L01+
*******************************************************************************
* Rev. Date Comment
* v1.01 06/04/2017 Modificacion para usar el PIC18F25K22
******************************************************************************/
#define _XTAL_FREQ 16000000UL
#include <xc.h>
#include <stdlib.h>
#include "spi.h"
#include "nRF24L01.h"
#include "wl_module.h"
// PIC18F25K22 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1H
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config PRICLKEN = OFF // Primary clock enable bit (Primary clock can be disabled by software)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRTEN = ON // Power-up Timer Enable bit (Power up timer enabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 190 // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC1 // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON // PORTB A/D Enable bit (PORTB<5:0> pins are configured as analog input channels on Reset)
#pragma config CCP3MX = PORTB5 // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5)
#pragma config HFOFST = ON // HFINTOSC Fast Start-up (HFINTOSC output and ready status are not delayed by the oscillator stable status)
#pragma config T3CMX = PORTC0 // Timer3 Clock input mux bit (T3CKI is on RC0)
#pragma config P2BMX = PORTB5 // ECCP2 B output mux bit (P2B is on RB5)
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled if MCLRE is also 1)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#define MAX_STRLEN 14
char received_string[MAX_STRLEN+1];
void _delay_10ms(int length){
while(length){
__delay_ms(10);
length--;
}
}
int main(void){
unsigned char payload[wl_module_PAYLOAD]; //Array for Payload
unsigned char maincounter =0;
unsigned char k;
OSCCONbits.IRCF = 0b111; //Internal Fosc = 16MHz
// status pin to indicate when master
// sends a message only for debugging
TRISCbits.TRISC7 = 0;
LATCbits.LATC7 = 1;
wl_module_init(); //initialise nRF24L01+ Module
_delay_10ms(5); //wait for nRF24L01+ Module
INTCONbits.PEIE = 1; // peripheral interrupts enabled
INTCONbits.GIE = 1; // global interrupt enable
wl_module_tx_config(wl_module_TX_NR_0); //Config Module
while(1){
LATCbits.LATC7 = 0; // turn indicator LED on
for (k=0; k<=wl_module_PAYLOAD-1; k++){
payload[k] = k;
}
payload[0] = maincounter;
payload[1] = maincounter+1;
wl_module_send(payload,wl_module_PAYLOAD);
maincounter++;
if (maincounter > 0x0F){
maincounter = 0;
}
_delay_10ms(50);
LATCbits.LATC7 = 1; // turn indicator LED off
_delay_10ms(50);
}
return 0;
}
void interrupt ISR(void){
// external interrupt IRQ pin of NRF24L01
if( INTCON3bits.INT2IF ){
unsigned char status;
// Read wl_module status
wl_module_CSN_lo; // Pull down chip select
status = spi_fast_shift(NOOP); // Read status register
wl_module_CSN_hi; // Pull up chip select
if (status & (1<<TX_DS)){ // IRQ: Package has been sent
wl_module_config_register(STATUS, (1<<TX_DS)); //Clear Interrupt Bit
PTX=0;
}
if (status & (1<<MAX_RT)){ // IRQ: Package has not been sent, send again
wl_module_config_register(STATUS, (1<<MAX_RT)); // Clear Interrupt Bit
wl_module_CE_hi; // Start transmission
__delay_us(10);
wl_module_CE_lo;
}
if (status & (1<<TX_FULL)){ //TX_FIFO Full <-- this is not an IRQ
wl_module_CSN_lo; // Pull down chip select
spi_fast_shift(FLUSH_TX); // Flush TX-FIFO
wl_module_CSN_hi; // Pull up chip select
}
// reset INT2 flag
INTCON3bits.INT2IF = 0;
}
}
Para el receptor quedo de la siguiente forma:


El archivo main.c para el receptor es el siguiente:
/*
* 2013 Elia Ritterbusch
* http://eliaselectronics.com
*
* This work is licensed under the Creative Commons Attribution 3.0 Unported License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/
*/
/*******************************************************************************
*
* XC8_006: Probando modulos nRF24L01+
*
*******************************************************************************
* FileName: main.c
* Processor: PIC18F46K22
* Complier: XC8 v1.30
* Author: Pedro Sánchez (MrChunckuee)
* Blog: http://mrchunckuee.blogspot.com/
* Email: mrchunckuee.psr@gmail.com
* Description: Probando libreria para los modulos nRF24L01+
*******************************************************************************
* Rev. Date Comment
* v1.01 06/04/2017 Modificacion para usar el PIC18F46K22
******************************************************************************/
#define _XTAL_FREQ 16000000UL
#include <xc.h>
#include <stdlib.h>
#include "spi.h"
#include "nRF24L01.h"
#include "wl_module.h"
// PIC18F46K22 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1H
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config PRICLKEN = OFF // Primary clock enable bit (Primary clock can be disabled by software)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRTEN = ON // Power-up Timer Enable bit (Power up timer enabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 190 // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC1 // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON // PORTB A/D Enable bit (PORTB<5:0> pins are configured as analog input channels on Reset)
#pragma config CCP3MX = PORTB5 // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5)
#pragma config HFOFST = ON // HFINTOSC Fast Start-up (HFINTOSC output and ready status are not delayed by the oscillator stable status)
#pragma config T3CMX = PORTC0 // Timer3 Clock input mux bit (T3CKI is on RC0)
#pragma config P2BMX = PORTD2 // ECCP2 B output mux bit (P2B is on RD2)
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled if MCLRE is also 1)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-003FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (004000-007FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection Block 2 (Block 2 (008000-00BFFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection Block 3 (Block 3 (00C000-00FFFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-003FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (004000-007FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection Block 2 (Block 2 (008000-00BFFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection Block 3 (Block 3 (00C000-00FFFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (004000-007FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection Block 2 (Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection Block 3 (Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#define MAX_STRLEN 14
char received_string[MAX_STRLEN+1];
void _delay_10ms(int length){
while(length){
__delay_ms(10);
length--;
}
}
int main(void){
unsigned char payload[wl_module_PAYLOAD]; //holds the payload
unsigned char nRF_status; //STATUS information of nRF24L01+
unsigned char zaehler = 0;
OSCCONbits.IRCF = 0b111; //Internal Fosc = 16MHz
wl_module_init(); //Init nRF Module
_delay_10ms(5); //wait for Module
// configure output port
TRISD &= ~(0x0F);
LATD |= 0x0F;
INTCONbits.PEIE = 1; // peripheral interrupts enabled
INTCONbits.GIE = 1; // global interrupt enable
wl_module_config(); //config nRF as RX Module, simple Version
while(1){
while (!wl_module_data_ready()); //waits for RX_DR Flag in STATUS
nRF_status = wl_module_get_data(payload); //reads the incomming Data to Array payload
zaehler = payload[0];
LATD |= 0x0F;
LATD &= ~(payload[0]);
}
return 0;
}
void interrupt ISR(void){
// external interrupt IRQ pin of NRF24L01
if( INTCON3bits.INT2IF ){
unsigned char status;
// Read wl_module status
wl_module_CSN_lo; // Pull down chip select
status = spi_fast_shift(NOOP); // Read status register
wl_module_CSN_hi; // Pull up chip select
if (status & (1<<TX_DS)){ // IRQ: Package has been sent
wl_module_config_register(STATUS, (1<<TX_DS)); //Clear Interrupt Bit
PTX=0;
}
if (status & (1<<MAX_RT)){ // IRQ: Package has not been sent, send again
wl_module_config_register(STATUS, (1<<MAX_RT)); // Clear Interrupt Bit
wl_module_CE_hi; // Start transmission
__delay_us(10);
wl_module_CE_lo;
}
if (status & (1<<TX_FULL)){ //TX_FIFO Full <-- this is not an IRQ
wl_module_CSN_lo; // Pull down chip select
spi_fast_shift(FLUSH_TX); // Flush TX-FIFO
wl_module_CSN_hi; // Pull up chip select
}
// reset INT2 flag
INTCON3bits.INT2IF = 0;
}
}
Vídeo:
un pequeño video donde muestra los módulos en acción:


Descargas:
Aquí el enlace directo para DESCARGAR los archivos disponibles, también puedes revisar o descargar la información desde mi repositorio en GitHub, si no sabes como descargarlo puedes checar aquí, bueno por el momento es todo si tienes dudas, comentarios, sugerencias, inquietudes, traumas, etc. dejarlas y tratare de responder lo mas pronto posible.


Donaciones:
Si te gusta el contenido o si los recursos te son de utilidad, comparte el enlace en tus redes sociales o sitios donde creas que puede ser de interés y la otra puedes ayudarme con una donación para seguir realizando publicaciones y mejorar el contenido del sitio. También puedes hacer donaciones en especie, ya sea con componentes, tarjetas de desarrollo o herramientas. Ponte en contacto para platicar, o puedes volverte uno de nuestros sponsors.


Pido una retroalimentación avisando cada que un enlace no sirva o tenga errores al momento de abrirlo, así también si una imagen no se ve o no carga, para corregirlo en el menor tiempo posible.

Publicar un comentario

2 Comentarios

  1. Hola.
    Lo primero agradecer tus aportes.
    Sabes porque al compilar tu proyecto me salen un monton de warnings de funciones no llamadas y de conversion a datos de tipo mas corto, y en el proyecto original de github no salen siendo practicamente iguales.
    Estoy trabajando con mplabx ide ver 2.10 y xc8 v1.34
    Gracias

    ResponderEliminar
    Respuestas
    1. Pues yo estoy usando MPLAB X v3.61 & XC8 v1.42 y tambien me marcan los warnings sobre funciones no llamadas (llegue a casa a compilarlo nuevamente), desconozco el por que el original no los marca, de hecho yo no compile el original directamente cree un proyecto y agregue las librerias. A pesar de eso el demo trabaja bien.

      Eliminar