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);
|
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
34
RF24.h
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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,13 +179,21 @@ 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 );
|
||||||
|
|
||||||
|
// Put a zero at the end for easy printing
|
||||||
|
receive_payload[len] = 0;
|
||||||
|
|
||||||
// Spew it
|
// 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
|
// 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.
|
||||||
|
|
Loading…
Reference in New Issue