Implement dynamic payloads, with an example
This commit is contained in:
parent
98fbd44111
commit
63eb62ebc3
42
RF24.cpp
42
RF24.cpp
|
@ -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
34
RF24.h
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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,12 +179,20 @@ 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 );
|
||||
|
||||
// Spew it
|
||||
printf("Got payload %lu...",got_time);
|
||||
// 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( &got_time, sizeof(unsigned long) );
|
||||
radio.write( receive_payload, len );
|
||||
printf("Sent response.\n\r");
|
||||
|
||||
// Now, resume listening so we catch the next packets.
|
||||
|
|
Loading…
Reference in New Issue