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); csn(LOW);
status = SPI.transfer( W_TX_PAYLOAD ); status = SPI.transfer( W_TX_PAYLOAD );
uint8_t data_len = min(len,payload_size); 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-- ) while ( data_len-- )
SPI.transfer(*current++); SPI.transfer(*current++);
while ( blank_len-- ) //while ( blank_len-- )
SPI.transfer(0); // SPI.transfer(0);
csn(HIGH); csn(HIGH);
@ -132,11 +132,11 @@ uint8_t RF24::read_payload(void* buf, uint8_t len)
csn(LOW); csn(LOW);
status = SPI.transfer( R_RX_PAYLOAD ); status = SPI.transfer( R_RX_PAYLOAD );
uint8_t data_len = min(len,payload_size); 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-- ) while ( data_len-- )
*current++ = SPI.transfer(0xff); *current++ = SPI.transfer(0xff);
while ( blank_len-- ) //while ( blank_len-- )
SPI.transfer(0xff); // SPI.transfer(0xff);
csn(HIGH); csn(HIGH);
return status; return status;
@ -396,7 +396,7 @@ boolean RF24::write( const void* buf, uint8_t len )
// Handle the ack packet // Handle the ack packet
if ( ack_payload_available ) if ( ack_payload_available )
{ {
ack_payload_length = read_payload_length(); ack_payload_length = getDynamicPayloadSize();
IF_SERIAL_DEBUG(Serial.print("[AckPacket]/")); IF_SERIAL_DEBUG(Serial.print("[AckPacket]/"));
IF_SERIAL_DEBUG(Serial.println(ack_payload_length,DEC)); 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; 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) void RF24::enableAckPayload(void)
{ {
// //
@ -596,7 +620,7 @@ void RF24::enableAckPayload(void)
IF_SERIAL_DEBUG(printf("FEATURE=%i\n\r",read_register(FEATURE))); 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)); 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); 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 * Empty the receive buffer
* *
@ -352,7 +342,7 @@ public:
void setChannel(uint8_t channel); void setChannel(uint8_t channel);
/** /**
* Set Payload Size * Set Static Payload Size
* *
* This implementation uses a pre-stablished fixed payload size for all * This implementation uses a pre-stablished fixed payload size for all
* transmissions. If this method is never called, the driver will always * transmissions. If this method is never called, the driver will always
@ -366,7 +356,7 @@ public:
void setPayloadSize(uint8_t size); void setPayloadSize(uint8_t size);
/** /**
* Get Payload Size * Get Static Payload Size
* *
* @see setPayloadSize() * @see setPayloadSize()
* *
@ -374,6 +364,16 @@ public:
*/ */
uint8_t getPayloadSize(void); 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 * Print a giant block of debugging information to stdout
* *
@ -425,6 +425,16 @@ public:
*/ */
void enableAckPayload(void); 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 * 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 // The role of the current running sketch
role_e role; 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) void setup(void)
{ {
// //
@ -87,6 +98,9 @@ void setup(void)
radio.begin(); radio.begin();
// enable dynamic payloads
radio.enableDynamicPayloads();
// optionally, increase the delay between retries & # of retries // optionally, increase the delay between retries & # of retries
radio.setRetries(15,15); radio.setRetries(15,15);
@ -137,22 +151,24 @@ void loop(void)
if (role == role_ping_out) 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. // First, stop listening so we can talk.
radio.stopListening(); radio.stopListening();
// Take the time, and send it. This will block until complete // Take the time, and send it. This will block until complete
unsigned long time = millis(); printf("Now sending length %i...",next_payload_size);
printf("Now sending %lu...",time); radio.write( send_payload, next_payload_size );
radio.write( &time, sizeof(unsigned long) );
// Now, continue listening // Now, continue listening
radio.startListening(); 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(); unsigned long started_waiting_at = millis();
bool timeout = false; bool timeout = false;
while ( ! radio.available() && ! timeout ) while ( ! radio.available() && ! timeout )
if (millis() - started_waiting_at > 250 ) if (millis() - started_waiting_at > 500 )
timeout = true; timeout = true;
// Describe the results // Describe the results
@ -163,12 +179,20 @@ void loop(void)
else else
{ {
// Grab the response, compare, and send to debugging spew // Grab the response, compare, and send to debugging spew
unsigned long got_time; uint8_t len = radio.getDynamicPayloadSize();
radio.read( &got_time, sizeof(unsigned long) ); radio.read( receive_payload, len );
// Put a zero at the end for easy printing
receive_payload[len] = 0;
// Spew it // 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 // Try again 1s later
delay(1000); delay(1000);
@ -184,22 +208,26 @@ void loop(void)
if ( radio.available() ) if ( radio.available() )
{ {
// Dump the payloads until we've gotten everything // Dump the payloads until we've gotten everything
unsigned long got_time; uint8_t len;
boolean done = false; boolean done = false;
while (!done) while (!done)
{ {
// Fetch the payload, and see if this was the last one. // 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 );
// Spew it // Put a zero at the end for easy printing
printf("Got payload %lu...",got_time); 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 // First, stop listening so we can talk
radio.stopListening(); radio.stopListening();
// Send the final one back. // Send the final one back.
radio.write( &got_time, sizeof(unsigned long) ); radio.write( receive_payload, len );
printf("Sent response.\n\r"); printf("Sent response.\n\r");
// Now, resume listening so we catch the next packets. // Now, resume listening so we catch the next packets.