From 63eb62ebc3a69f4f549532c493ce48cdfa0a8928 Mon Sep 17 00:00:00 2001 From: maniacbug Date: Sun, 10 Jul 2011 08:00:58 -0700 Subject: [PATCH] Implement dynamic payloads, with an example --- RF24.cpp | 42 +++++++++++++++----- RF24.h | 34 ++++++++++------ examples/pingpair_dyn/pingpair_dyn.pde | 54 +++++++++++++++++++------- 3 files changed, 96 insertions(+), 34 deletions(-) diff --git a/RF24.cpp b/RF24.cpp index 14cf9e5..24e5fc8 100644 --- a/RF24.cpp +++ b/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)); diff --git a/RF24.h b/RF24.h index 4e7fb79..58a4a92 100644 --- a/RF24.h +++ b/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 * diff --git a/examples/pingpair_dyn/pingpair_dyn.pde b/examples/pingpair_dyn/pingpair_dyn.pde index 7a70469..3ee7c86 100644 --- a/examples/pingpair_dyn/pingpair_dyn.pde +++ b/examples/pingpair_dyn/pingpair_dyn.pde @@ -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.