Commit 2406e06a authored by TMRh20's avatar TMRh20

Raspberry Pi support

Added support for hardware SPI on RPI per jscrane fork:
- Fixed a few bugs with single SPI transfers
- Aligned with optimized RF24 library fork
- Updated bmc2835 files per
http://www.airspayce.com/mikem/bcm2835/index.html
- Merged bcm files with changes from
https://github.com/farconada/RF24Network
- Added example files
- Added setup info to readme
parent 8ff9fb6f
#############################################################################
#
# Makefile for librf24-bcm on Raspberry Pi
#
# License: GPL (General Public License)
# Author: Charles-Henri Hallard
# Date: 2013/03/13
#
# Description:
# ------------
# use make all and mak install to install the library
# You can change the install directory by editing the LIBDIR line
#
PREFIX=/usr/local
# Library parameters
# where to put the lib
LIBDIR=$(PREFIX)/lib
# lib name
LIB=librf24-bcm
# shared library name
LIBNAME=$(LIB).so.1.0
# The recommended compiler flags for the Raspberry Pi
CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
# make all
# reinstall the library after each recompilation
all: librf24-bcm install
# Make the library
librf24-bcm: RF24.o bcm2835.o
g++ -shared -Wl,-soname,$@.so.1 ${CCFLAGS} -o ${LIBNAME} $^
# Library parts
RF24.o: RF24.cpp
g++ -Wall -fPIC ${CCFLAGS} -c $^
bcm2835.o: bcm2835.c
gcc -Wall -fPIC ${CCFLAGS} -c $^
# clear build files
clean:
rm -rf *.o ${LIB}.*
# Install the library to LIBPATH
install:
@echo "[Install]"
@if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi
#@install -m 0755 ${LIB}.a ${LIBDIR}
@install -m 0755 ${LIBNAME} ${LIBDIR}
@ln -sf ${LIBDIR}/${LIBNAME} ${LIBDIR}/${LIB}.so.1
@ln -sf ${LIBDIR}/${LIBNAME} ${LIBDIR}/${LIB}.so
@ldconfig
This diff is collapsed.
This diff is collapsed.
/*
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
03/17/2013 : Charles-Henri Hallard (http://hallard.me)
Modified to use with Arduipi board http://hallard.me/arduipi
Modified to use the great bcm2835 library for I/O and SPI
*/
#ifndef __RF24_CONFIG_H__
#define __RF24_CONFIG_H__
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <stddef.h>
#include "bcm2835.h"
// GCC a Arduino Missing
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define _BV(x) (1<<(x))
#define pgm_read_word(p) (*(p))
#define pgm_read_byte(p) (*(p))
#endif // __RF24_CONFIG_H__
// vim:ai:cin:sts=2 sw=2 ft=cpp
This diff is collapsed.
This diff is collapsed.
#############################################################################
#
# Makefile for librf24 examples on Raspberry Pi
#
# License: GPL (General Public License)
# Author: gnulnulf <arco@appeltaart.mine.nu>
# Date: 2013/02/07 (version 1.0)
#
# Description:
# ------------
# use make all and make install to install the examples
# You can change the install directory by editing the prefix line
#
prefix := /usr/local
# The recommended compiler flags for the Raspberry Pi
CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
#CCFLAGS=
# define all programs
#PROGRAMS = scanner pingtest gettingstarted
PROGRAMS = gettingstarted gettingstarted_call_response transfer pingpair_dyn
SOURCES = ${PROGRAMS:=.cpp}
all: ${PROGRAMS}
${PROGRAMS}: ${SOURCES}
g++ ${CCFLAGS} -Wall -I../ -lrf24-bcm $@.cpp -o $@
clean:
rm -rf $(PROGRAMS)
install: all
test -d $(prefix) || mkdir $(prefix)
test -d $(prefix)/bin || mkdir $(prefix)/bin
for prog in $(PROGRAMS); do \
install -m 0755 $$prog $(prefix)/bin; \
done
.PHONY: install
#############################################################################
#
# Makefile for librf24 examples on Raspberry Pi
#
# License: GPL (General Public License)
# Author: gnulnulf <arco@appeltaart.mine.nu>
# Date: 2013/02/07 (version 1.0)
#
# Description:
# ------------
# use make all and make install to install the examples
# You can change the install directory by editing the prefix line
#
prefix := /usr/local
# The recommended compiler flags for the Raspberry Pi
CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
#CCFLAGS=
# define all programs
PROGRAMS = rpi-hub scanner
SOURCES = ${PROGRAMS:=.cpp}
all: ${PROGRAMS}
${PROGRAMS}: ${SOURCES}
g++ ${CCFLAGS} -Wall -I../ -lrf24-bcm $@.cpp -o $@
clean:
rm -rf $(PROGRAMS)
install: all
test -d $(prefix) || mkdir $(prefix)
test -d $(prefix)/bin || mkdir $(prefix)/bin
for prog in $(PROGRAMS); do \
install -m 0755 $$prog $(prefix)/bin; \
done
.PHONY: install
/*
*
* Filename : rpi-hub.cpp
*
* This program makes the RPi as a hub listening to all six pipes from the remote sensor nodes ( usually Arduino )
* and will return the packet back to the sensor on pipe0 so that the sender can calculate the round trip delays
* when the payload matches.
*
* I encounter that at times, it also receive from pipe7 ( or pipe0 ) with content of FFFFFFFFF that I will not sent
* back to the sender
*
* Refer to RF24/examples/rpi_hub_arduino/ for the corresponding Arduino sketches to work with this code.
*
*
* CE is not used and CSN is GPIO25 (not pinout)
*
* Refer to RPi docs for GPIO numbers
*
* Author : Stanley Seow
* e-mail : stanleyseow@gmail.com
* date : 6th Mar 2013
*
* 03/17/2013 : Charles-Henri Hallard (http://hallard.me)
* Modified to use with Arduipi board http://hallard.me/arduipi
* Changed to use modified bcm2835 and RF24 library
*
*
*/
#include <cstdlib>
#include <iostream>
#include "../RF24.h"
using namespace std;
// Radio pipe addresses for the 2 nodes to communicate.
// First pipe is for writing, 2nd, 3rd, 4th, 5th & 6th is for reading...
const uint64_t pipes[6] =
{ 0xF0F0F0F0D2LL, 0xF0F0F0F0E1LL,
0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL,
0xF0F0F0F0F1, 0xF0F0F0F0F2
};
// CE Pin, CSN Pin, SPI Speed
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_8MHZ);
int main(int argc, char** argv)
{
uint8_t len;
// Refer to RF24.h or nRF24L01 DS for settings
radio.begin();
radio.enableDynamicPayloads();
radio.setAutoAck(1);
radio.setRetries(15,15);
radio.setDataRate(RF24_1MBPS);
radio.setPALevel(RF24_PA_MAX);
radio.setChannel(76);
radio.setCRCLength(RF24_CRC_16);
// Open 6 pipes for readings ( 5 plus pipe0, also can be used for reading )
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
radio.openReadingPipe(2,pipes[2]);
radio.openReadingPipe(3,pipes[3]);
radio.openReadingPipe(4,pipes[4]);
radio.openReadingPipe(5,pipes[5]);
//
// Start listening
//
radio.startListening();
//
// Dump the configuration of the rf unit for debugging
//
radio.printDetails();
printf("Output below : \n");
delay(1);
while(1)
{
char receivePayload[32];
uint8_t pipe = 1;
// Start listening
radio.startListening();
while ( radio.available(&pipe) )
{
len = radio.getDynamicPayloadSize();
radio.read( receivePayload, len );
// Display it on screen
printf("Recv: size=%i payload=%s pipe=%i",len,receivePayload,pipe);
// Send back payload to sender
radio.stopListening();
// if pipe is 7, do not send it back
if ( pipe != 7 )
{
radio.write(receivePayload,len);
receivePayload[len]=0;
printf("\t Send: size=%i payload=%s pipe:%i\n",len,receivePayload,pipe);
}
else
{
printf("\n");
}
pipe++;
// reset pipe to 0
if ( pipe > 6 )
pipe = 0;
}
delayMicroseconds(20);
}
return 0;
}
/*
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
03/17/2013 : Charles-Henri Hallard (http://hallard.me)
Modified to use with Arduipi board http://hallard.me/arduipi
Changed to use modified bcm2835 and RF24 library
*/
/**
* Channel scanner
*
* Example to detect interference on the various channels available.
* This is a good diagnostic tool to check whether you're picking a
* good channel for your application.
*
* Inspired by cpixip.
* See http://arduino.cc/forum/index.php/topic,54795.0.html
*/
#include <cstdlib>
#include <iostream>
#include "../RF24.h"
using namespace std;
//
// Hardware configuration
//
// CE Pin, CSN Pin, SPI Speed
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_8MHZ);
//
// Channel info
//
//const uint8_t num_channels = 128;
const uint8_t num_channels = 120;
uint8_t values[num_channels];
const int num_reps = 100;
int reset_array=0;
int main(int argc, char** argv)
{
//
// Print preamble
//
//Serial.begin(57600);
//printf_begin();
printf("RF24/examples/scanner/\n");
//
// Setup and configure rf radio
//
radio.begin();
radio.setAutoAck(false);
// Get into standby mode
radio.startListening();
radio.stopListening();
radio.printDetails();
// Print out header, high then low digit
int i = 0;
while ( i < num_channels )
{
printf("%x",i>>4);
++i;
}
printf("\n");
i = 0;
while ( i < num_channels )
{
printf("%x",i&0xf);
++i;
}
printf("\n");
// forever loop
while(1)
{
if ( reset_array == 1 )
{
// Clear measurement values
memset(values,0,sizeof(values));
printf("\n");
}
// Scan all channels num_reps times
int i = num_channels;
while (i--)
{
// Select this channel
radio.setChannel(i);
// Listen for a little
radio.startListening();
delayMicroseconds(128);
//radio.stopListening();
// Did we get a carrier?
if ( radio.testCarrier() )
++values[i];
if ( values[i] == 0xf )
{
reset_array = 2;
}
radio.stopListening();
}
// Print out channel measurements, clamped to a single hex digit
i = 0;
while ( i < num_channels )
{
printf("%x",min(0xf,(values[i]&0xf)));
++i;
}
printf("\n");
}
return 0;
}
// vim:ai:cin:sts=2 sw=2 ft=cpp
/*
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
03/17/2013 : Charles-Henri Hallard (http://hallard.me)
Modified to use with Arduipi board http://hallard.me/arduipi
Changed to use modified bcm2835 and RF24 library
TMRh20 2014 - Updated to work with optimized RF24 Arduino library
*/
/**
* Example RF Radio Ping Pair
*
* This is an example of how to use the RF24 class on RPi, communicating to an Arduino running
* the GettingStarted sketch.
*/
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include "./RF24.h"
using namespace std;
//
// Hardware configuration
//
// CE Pin, CSN Pin, SPI Speed
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_8MHZ);
RF24 radio(RPI_V2_GPIO_P1_15,BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL };
bool role_ping_out = 1, role_pong_back = 0;
bool role = 0;
int main(int argc, char** argv){
// Print preamble:
printf("RF24/examples/pingtest/\n");
// Setup and configure rf radio
radio.begin();
// optionally, increase the delay between retries & # of retries
radio.setRetries(15,15);
// Dump the configuration of the rf unit for debugging
radio.printDetails();
/********* Role chooser ***********/
printf("\n ************ Role Setup ***********\n");
string input = "";
char myChar = {0};
cout << "Choose a role: Enter 0 for pong_back, 1 for ping_out (CTRL+C to exit) \n>";
getline(cin,input);
if(input.length() == 1) {
myChar = input[0];
if(myChar == '0'){
cout << "Role: Pong Back, awaiting transmission " << endl << endl;
}else{ cout << "Role: Ping Out, starting transmission " << endl << endl;
role = role_ping_out;
}
}
/***********************************/
// This simple sketch opens two pipes for these two nodes to communicate
// back and forth.
if ( role == role_ping_out ) {
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
} else {
radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1,pipes[0]);
radio.startListening();
}
// forever loop
while (1)
{
if (role == role_ping_out)
{
// First, stop listening so we can talk.
radio.stopListening();
// Take the time, and send it. This will block until complete
printf("Now sending...\n");
unsigned long time = millis();
bool ok = radio.write( &time, sizeof(unsigned long) );
if (!ok){
printf("failed.\n");
}
// Now, continue listening
radio.startListening();
// Wait here until we get a response, or timeout (250ms)
unsigned long started_waiting_at = millis();
bool timeout = false;
while ( ! radio.available() && ! timeout ) {
// by bcatalin » Thu Feb 14, 2013 11:26 am
//delay(5); //add a small delay to let radio.available to check payload
if (millis() - started_waiting_at > 200 )
timeout = true;
}
// Describe the results
if ( timeout )
{
printf("Failed, response timed out.\n");
}
else
{
// Grab the response, compare, and send to debugging spew
unsigned long got_time;
radio.read( &got_time, sizeof(unsigned long) );
// Spew it
printf("Got response %lu, round-trip delay: %lu\n",got_time,millis()-got_time);
}
// Try again 1s later
// delay(1000);
sleep(1);
}
//
// Pong back role. Receive each packet, dump it out, and send it back
//
if ( role == role_pong_back )
{
// if there is data ready
//printf("Check available...\n");
//delay(3);
if ( radio.available() )
{
// Dump the payloads until we've gotten everything
unsigned long got_time;
// Fetch the payload, and see if this was the last one.
radio.read( &got_time, sizeof(unsigned long) );
radio.stopListening();
//delay(1);
// Seem to need a delay, or the RPi is too quick
radio.write( &got_time, sizeof(unsigned long) );
//delay(1);
// Now, resume listening so we catch the next packets.
radio.startListening();
//delay(1);
// Spew it
printf("Got payload(%d) %lu...\n",sizeof(unsigned long), got_time);
}
//delay(5);
}
} // forever loop
return 0;
}
/*
TMRh20 2014 - Updated to work with optimized RF24 Arduino library
*/
/**
* Example for efficient call-response using ack-payloads
*
* This example continues to make use of all the normal functionality of the radios including
* the auto-ack and auto-retry features, but allows ack-payloads to be written optionlly as well.
* This allows very fast call-response communication, with the responding radio never having to
* switch out of Primary Receiver mode to send back a payload, but having the option to switch to
* primary transmitter if wanting to initiate communication instead of respond to a commmunication.
*/
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include "./RF24.h"
using namespace std;
//
// Hardware configuration
//
// CE Pin, CSN Pin, SPI Speed
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t addresses[2] = { 0xABCDABCD71LL, 0x544d52687CLL };
bool role_ping_out = 1, role_pong_back = 0, role = 0;
uint8_t counter = 1; // A single byte to keep track of the data being sent back and forth
int main(int argc, char** argv){
printf("RF24/examples/gettingstarted_call_response\n");
radio.begin();
radio.setAutoAck(1); // Ensure autoACK is enabled
radio.enableAckPayload(); // Allow optional ack payloads
radio.setRetries(1,15); // Smallest time between retries, max no. of retries
radio.setPayloadSize(1); // Here we are sending 1-byte payloads to test the call-response speed
//radio.powerUp();
radio.printDetails(); // Dump the configuration of the rf unit for debugging
/********* Role chooser ***********/
printf("\n ************ Role Setup ***********\n");
string input = "";
char myChar = {0};
cout << "Choose a role: Enter 0 for pong_back, 1 for ping_out (CTRL+C to exit)\n>";
getline(cin,input);
if(input.length() == 1) {
myChar = input[0];
if(myChar == '0'){
cout << "Role: Pong Back, awaiting transmission " << endl << endl;
}else{ cout << "Role: Ping Out, starting transmission " << endl << endl;
role = role_ping_out;
}
}
/***********************************/
// This simple sketch opens two pipes for these two nodes to communicate
// back and forth.
if ( role == role_ping_out ) {
radio.openWritingPipe(addresses[0]);
radio.openReadingPipe(1,addresses[1]);
}else{
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1,addresses[0]);
radio.startListening();
}
// forever loop
while (1){
/****************** Ping Out Role ***************************/
if (role == role_ping_out){ // Radio is in ping mode
uint8_t gotByte; // Initialize a variable for the incoming response
radio.stopListening(); // First, stop listening so we can talk.
printf("Now sending %d as payload. ",counter); // Use a simple byte counter as payload
unsigned long time = millis(); // Record the current microsecond count
if ( radio.write(&counter,1) ){ // Send the counter variable to the other radio
if(!radio.available()){ // If nothing in the buffer, we got an ack but it is blank
printf("Got blank response. round-trip delay: %lu ms\n\r",millis()-time);
}else{
while(radio.available() ){ // If an ack with payload was received
radio.read( &gotByte, 1 ); // Read it, and display the response time
printf("Got response %d, round-trip delay: %lu ms\n\r",gotByte,millis()-time);
counter++; // Increment the counter variable
}
}
}else{ printf("Sending failed.\n\r"); } // If no ack response, sending failed
sleep(1); // Try again later
}
/****************** Pong Back Role ***************************/
if ( role == role_pong_back ) {
uint8_t pipeNo, gotByte; // Declare variables for the pipe and the byte received
while( radio.available(&pipeNo)){ // Read all available payloads
radio.read( &gotByte, 1 );
// Since this is a call-response. Respond directly with an ack payload.
// Ack payloads are much more efficient than switching to transmit mode to respond to a call
radio.writeAckPayload(pipeNo,&gotByte, 1 ); // This can be commented out to send empty payloads.
printf("Sent response %d \n\r", gotByte);
}
}
} //while 1
} //main
/*
TMRh20 2014 - Optimized RF24 Library Fork
*/
/**
* Example using Dynamic Payloads
*
* This is an example of how to use payloads of a varying (dynamic) size.
*/
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include "./RF24.h"
using namespace std;
//
// Hardware configuration
//
// CE Pin, CSN Pin, SPI Speed
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_8MHZ);
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
bool role_ping_out = 1, role_pong_back = 0;
bool role = 0;
const int min_payload_size = 4;
const int max_payload_size = 32;
const int payload_size_increments_by = 1;
int next_payload_size = min_payload_size;
char receive_payload[max_payload_size+1]; // +1 to allow room for a terminating NULL char
int main(int argc, char** argv){
// Print preamble:
printf("RF24/examples/pingpair_dyn/\n");
// Setup and configure rf radio
radio.begin();
radio.enableDynamicPayloads();
radio.setRetries(5,15);
radio.printDetails();
/********* Role chooser ***********/
printf("\n ************ Role Setup ***********\n");
string input = "";
char myChar = {0};
cout << "Choose a role: Enter 0 for receiver, 1 for transmitter (CTRL+C to exit) \n>";
getline(cin,input);
if(input.length() == 1) {
myChar = input[0];
if(myChar == '0'){
cout << "Role: Pong Back, awaiting transmission " << endl << endl;
}else{ cout << "Role: Ping Out, starting transmission " << endl << endl;
role = role_ping_out;
}
}
/***********************************/
if ( role == role_ping_out ) {
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
} else {
radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1,pipes[0]);
radio.startListening();
}
// forever loop
while (1)
{
if (role == role_ping_out)
{
// The payload will always be the same, what will change is how much of it we send.
static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012";
// First, stop listening so we can talk.
radio.stopListening();
// Take the time, and send it. This will block until complete
printf("Now sending length %i...",next_payload_size);
radio.write( send_payload, next_payload_size );
// Now, continue listening
radio.startListening();
// Wait here until we get a response, or timeout
unsigned long started_waiting_at = millis();
bool timeout = false;
while ( ! radio.available() && ! timeout )
if (millis() - started_waiting_at > 500 )
timeout = true;
// Describe the results
if ( timeout )
{
printf("Failed, response timed out.\n\r");
}
else
{
// Grab the response, compare, and send to debugging spew
uint8_t len = radio.getDynamicPayloadSize();
radio.read( receive_payload, len );
// Put a zero at the end for easy printing
receive_payload[len] = 0;
// Spew it
printf("Got response size=%i value=%s\n\r",len,receive_payload);
}
// Update size for next time.
next_payload_size += payload_size_increments_by;
if ( next_payload_size > max_payload_size )
next_payload_size = min_payload_size;
// Try again 1s later
delay(100);
}
//
// Pong back role. Receive each packet, dump it out, and send it back
//
if ( role == role_pong_back )
{
// if there is data ready
if ( radio.available() )
{
// Dump the payloads until we've gotten everything
uint8_t len;
while (radio.available())
{
// Fetch the payload, and see if this was the last one.
len = radio.getDynamicPayloadSize();
radio.read( receive_payload, len );
// Put a zero at the end for easy printing
receive_payload[len] = 0;
// Spew it
printf("Got payload size=%i value=%s\n\r",len,receive_payload);
}
// First, stop listening so we can talk
radio.stopListening();
// Send the final one back.
radio.write( receive_payload, len );
printf("Sent response.\n\r");
// Now, resume listening so we catch the next packets.
radio.startListening();
}
}
}
}
/*
TMRh20 2014
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
*/
/** General Data Transfer Rate Test
* This example demonstrates basic data transfer functionality with the
updated library. This example will display the transfer rates acheived using
the slower form of high-speed transfer using blocking-writes.
*/
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include "./RF24.h"
using namespace std;
//
// Hardware configuration
//
// CE Pin, CSN Pin, SPI Speed
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_8MHZ);
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t addresses[2] = { 0xABCDABCD71LL, 0x544d52687CLL };
bool role_ping_out = 1, role_pong_back = 0;
bool role = 0;
uint8_t data[32];
unsigned long startTime, stopTime, counter, rxTimer=0;
int main(int argc, char** argv){
// Print preamble:
printf("RF24/examples/Transfer/\n");
radio.begin(); // Setup and configure rf radio
radio.setChannel(1);
radio.setPALevel(RF24_PA_MAX);
radio.setDataRate(RF24_2MBPS);
radio.setAutoAck(1); // Ensure autoACK is enabled
radio.setRetries(2,15); // Optionally, increase the delay between retries & # of retries
radio.setCRCLength(RF24_CRC_8);
radio.printDetails();
/********* Role chooser ***********/
printf("\n ************ Role Setup ***********\n");
string input = "";
char myChar = {0};
cout << "Choose a role: Enter 0 for receiver, 1 for transmitter (CTRL+C to exit)\n>";
getline(cin,input);
if(input.length() == 1) {
myChar = input[0];
if(myChar == '0'){
cout << "Role: Pong Back, awaiting transmission " << endl << endl;
}else{ cout << "Role: Ping Out, starting transmission " << endl << endl;
role = role_ping_out;
}
}
/***********************************/
if ( role == role_ping_out ) {
radio.openWritingPipe(addresses[0]);
radio.openReadingPipe(1,addresses[1]);
} else {
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1,addresses[0]);
radio.startListening();
}
for(int i=0; i<32; i++){
data[i] = rand() % 255; //Load the buffer with random data
}
// forever loop
while (1){
if (role == role_ping_out){
sleep(2);
printf("Initiating Basic Data Transfer\n\r");
long int cycles = 10000; //Change this to a higher or lower number.
startTime = millis();
for(int i=0; i<cycles; i++){ //Loop through a number of cycles
data[0] = i; //Change the first byte of the payload for identification
if(!radio.writeFast(&data,32)){ //Write to the FIFO buffers
counter++; //Keep count of failed payloads
}
}
stopTime = millis();
if(!radio.txStandBy()){ counter+=3; }
float numBytes = cycles*32;
float rate = numBytes / (stopTime - startTime);
printf("Transfer complete at %.2f KB/s \n\r",rate);
printf("%lu of %lu Packets Failed to Send\n\r",counter,cycles);
counter = 0;
}
if(role == role_pong_back){
while(radio.available()){
radio.read(&data,32);
counter++;
}
if(millis() - rxTimer > 1000){
rxTimer = millis();
printf("Rate: ");
float numBytes = counter*32;
printf("%.2f KB/s \n\r",numBytes/1000);
printf("Payload Count: %lu \n\r", counter);
counter = 0;
}
}
} // loop
} // main
/*
Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de>
Portions Copyright (C) 2011 Greg Copeland
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/* 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
#define FEATURE 0x1D
/* Bit Mnemonics */
#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
#define ENAA_P5 5
#define ENAA_P4 4
#define ENAA_P3 3
#define ENAA_P2 2
#define ENAA_P1 1
#define ENAA_P0 0
#define ERX_P5 5
#define ERX_P4 4
#define ERX_P3 3
#define ERX_P2 2
#define ERX_P1 1
#define ERX_P0 0
#define AW 0
#define ARD 4
#define ARC 0
#define PLL_LOCK 4
#define RF_DR 3
#define RF_PWR 6
#define RX_DR 6
#define TX_DS 5
#define MAX_RT 4
#define RX_P_NO 1
#define TX_FULL 0
#define PLOS_CNT 4
#define ARC_CNT 0
#define TX_REUSE 6
#define FIFO_FULL 5
#define TX_EMPTY 4
#define RX_FULL 1
#define RX_EMPTY 0
#define DPL_P5 5
#define DPL_P4 4
#define DPL_P3 3
#define DPL_P2 2
#define DPL_P1 1
#define DPL_P0 0
#define EN_DPL 2
#define EN_ACK_PAY 1
#define EN_DYN_ACK 0
/* Instruction Mnemonics */
#define R_REGISTER 0x00
#define W_REGISTER 0x20
#define REGISTER_MASK 0x1F
#define ACTIVATE 0x50
#define R_RX_PL_WID 0x60
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0
#define W_ACK_PAYLOAD 0xA8
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define NOP 0xFF
/* Non-P omissions */
#define LNA_HCURR 0
/* P model memory Map */
#define RPD 0x09
#define W_TX_PAYLOAD_NO_ACK 0xB0
/* P model bit Mnemonics */
#define RF_DR_LOW 5
#define RF_DR_HIGH 3
#define RF_PWR_LOW 1
#define RF_PWR_HIGH 2
Optimized Raspberry Pi RF24 and RF24 Network Libraries
=============================================
General Documentation: http://tmrh20.github.io
Library functions are mostly the same.
See the included examples for RPi specific usage
##Raspberry Pi - PreConfig
####Possible pre-configuration:
If SPI is not already enabled, load it on boot:
```
sudo raspi-config
```
A. Update the tool via the menu as required
B. Select Advanced and enable the SPI kernel module
C. Update other software and libraries:
```
sudo apt-get update
sudo apt-get upgrade
```
RPi - RF24 Quick-Start
======================
A. Make a directory to contain the RF24 and possibly RF24Network lib and enter it:
```
mkdir ~/rf24libs
cd ~/rf24libs
```
B. Clone the RF24 Repo
```
git clone https://github.com/tmrh20/RF24.git rtemp
```
C. Copy the RPi library folder to the current directory, and delete the rest
```
mv rtemp/RPi/RF24 ./
rm -r rtemp
cd RF24
```
D. Build the library, and run an example file:
```
sudo make
cd examples
sudo make
sudo ./gettingstarted
```
RPi - RF24Network Quick-Start
=============================
A. Enter the same directory that contains the RF24 library folder
```
cd ~/rf24libs
```
B. Clone the RF24Network Repo
```
git clone https://github.com/tmrh20/RF24Network.git ntemp
```
C. Copy the RF24Network folder to the current directory, and delete the rest
```
mv rtemp/RPi/RF24Network ./
rm -r ntemp
cd RF24Network
```
D. Build the library
```
sudo make
cd examples
sudo make
sudo ./helloworld_rx OR sudo ./helloworld_tx
```
Connection Info
===============
Using pin 15/GPIO 22 for CE, pin 24/GPIO8 (CE0) for CSN
**Constructor:**
```
RF24 radio(RPI_V2_GPIO_P1_15,BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);
```
**Pins:**
|NRF24L01 | RPI | P1 Connector |
|----- |----------- | -------------|
|VCC: | rpi-3v3 | (17) |
|GND: | rpi-gnd | (25) |
|CE: | rpi-gpio22 | (15) |
|CSN: | rpi-gpio8 | (24) |
|SCK: | rpi-sckl | (23) |
|MOSI: | rpi-mosi | (19) |
|MISO: | rpi-miso | (21) |
****************
Based on the arduino lib from J. Coliz <maniacbug@ymail.com>.
the library was berryfied by Purinda Gunasekara <purinda@gmail.com>.
then forked from github stanleyseow/RF24 to https://github.com/jscrane/RF24-rpi
Network lib also based on https://github.com/farconada/RF24Network
Currently optimized and aligned with Arduino fork of libraries by TMRh20:
https://github.com/tmrh20/RF24/RPi and https://github.com/tmrh20/RF24Network/RPi
Documentation: http://tmrh20.github.io
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment