[PIC] nRF24L01+ and PIC16F628A as RX

Status
Not open for further replies.

megacrypto

Junior Member level 2
Joined
Sep 21, 2009
Messages
20
Helped
5
Reputation
10
Reaction score
5
Trophy points
1,283
Visit site
Activity points
1,425
Hello All,

I'm trying to build a receiving unit using the nRF24L01+ and PIC16F628A. Im using an nRF24L01+ and RaspberryPi as my TX unit which i managed to get working (tested on another nRF24L01+ and RasPi, and also with Arduino Uno). I'm not very good with PIC programming and just started with Hitech C (managed the ABC projects of lighting an LED or writting to an LCD, etc.)

The following is my code on RasPi side for TX:

Code:
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include "RF24.h"

using namespace std;

/*
Pins:
    nRF     RasPi
    1       25      GND
    2       17      3v3
    3       22      GPIO 25
    4       24      GPIO  8
    5       23      GPIO 11
    6       19      GPIO 10 (MOSI)
    7       21      GPIO  9 (MISO)

Compile:

        g++ -Wall -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -L../librf24/  -lrf24 rpi-hub.cpp -o rpi-hub

        ~/RF24/librf24-rpi/librf24/rpi-hub

Addresses:
        Use at least 32bit address and enable 16bit CRC.
        Avoid addresses that start with 0x00, 0x55, 0xAA and 0xFF.
*/

// define Own receiving addresses:
const uint64_t pipes[5] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL, 0xF0F0F0F0E4LL, 0xF0F0F0F0E5LL };

// define Remote Nodes addresses:
const uint64_t nodes[2] = { 0x7365727632LL, 0x7365727632LL };

RF24 radio("/dev/spidev0.0",8000000,25);
uint8_t counter = 0;
char receivePayload[32];

uint64_t rxAddr = 0;
int rxPin  = 0;
int rxCmd  = 0;

void setup(void) {
    radio.begin();
    radio.enableDynamicPayloads();
    radio.setAutoAck(1);
    radio.setRetries(15,15);
    radio.setDataRate(RF24_1MBPS);
    radio.setPALevel(RF24_PA_MAX);
    radio.setChannel(75);
    radio.setCRCLength(RF24_CRC_16);

    // Open 6 pipes for readings ( 5 plus pipe0, also can be used for reading )
    radio.openWritingPipe(nodes[0]);
    radio.openReadingPipe(1,pipes[0]);
    radio.openReadingPipe(2,pipes[1]);
    radio.openReadingPipe(3,pipes[2]);
    radio.openReadingPipe(4,pipes[3]);
    radio.openReadingPipe(5,pipes[4]);

    // Start Listening
    radio.startListening();

//  radio.printDetails();
//  printf("\n\rOutput below : \n\r");
    usleep(500);

}

void sendCMD(uint64_t addr, int pin, int cmd ){
    char outBuffer[32]="";
    char temp[1]="";

//    cout << "Address = " << addr << endl;

    // set node address
    radio.openWritingPipe(addr);

    radio.stopListening();

    sprintf(outBuffer, "%03d", pin);
    strcat(outBuffer,",");
    sprintf(temp, "%03d", cmd);
    strcat(outBuffer, temp);

    if (radio.write( outBuffer, strlen(outBuffer))) {
       printf("Send successful\n\r");
    }
    else {
       printf("Send failed\n\r");
    }

    radio.startListening();
    //delay(20);
}

int main(int argc, char** argv){

    std::string s(argv[1]);
    std::stringstream strm(s);
    uint64_t n;
    strm >> std::hex >> n;
//    std::cout << std::hex << n << std::endl;

    rxPin   =   atoi(argv[2]);
    rxCmd   =   atoi(argv[3]);

//    cout << "Address = " << n << endl;

    setup();

    sendCMD(n, rxPin, rxCmd);
/*
    while(1){
        sendCMD(0x7365727631LL,0,1);
        delay(5000);
        sendCMD(0x7365727631LL,1,1);
        delay(5000);
        sendCMD(0x7365727631LL,2,1);
    }
*/
    return 0;
}

I found a lot of examples for the PIC (thanks to "asking" here on this forum), but as my knowledge is not that great in this area, I cant manage to get it running. Here is the closest code I found to work as RX:
Code:
#include <xc.h>
#include <htc.h>

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_ON & LVP_OFF & CPD_OFF & CP_OFF);
#define _XTAL_FREQ      20000000

#define _XTAL_FREQ      20000000




