Implement dynamic payloads, with an example

This commit is contained in:
maniacbug 2011-07-10 08:00:58 -07:00
parent 98fbd44111
commit 63eb62ebc3
3 changed files with 96 additions and 34 deletions

View File

@ -111,11 +111,11 @@ uint8_t RF24::write_payload(const void* buf, uint8_t len)
csn(LOW);
status = SPI.transfer( W_TX_PAYLOAD );
uint8_t data_len = min(len,payload_size);
uint8_t blank_len = payload_size - data_len;
//uint8_t blank_len = payload_size - data_len;
while ( data_len-- )
SPI.transfer(*current++);
while ( blank_len-- )
SPI.transfer(0);
//while ( blank_len-- )
// SPI.transfer(0);
csn(HIGH);
@ -132,11 +132,11 @@ uint8_t RF24::read_payload(void* buf, uint8_t len)
csn(LOW);
status = SPI.transfer( R_RX_PAYLOAD );
uint8_t data_len = min(len,payload_size);
uint8_t blank_len = payload_size - data_len;
//uint8_t blank_len = payload_size - data_len;
while ( data_len-- )
*current++ = SPI.transfer(0xff);
while ( blank_len-- )
SPI.transfer(0xff);
//while ( blank_len-- )
// SPI.transfer(0xff);
csn(HIGH);
return status;
@ -396,7 +396,7 @@ boolean RF24::write( const void* buf, uint8_t len )
// Handle the ack packet
if ( ack_payload_available )
{
ack_payload_length = read_payload_length();
ack_payload_length = getDynamicPayloadSize();
IF_SERIAL_DEBUG(Serial.print("[AckPacket]/"));
IF_SERIAL_DEBUG(Serial.println(ack_payload_length,DEC));
}
@ -430,7 +430,7 @@ void RF24::startWrite( const void* buf, uint8_t len )
/******************************************************************/
uint8_t RF24::read_payload_length(void)
uint8_t RF24::getDynamicPayloadSize(void)
{
uint8_t result = 0;
@ -577,6 +577,30 @@ void RF24::toggle_features(void)
/******************************************************************/
void RF24::enableDynamicPayloads(void)
{
// Enable dynamic payload throughout the system
write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) );
// If it didn't work, the features are not enabled
if ( ! read_register(FEATURE) )
{
// So enable them and try again
toggle_features();
write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) );
}
IF_SERIAL_DEBUG(printf("FEATURE=%i\n\r",read_register(FEATURE)));
// Enable dynamic payload on all pipes
//
// Not sure the use case of only having dynamic payload on certain
// pipes, so the library does not support it.
write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P5) | _BV(DPL_P4) | _BV(DPL_P3) | _BV(DPL_P2) | _BV(DPL_P1) | _BV(DPL_P0));
}
/******************************************************************/
void RF24::enableAckPayload(void)
{
//
@ -596,7 +620,7 @@ void RF24::enableAckPayload(void)
IF_SERIAL_DEBUG(printf("FEATURE=%i\n\r",read_register(FEATURE)));
//
// Enable dynamic payload on pipe 0
// Enable dynamic payload on pipes 0 & 1
//
write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P1) | _BV(DPL_P0));

34
RF24.h
View File

@ -112,16 +112,6 @@ protected:
*/
uint8_t read_payload(void* buf, uint8_t len);
/**
* Read the payload length
*
* For dynamic payloads, this pulls the size of the payload off
* the chip
*
* @return Payload length of last-received dynamic payload
*/
uint8_t read_payload_length(void);
/**
* Empty the receive buffer
*
@ -352,7 +342,7 @@ public:
void setChannel(uint8_t channel);
/**
* Set Payload Size
* Set Static Payload Size
*
* This implementation uses a pre-stablished fixed payload size for all
* transmissions. If this method is never called, the driver will always
@ -366,7 +356,7 @@ public:
void setPayloadSize(uint8_t size);
/**
* Get Payload Size
* Get Static Payload Size
*
* @see setPayloadSize()
*
@ -374,6 +364,16 @@ public:
*/
uint8_t getPayloadSize(void);
/**
* Get Dynamic Payload Size
*
* For dynamic payloads, this pulls the size of the payload off
* the chip
*
* @return Payload length of last-received dynamic payload
*/
uint8_t getDynamicPayloadSize(void);
/**
* Print a giant block of debugging information to stdout
*
@ -425,6 +425,16 @@ public:
*/
void enableAckPayload(void);
/**
* Enable dynamically-sized payloads
*
* This way you don't always have to send large packets just to send them
* once in a while. This enables dynamic payloads on ALL pipes.
*
* @see examples/pingpair_pl/pingpair_dyn.pde
*/
void enableDynamicPayloads(void);
/**
* Write an ack payload for the specified pipe
*

View File

@ -55,6 +55,17 @@ const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};
// The role of the current running sketch
role_e role;
//
// Payload
//
const int min_payload_size = 4;
const int max_payload_size = 32;
const int payload_size_increments_by = 2;
int next_payload_size = min_payload_size;
char receive_payload[max_payload_size+1]; // +1 to allow room for a terminating NULL char
void setup(void)
{
//
@ -87,6 +98,9 @@ void setup(void)
radio.begin();
// enable dynamic payloads
radio.enableDynamicPayloads();
// optionally, increase the delay between retries & # of retries
radio.setRetries(15,15);
@ -137,22 +151,24 @@ void loop(void)
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
unsigned long time = millis();
printf("Now sending %lu...",time);
radio.write( &time, sizeof(unsigned long) );
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 (250ms)
// 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 > 250 )
if (millis() - started_waiting_at > 500 )
timeout = true;
// Describe the results
@ -163,13 +179,21 @@ void loop(void)
else
{
// Grab the response, compare, and send to debugging spew
unsigned long got_time;
radio.read( &got_time, sizeof(unsigned long) );
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 %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
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(1000);
}
@ -184,22 +208,26 @@ void loop(void)
if ( radio.available() )
{
// Dump the payloads until we've gotten everything
unsigned long got_time;
uint8_t len;
boolean done = false;
while (!done)
{
// Fetch the payload, and see if this was the last one.
done = radio.read( &got_time, sizeof(unsigned long) );
len = radio.getDynamicPayloadSize();
done = radio.read( receive_payload, len );
// Put a zero at the end for easy printing
receive_payload[len] = 0;
// Spew it
printf("Got payload %lu...",got_time);
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( &got_time, sizeof(unsigned long) );
radio.write( receive_payload, len );
printf("Sent response.\n\r");
// Now, resume listening so we catch the next packets.