Hi to all.
I am trying to make an rf link using the 24l01 transceiver.
I am using a code based on the demo code for the sparkfun mirf v2 board.
I am using the CCS compiler.
The transmitter uses a PIC12F629 and the receiver uses a PIC16F877A.
The transmitter transmit, then enter the sleep mode and, after 1152 ms (±), exit from sleep and repeat the cycle (this to make battery last more).
I can´t get it to work.
Can somebody help me to locate what I am doing wrong?
The code of Transmitter and Receiver are pasted below.
Any help is much apreciated.
Thanks
Sergio
Transmiter:
#include <12f629.h>
#device adc=8
#FUSES WDT //Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES PUT //Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOCPD //No EE protection
#FUSES NOPROTECT //Code not protected from reading
#use delay(clock=4000000)
/*******************************************************************/
#define CE PIN_A0 // output Chip enable to nRF24L01 CE PIN_1
#define CSN PIN_A5 // output Chip Select to nRF24L01 CSN PIN_2
#define SCK PIN_A1 // serial clock output to nRF24L01 SCK PIN_3
#define MOSI PIN_A4 // serial data out to nRF24L01 MOSI PIN_4
#define MISO PIN_A2 // serial data in from nRF24L01 MISO PIN_5
#define IRQ PIN_A3 // input valid TX/RX from nRF24L01 IRQ PIN_6
/*******************************************************************/
unsigned int cmd, data, j;
/*******************************************************************/
void NRF24l01_Send(int dat);
void TX_Mode (void);
void TX_Data (void);
/*******************************************************************/
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);setup_wdt(WDT_1152MS);
setup_timer_1(T1_DISABLED);
setup_comparator(NC_NC_NC_NC);
enable_interrupts(GLOBAL);
while(1)
{
delay_ms(2); // Wait for everything to settle...
TX_Mode();
TX_Data();
delay_ms(10);
restart_wdt (); // Restart WatchDog
sleep();
}
}
/*******************************************************************/
void TX_Mode()
{
output_low(CSN);
output_low(CE);
cmd=0x20; // 0010 0000 - Write register 0 - CONFIG
data=0x38; // 0011 1000 - PTX, CRC enabled
// bit 7 - RESERVED
// bit 6 - MASK_RX_DR
// bit 5 - MASK_TX_DS
// bit 4 - MASK_MAX_RT
// bit 3 - EN_CRC
// bit 2 - CRCO
// bit 1 - PWR_UP
// bit 0 - PRIM_RX
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_low(CSN);
cmd=0x24; // 0010 0100 - Write register 4 - SETUP_RETR
data=0x00; // 0000 0000 - Wait 250+86 ms - Re-transmit disabled
// bit 7 - ARD
// bit 6 - ARD
// bit 5 - ARD
// bit 4 - ARD
// bit 3 - ARC
// bit 2 - ARC
// bit 1 - ARC
// bit 0 - ARC
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_low(CSN);
cmd=0x23; // 0010 0011 - Write register 3 - SETUP_AW
data=0x03; // 0000 0011 - ADDRESS Width = 3
// bit 7 - RESERVED
// bit 6 - RESERVED
// bit 5 - RESERVED
// bit 4 - RESERVED
// bit 3 - RESERVED
// bit 2 - RESERVED
// bit 1 - AW
// bit 0 - AW
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_low(CSN);
cmd=0x26; // 0010 0110 - Write register 6 - RF_SETUP
data=0x07; // 0000 0111 - DATA RATE = 1 Mb
// bit 7 - RESERVED
// bit 6 - RESERVED
// bit 5 - RESERVED
// bit 4 - PLL_LOCK
// bit 3 - RF_DR
// bit 2 - RF_PWR
// bit 1 - RF_PWR
// bit 0 - LNA_HCURR
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_low(CSN);
cmd=0x25; // 0010 0101 - Write register 5 - RF_CH
data=0x02; // 0000 0010 - Set Channel 2
// bit 7 - RESERVED
// bit 6 - RF_CH
// bit 5 - RF_CH
// bit 4 - RF_CH
// bit 3 - RF_CH
// bit 2 - RF_CH
// bit 1 - RF_CH
// bit 0 - RF_CH
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_low(CSN);
cmd=0x30; // 0011 0000 - Write register 10 - TX_ADDR
data=0xE7; // 1110 0111 - Set Address E7E7E7E7E7.
NRF24l01_Send(cmd);
for(j=0;j<5;j++)
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_low(CSN);
cmd=0x21; // 0010 0001 - Write register 1 - EN_AA
data=0x00; // 0000 0000 - Disable AUTOACK
// bit 7 - RESERVED
// bit 6 - RESERVED
// bit 5 - ENAA_P5
// bit 4 - ENAA_P4
// bit 3 - ENAA_P3
// bit 2 - ENAA_P2
// bit 1 - ENAA_P1
// bit 0 - ENAA_P0
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_low(CSN);
}
/*******************************************************************/
void TX_Data()
{
output_low(CSN);
cmd=0x27; // 0010 0111 - Write register 7 - STATUS
data=0x7E; // 0111 1110 - Clear Ints
// bit 7 - RESERVED
// bit 6 - RX_DR
// bit 5 - TX_DS
// bit 4 - MAX_RT
// bit 3 - RX_P_NO
// bit 2 - RX_P_NO
// bit 1 - RX_P_NO
// bit 0 - TX_FULL
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_low(CSN);
cmd=0xE1; // (1110 0001) - Flush TX
data=0x3A; // 0011 1010 - Power up module
// bit 7 - RESERVED
// bit 6 - MASK_RX_DR
// bit 5 - MASK_TX_DS
// bit 4 - MASK_MAX_RT
// bit 3 - EN_CRC
// bit 2 - CRCO
// bit 1 - PWR_UP
// bit 0 - PRIM_RX
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_high(CE);
cmd = 0xA0; // 1010 0000 - Write tx_payload
NRF24l01_Send(cmd);
data = 0x34; // 0011 0100 - First byte of payload
NRF24l01_Send(data);
data = 0x33; // 0011 0011 - Second byte of payload
NRF24l01_Send(data);
data = 0x32; // 0011 0010 - Third byte of payload
NRF24l01_Send(data);
data = 0x31; // 0011 0001 - Fourth byte of payload
NRF24l01_Send(data);
output_high(CSN);
delay_us(20);
output_high(CE);
delay_us(20);
output_low(CE);
}
/*******************************************************************/
void NRF24l01_Send(int dat)
{
int i;
for (i=0;i<8;i++)
{
if (dat && 0x80)
{
output_high(MOSI);
}
else
{
output_low(MOSI);
}
output_high(SCK);
output_low(SCK);
dat <<=1;
}//for (i...
}
/*******************************************************************/
Receiver:
#case
#include <16F877.h>
#device *=16
/*******************************************************************/
//Change the following to change the clock frequency
#define CRYSTAL_FREQ 8000000
#define YES 1
#define NO 0
#define ON 1
#define OFF 0
#define HIGH 1
#define LOW 0
#define LCD_D0 PIN_B4
#define LCD_D1 PIN_B5
#define LCD_D2 PIN_B6
#define LCD_D3 PIN_B7
#define LCD_EN PIN_B3
#define LCD_RS PIN_B2
#define RX_IN PIN_B2
#define BUZZER PIN_D0
#define LED PIN_B7
#define LINE_1 0x00
#define LINE_2 0x40
#define LINE_3 0x10
#define LINE_4 0x50
#define CLEAR_DISP 0x01
#define CR 13
#define SPACE ' '
#define PERIOD '.'
#define PLUS '+'
#define RX_BUFFER_SIZE 40
// Control and SPI Pin defines //////////////////////////////////////////
#define CE PIN_C1 // output Chip enable to nRF24L01 CE
#define CSN PIN_C2 // output Chip Select to nRF24L01 CSN
#define SCK PIN_C3 // serial clock output to nRF24L01 SCK
#define MOSI PIN_C5 // serial data out to nRF24L01 MOSI
#define MISO PIN_C4 // serial data in from nRF24L01 MISO
#define IRQ PIN_B0 // input valid TX/RX from nRF24L01 IRQ
// LED indicator Pins
#define LED0 PIN_A0
#define LED1 PIN_A1
#define LED2 PIN_A2
#define LED_Activity PIN_A3
/*******************************************************************/
#separate void InitRxBuffer ( void );
#separate void LCD_Init ( void );
#separate void LCD_SetPosition ( unsigned int cX );
#separate void LCD_PutChar ( unsigned int cX );
#separate void LCD_PutCmd ( unsigned int cX );
#separate void LCD_PulseEnable ( void );
#separate void LCD_SetData ( unsigned int cX );
#separate void Play (void);
#separate void Zero_cC (void);
#separate void RF_Config_RX (void);
#separate void NRF24l01_Send (int cmd);
#separate void NRF24l01_Rx_RST (void);
/*******************************************************************/
#fuses HS, NOPROTECT, PUT, NOWDT, NOBROWNOUT//, NOLVP//, NOCPD
#use standard_io ( A )
#use standard_io ( B )
#use standard_io ( C )
#use delay ( clock = CRYSTAL_FREQ )
#use rs232 ( baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS, stream=TAG )
#priority RDA, RTCC
/*******************************************************************/
static char cRxBuffer[RX_BUFFER_SIZE]; // RX Buffer
static char cRxMsgReady, cRxByteCnt;
static char *cRxBufferWritePtr, *cRxBufferReadPtr;// Pointer for the Rx buffer
unsigned int dataready;
unsigned int Timer_1ms, Timer_100ms, Timer_1s;// Timers 1ms, 100ms, 1s
unsigned int ID_1, ID_2, ID_3, ID_4, state;
//long CRC xFFFF;
enum
{
State_IDDLE,
State_TIMEOUT_Second,
State_ID_Received
};
/*******************************************************************/
#INT_EXT
EXTINT_isr()
{
if(!input(PIN_B0)) // keep button action sychronized wth button flag
{
ID_1 ++;
if (ID_1 == 0)
{
ID_2 ++;
if (ID_2 ==0)
{
ID_3 ++;
if (ID_3 == 0)
{
ID_4 ++;
if (ID_4 == 0)
{
ID_1 = 1;
}// if (ID_4
}// if (ID_3...
}// if )ID_2...
}// if (ID_1...
state = State_ID_Received;
//delay_ms(10);
}
return (0);
}
/*******************************************************************/
#INT_TIMER0
TIMER0_isr()
{
set_timer0(100); // Restart 1 ms timming
if (Timer_1ms++ >= 100) // If 100 ms
{
Timer_1ms =0; // Reset counter
Timer_100ms++; // Increment 100 ms counter
output_toggle(LED_Activity); // Toggle the state of led
}
if (Timer_100ms >= 10) // 1 second?
{
Timer_100ms =0; // Reset 100ms counter
Timer_1s++; // Increment 1 second counter
state = State_TIMEOUT_Second; // 1 second elapsed.
}
return(0);
}
/*******************************************************************/
void main ( void )
{
disable_interrupts ( GLOBAL ); // Just in case...
set_tris_a(00000000); // 1 --> Input 0 --> output
set_tris_b(00000001); // 1 --> Input 0 --> output
set_tris_c(00000000); // 1 --> Input 0 --> output
set_tris_d(00000000); // 1 --> Input 0 --> output
setup_adc_ports(NO_ANALOGS); // Set PortA Digital IO
setup_adc(ADC_OFF); // Turn off ADC
setup_ccp1(CCP_OFF); // Turn off CCP - will disrupt output writes on PIN_B3 if on
//setup_spi(SPI_MASTER|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64);
setup_timer_1(T1_DISABLED); // Disable Timer 1
setup_timer_2(T2_DISABLED,0,1); // Disable Timer 2
output_float ( RX_IN ); // Ensure Rx input is HiZ
LCD_Init(); // Set up LCD for 4-wire bus, etc.
delay_ms(200); // wait lcd...
ID_1 = 0;
ID_2 = 0;
ID_3 = 0;
ID_4 = 0;
Timer_1ms = 0; // Reset Timer counters
Timer_100ms = 0; // " " "
Timer_1s = 0; // " " "
dataready = FALSE;
/* INIT MESSAGE */
LCD_SetPosition ( LINE_1 + 0 );
printf ( LCD_PutChar, "2.4 GHz Terminal" ); // welcome screen
LCD_SetPosition ( LINE_2 + 0 );
printf ( LCD_PutChar, " RFtreck " );
output_low(CE); // set CE low to disable transmission
output_low(LED0 | LED1 | LED2 | LED_Activity); // set LEDs Low
delay_ms(2);
output_high(LED0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);//Internal counter and div by 64
set_timer0(100); // Count 156 times (20000000/128/156 = 1ms)
enable_interrupts ( INT_TIMER0); // enable timer0 interrupt
ext_int_edge(H_TO_L); // Interrupção na descida do pulso.
enable_interrupts(INT_EXT);
//aqui, limpar os flags de interrupções, senão gera int na b0...
enable_interrupts ( GLOBAL ); // enable all interrupts
delay_ms(100);
output_low(LED0);
Play (); // Starting Connection to modem...
RF_Config_RX(); // Init NRF24l01 in reception mode.
/********************************************************************
MAIN LOOP
********************************************************************/
while(1)
{
switch (state)
{
case State_IDDLE:
break;
case State_ID_Received:
{
disable_interrupts ( GLOBAL );
NRF24l01_Rx_RST();
LCD_PutCmd (CLEAR_DISP); // Clear LCD.
LCD_SetPosition ( LINE_1 + 0 );
printf ( LCD_PutChar, " Recebido dado." );
LCD_SetPosition ( LINE_2 + 0 );
printf ( LCD_PutChar, " %X%X%X%X ", ID_4, ID_3, ID_2, ID_1 );
fprintf ( TAG,"%X%X%X%X\n\r", ID_4, ID_3, ID_2, ID_1 );
//LCD_PutCmd (CLEAR_DISP); // Clear LCD.
state = State_IDDLE;
enable_interrupts ( GLOBAL ); // Enable all interrupts
break;
}
case State_TIMEOUT_Second:
{
disable_interrupts ( GLOBAL );
output_toggle(LED2); // Toggle the state of led
state = State_IDDLE;
enable_interrupts ( GLOBAL ); // Enable all interrupts
}
default:
state = State_IDDLE;
break;
}//switch (state)
}//while(1)
}
/*******************************************************************/
/* LCD FUNCTIONS ==================================================*/
#separate void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
delay_ms ( 200 ); /* wait enough time after Vdd rise */
output_low ( LCD_RS );
LCD_SetData ( 0x03 ); /* init with specific nibbles to start 4-bit mode */
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); /* set 4-bit interface */
LCD_PulseEnable(); /* send dual nibbles hereafter, MSN first */
LCD_PutCmd ( 0x2C ); /* function set (all lines, 5x7 characters) */
LCD_PutCmd ( 0x0C ); /* display ON, cursor off, no blink */
LCD_PutCmd ( 0x01 ); /* clear display */
LCD_PutCmd ( 0x06 ); /* entry mode set, increment & scroll left */
}
/*******************************************************************/
#separate void LCD_SetPosition ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}
/*******************************************************************/
#separate void LCD_PutChar ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
output_high ( LCD_RS );
LCD_SetData ( swap ( cX ) ); /* send high nibble */
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */
LCD_PulseEnable();
output_low ( LCD_RS );
}
/*******************************************************************/
#separate void LCD_PutCmd ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) ); /* send high nibble */
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */
LCD_PulseEnable();
}
/*******************************************************************/
#separate void LCD_PulseEnable ( void )
{
output_high ( LCD_EN );
delay_us ( 3 ); // was 10
output_low ( LCD_EN );
delay_ms ( 3 ); // was 5
}
/*******************************************************************/
#separate void LCD_SetData ( unsigned int cX )
{
output_bit ( LCD_D0, cX & 0x01 );
output_bit ( LCD_D1, cX & 0x02 );
output_bit ( LCD_D2, cX & 0x04 );
output_bit ( LCD_D3, cX & 0x08 );
}
/*******************************************************************/
/* RS232 FUNCTIONS ================================================*/
#separate void InitRxBuffer ( void )
{
disable_interrupts ( INT_RDA );
memset (cRxBuffer, 0, sizeof(cRxBuffer)); // Zero Buffer.
Zero_cC(); // Zero Buffer cC
cRxBufferWritePtr = cRxBuffer; // Point to beginning of buffer.
cRxBufferReadPtr = cRxBuffer; // " " "
cRxByteCnt = 0; // Number of chars received.
cRxMsgReady = NO; // Message is not ready to process.
enable_interrupts ( INT_RDA ); // Enable serial interrupt.
enable_interrupts ( GLOBAL ); // Enable all interrupts.
}
/*******************************************************************/
#separate void Play (void)
{
// Play a tone in Buzzer (for debug only).
output_high (BUZZER);
delay_ms (250);
output_low (BUZZER);
}
/*******************************************************************/
void RF_Config_RX (void)
{
int j, data, cmd;
output_low(CSN);
output_low(CE);
cmd=0x20; // 0010 0000 - Write register 0 - CONFIG
data=0x39; // 0011 1001 - PRX, CRC enabled
// bit 7 - RESERVED
// bit 6 - MASK_RX_DR
// bit 5 - MASK_TX_DS
// bit 4 - MASK_MAX_RT
// bit 3 - EN_CRC
// bit 2 - CRCO
// bit 1 - PWR_UP
// bit 0 - PRIM_RX
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
output_low(CSN);
cmd=0x21; // 0010 0001 - Write register 1 - EN_AA
data=0x00; // 0000 0000 - Disable AUTOACK
// bit 7 - RESERVED
// bit 6 - RESERVED
// bit 5 - ENAA_P5
// bit 4 - ENAA_P4
// bit 3 - ENAA_P3
// bit 2 - ENAA_P2
// bit 1 - ENAA_P1
// bit 0 - ENAA_P0
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
output_low(CSN);
cmd=0x23; // 0010 0011 - Write register 3 - SETUP_AW
data=0x03; // 0000 0011 - ADDRESS Width = 3
// bit 7 - RESERVED
// bit 6 - RESERVED
// bit 5 - RESERVED
// bit 4 - RESERVED
// bit 3 - RESERVED
// bit 2 - RESERVED
// bit 1 - AW
// bit 0 - AW
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
output_low(CSN);
cmd=0x26; // 0010 0110 - Write register 6 - RF_SETUP
data=0x07; // 0000 0111 - DATA RATE = 1 Mb
// bit 7 - RESERVED
// bit 6 - RESERVED
// bit 5 - RESERVED
// bit 4 - PLL_LOCK
// bit 3 - RF_DR
// bit 2 - RF_PWR
// bit 1 - RF_PWR
// bit 0 - LNA_HCURR
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
output_low(CSN);
cmd=0x31; // 0011 0001 - Write register 11 - RX_PW_P0
data=0x04; // 0000 0100 - Data payload = 4 bytes
// bit 7 - RESERVED
// bit 6 - RESERVED
// bit 5 - RX_PW_P0
// bit 4 - RX_PW_P0
// bit 3 - RX_PW_P0
// bit 2 - RX_PW_P0
// bit 1 - RX_PW_P0
// bit 0 - RX_PW_P0
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
output_low(CSN);
cmd=0x25; // 0010 0101 - Write register 5 - RF_CH
data=0x02; // 0000 0010 - Set Channel 2
// bit 7 - RESERVED
// bit 6 - RF_CH
// bit 5 - RF_CH
// bit 4 - RF_CH
// bit 3 - RF_CH
// bit 2 - RF_CH
// bit 1 - RF_CH
// bit 0 - RF_CH
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
output_low(CSN);
cmd=0x30; // 0011 0000 - Write register 10 - TX_ADDR
data=0xE7; // 1110 0111 - Set Address E7E7E7E7E7.
NRF24l01_Send(cmd);
for(j=0;j<5;j++)
NRF24l01_Send(data);
output_high(CSN);
output_low(CSN);
cmd=0x20; // 0010 0000 - Write register 0 - CONFIG
data=0x3B; // 0011 1011 - Power up module
// bit 7 - RESERVED
// bit 6 - MASK_RX_DR
// bit 5 - MASK_TX_DS
// bit 4 - MASK_MAX_RT
// bit 3 - EN_CRC
// bit 2 - CRCO
// bit 1 - PWR_UP
// bit 0 - PRIM_RX
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
output_high(CE);
}
/*******************************************************************/
void NRF24l01_Send(int dat)
{
int i;
for (i=0;i<8;i++)
{
if (dat && 0x80)
{
output_high(MOSI);
}
else
{
output_low(MOSI);
}
output_high(SCK);
output_low(SCK);
dat <<=1;
}//for (i...
}
/*******************************************************************/
void NRF24l01_Rx_RST (void)
{
int i, j, data, cmd;
cmd = 0x61; // 0110 0001 - Read RX Payload
output_low (CSN);
NRF24l01_Send(cmd);
for (j=0; j<4; j++)
{
data=0;
for (i=0;i<8;i++)
{
output_high(SCK);
shift_left(&data, 1, input(MISO));
output_low(SCK);
}// for (i=0...
printf("%X", data);
}// for (j=0...
printf("\n\r");
cmd=0xE2;// 1110 0010 - Flush RX FIFO
output_low (CSN);
NRF24l01_Send(cmd);
output_high(CSN);
output_low(CSN);
cmd=0x27; // 0010 0111 - Write Register 7 - STATUS
data=0x40; // 0100 0000 - Reset INTs
// bit 7 - RESERVED
// bit 6 - RX_DR
// bit 5 - TX_DS
// bit 4 - MAX_RT
// bit 3 - RX_P_NO
// bit 2 - RX_P_NO
// bit 1 - RX_P_NO
// bit 0 - TX_FULL
NRF24l01_Send(cmd);
NRF24l01_Send(data);
output_high(CSN);
}
/*******************************************************************/