#include "stdint.h"
/* Memory Map */
#define CONFIG      0x00
#define EN_AA       0x01
#define EN_RXADDR   0x02
#define SETUP_AW    0x03
#define SETUP_RETR  0x04
#define RF_CH       0x05
#define RF_SETUP    0x06
#define STATUS      0x07
#define OBSERVE_TX  0x08
#define CD          0x09
#define RX_ADDR_P0  0x0A
#define RX_ADDR_P1  0x0B
#define RX_ADDR_P2  0x0C
#define RX_ADDR_P3  0x0D
#define RX_ADDR_P4  0x0E
#define RX_ADDR_P5  0x0F
#define TX_ADDR     0x10
#define RX_PW_P0    0x11
#define RX_PW_P1    0x12
#define RX_PW_P2    0x13
#define RX_PW_P3    0x14
#define RX_PW_P4    0x15
#define RX_PW_P5    0x16
#define FIFO_STATUS 0x17
#define DYNPD       0x1C

/* Bit Mnemonics */

/* configuratio nregister */
#define MASK_RX_DR  6
#define MASK_TX_DS  5
#define MASK_MAX_RT 4
#define EN_CRC      3
#define CRCO        2
#define PWR_UP      1
#define PRIM_RX     0

/* enable auto acknowledgment */
#define ENAA_P5     5
#define ENAA_P4     4
#define ENAA_P3     3
#define ENAA_P2     2
#define ENAA_P1     1
#define ENAA_P0     0

/* enable rx addresses */
#define ERX_P5      5
#define ERX_P4      4
#define ERX_P3      3
#define ERX_P2      2
#define ERX_P1      1
#define ERX_P0      0

/* setup of address width */
#define AW          0 /* 2 bits */

/* setup of auto re-transmission */
#define ARD         4 /* 4 bits */
#define ARC         0 /* 4 bits */

/* RF setup register */
#define RF_DR_LOW       5
#define PLL_LOCK    4
#define RF_DR_HIGH  3
#define RF_PWR      1 /* 2 bits */

/* general status register */
#define RX_DR       6
#define TX_DS       5
#define MAX_RT      4
#define RX_P_NO     1 /* 3 bits */
#define TX_FULL     0

/* transmit observe register */
#define PLOS_CNT    4 /* 4 bits */
#define ARC_CNT     0 /* 4 bits */

/* fifo status */
#define TX_REUSE    6
#define FIFO_FULL   5
#define TX_EMPTY    4
#define RX_FULL     1
#define RX_EMPTY    0

/* dynamic length */
#define DPL_P0      0
#define DPL_P1      1
#define DPL_P2      2
#define DPL_P3      3
#define DPL_P4      4
#define DPL_P5      5

/* Instruction Mnemonics */
#define R_REGISTER    0x00 /* last 4 bits will indicate reg. address */
#define W_REGISTER    0x20 /* last 4 bits will indicate reg. address */
#define REGISTER_MASK 0x1F
#define R_RX_PAYLOAD  0x61
#define W_TX_PAYLOAD  0xA0
#define FLUSH_TX      0xE1
#define FLUSH_RX      0xE2
#define REUSE_TX_PL   0xE3
#define ACTIVATE      0x50
#define R_RX_PL_WID   0x60
#define NOP1          0xFF

#define nrf24_CONFIG ((1 << MASK_RX_DR)|(1<<EN_CRC)|(0<<CRCO)) //

// hardware spi pin defined 16F628A
#define LED_PIN      PORTAbits.RA2 // led test // pin no. 17
#define CS_Pin       PORTBbits.RB5 //          //set port as output pin no. 11
#define CE_Pin       PORTBbits.RB4         //set port as output pin no.10
#define SCK_Pin      PORTBbits.RB1        //set port as output pin no. 7
#define Mosi_Pin     PORTBbits.RB2         //set port as output pin no. 8
#define Miso_Pin     PORTBbits.RB3        //set port as input pin no. 9
#define HIGH         1
#define LOW          0
#define payload 1;


/* H/W SPI NOT REQUIRED FOR 16F628A

void SPI_init()
{
    SSPEN = 0;
    TRISC = 0;     //SCK
    CKE = 1;
    SSPCON = 0x01;  //CKP = 0, SCK = 1MHz
    SMP = 1;
    SSPEN = 1;
}


unsigned char SPI_transfer(unsigned char data)
{
    SSPBUF = data;       // Put command into SPI buffer
    while (!BF);         // Wait for the transfer to finish
    return SSPBUF;       // Save the read value
}


*/

uint8_t PTX;





void nrf24_ce_digitalwrite(uint8_t state)
{
if (state)
{
CE_Pin = 1;
}
else
{
CE_Pin = 0;
}
}


void nrf24_csn_digitalwrite(uint8_t state)
{
if (state)
{
CS_Pin = 1;
}
else
{
CS_Pin = 0;
}
}


void nrf24_sck_digitalwrite(uint8_t state)
{
if (state)
{
SCK_Pin = 1;
}
else
{
SCK_Pin = 0;
}
}


void nrf24_mosi_digitalwrite( uint8_t state)
{
if (state)
{
Mosi_Pin = 1;
}
else
{
Mosi_Pin = 0;
}
}





char SPI_transfer(char data)
{
        char i,temp=0;
        for(i=0;i<8;i++) // output 8-bit
        {
        if((data & 0x80)==0x80)
        {
                nrf24_mosi_digitalwrite(HIGH);         // output 'uchar', MSB to MOSI
        }
        else
        {
                nrf24_mosi_digitalwrite(LOW);
        }      
//==============================================================================
                data = (data << 1);            // shift next bit into MSB..
                temp<<=1;
                nrf24_sck_digitalwrite(HIGH);                // Set SCK high..
                if((Miso_Pin))temp++;         // capture current MISO bit
                nrf24_sck_digitalwrite(LOW);              // ..then set SCK low again
        }
    return(temp);                         // return read uchar
}





/* send and rece_pinive multiple bytes over SPI */ // checked with mirf
void nrf24_transferSync(uint8_t  *dataout,uint8_t *datain,uint8_t len)
{
    uint8_t i;

    for(i=0;i<len;i++){
       datain[i] = SPI_transfer(dataout[i]);
    }
}


//send multiple bytes over SPI // checked with mirf
void nrf24_transmitSync(uint8_t *dataout,uint8_t len)
{
    uint8_t i;

    for(i=0;i<len;i++){
      SPI_transfer(dataout[i]);
    }
}

void nrf24_configRegister(uint8_t reg, uint8_t value)
{
    nrf24_csn_digitalwrite(LOW);
    SPI_transfer(W_REGISTER | (REGISTER_MASK & reg));
    SPI_transfer(value);
    nrf24_csn_digitalwrite(HIGH);
}

void nrf24_powerUpRx() // checked with mirf
{      
nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(1<<PRIM_RX)));  
nrf24_configRegister(RX_PW_P0,1);  
//nrf24_configRegister(RX_PW_P1,1);    
}


void nrf24_init()
{
        TRISB = 0b00001000;
        TRISA = 0b00000000;
}


uint8_t nrf24_data_ready()  
// checks if data is available for reading
{
        uint8_t status;  
        nrf24_csn_digitalwrite(LOW);                          // Pull down chip select
        status = SPI_transfer(0xff);                                    // Read status register
        nrf24_csn_digitalwrite(HIGH);                              // Pull up chip select
    return status & ( 1 << RX_DR ) ;
}


/* Reads payload bytes uint8_to data array */
uint8_t nrf24_getData(uint8_t *data1)  // check with mirf
{
        uint8_t status;
    /* Pull down chip select */
    nrf24_csn_digitalwrite(LOW);

    /* Send cmd to read rx payload */
    SPI_transfer(R_RX_PAYLOAD);

    /* Read payload */
    nrf24_transferSync(data1,data1,1); //payload length 1 byte

    /* Pull up chip select */
    nrf24_csn_digitalwrite(HIGH);

    /* Reset status register */
    nrf24_configRegister(STATUS,(1<<RX_DR));
        return status;

}




void main()
{
TRISB = 0b00001000;
TRISA = 0b00000000;
CMCON = 0X07;
nrf24_init();
//__delay_us(13);
nrf24_configRegister(RF_CH,89);
//nrf24_configRegister(EN_AA,(0<<ENAA_P0)|(0<<ENAA_P1));
//nrf24_configRegister(RF_SETUP,(0<<RF_DR_LOW));
//nrf24_configRegister(RF_SETUP,(0<<RF_DR_HIGH));

nrf24_powerUpRx();
__delay_ms(5);
nrf24_ce_digitalwrite(HIGH);
uint8_t nrf_data[1];
uint8_t output;
uint8_t data_final = 0;


while(1)
{
{
while(nrf24_data_ready())
        {    

        //      LED_PIN = HIGH;
        //nrf24_configRegister(STATUS, (1<<RX_DR)); // KEEP CLEARING RX_DR AS YOU KEEP ON READING PAYLOADS....
        nrf24_ce_digitalwrite(LOW); // WHEN U HAVE RECEIVED PACKETS PULL CE LOW AND START READING R_RX_PAYLOAD
                output = nrf24_getData(nrf_data);      
        //      data_final = nrf_data[0];
        nrf24_configRegister(STATUS, (1<<RX_DR));
        }


if(nrf_data[0] == 111)
{
LED_PIN = HIGH;
}
else
{
LED_PIN = LOW;
}
while(!nrf24_data_ready()) // while nrf data not available
nrf24_ce_digitalwrite(HIGH); // START LISTENING AGAIN
__delay_us(10);
}
}
}

Is there anyway that anyone can help me out here?

Thanks
 

Maybe it will help if I specify a bit more what I'm looking for, which is:

- how to setup the pipes addresses on the RX unit (on the PIC)
- how to parse through the received payload

I really hope that anyone could lend me a hand here
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…