Added self-healing ping offset to leaf node. Made timeout more parallelized

This commit is contained in:
maniacbug 2011-05-13 20:16:54 -07:00
parent 52ab9e0081
commit 7b71380278
1 changed files with 50 additions and 31 deletions

View File

@ -163,8 +163,11 @@ void payload_printf(const char* name, const payload_t& pl)
// Setup/loop shared statics // Setup/loop shared statics
// //
static unsigned long last_ping_time; static unsigned long last_ping_sent_at;
const unsigned long ping_delay = 2000; static bool waiting_for_pong = false;
const unsigned long ping_delay = 2000; // ms
const unsigned long pong_timeout = 250; // ms
const unsigned long ping_phase_shift = 100; // ms
void setup(void) void setup(void)
{ {
@ -305,9 +308,10 @@ void loop(void)
{ {
// Is it time to ping again? // Is it time to ping again?
unsigned long now = millis(); unsigned long now = millis();
if ( now - last_ping_time >= ping_delay ) if ( now - last_ping_sent_at >= ping_delay )
{ {
last_ping_time = now; last_ping_sent_at = now;
waiting_for_pong = true;
// First, stop listening so we can talk. // First, stop listening so we can talk.
radio.stopListening(); radio.stopListening();
@ -315,40 +319,55 @@ void loop(void)
// Take the time, and send it to the base. This will block until complete // Take the time, and send it to the base. This will block until complete
payload_t ping(node_address,0,millis()); payload_t ping(node_address,0,millis());
// Print details.
printf("%lu ",millis()); printf("%lu ",millis());
payload_printf("PING",ping); payload_printf(">PING",ping);
bool ok = radio.write( &ping, sizeof(payload_t) ); bool ok = radio.write( &ping, sizeof(payload_t) );
if (ok) if (ok)
printf(" ok "); printf(" ok\n\r");
else else
printf(" failed "); printf(" failed\n\r");
// Now, continue listening // Now, continue listening
radio.startListening(); radio.startListening();
}
// Wait here until we get a response, or timeout (250ms) // Did we get a pong?
unsigned long started_waiting_at = millis(); if ( radio.available() )
bool timeout = false; {
while ( ! radio.available() && ! timeout ) // Not waiting anymore, got one.
if (millis() - started_waiting_at > 250 ) waiting_for_pong = false;
timeout = true;
// Describe the results // Dump the payloads until we've gotten everything
if ( timeout ) payload_t payload;
boolean done = false;
while (!done)
{ {
printf("Failed, response timed out.\n\r"); // Fetch the payload, and see if this was the last one.
} done = radio.read( &payload, sizeof(payload_t) );
else
{
// Grab the response, compare, and send to debugging spew
payload_t pong;
radio.read( &pong, sizeof(payload_t) );
// Spew it // Print details.
payload_printf(" ...PONG",pong); printf("%lu ",millis());
printf(" Round-trip delay: %lu\n\r",millis()-pong.time); payload_printf(">PONG",payload);
printf(" Round-trip delay: %lu\n\r",millis()-payload.time);
} }
} }
// Have we timed out waiting for our pong?
if ( waiting_for_pong && ( millis() - last_ping_sent_at > pong_timeout ) )
{
// Not waiting anymore, timed out.
waiting_for_pong = false;
// Timeouts usually happen because of collisions with other nodes
// getting a pong just as we are trying to get a ping. The best thing
// to do right now is offset our ping timing to search for a slot
// that's not occupied.
last_ping_sent_at += ping_phase_shift;
// Print details
printf("TIMED OUT.\n\r");
}
} }
// //
@ -413,9 +432,9 @@ void loop(void)
// Is it time to ping again? // Is it time to ping again?
unsigned long now = millis(); unsigned long now = millis();
if ( now - last_ping_time >= ping_delay ) if ( now - last_ping_sent_at >= ping_delay )
{ {
last_ping_time = now; last_ping_sent_at = now;
// First, stop listening so we can talk. // First, stop listening so we can talk.
radio.stopListening(); radio.stopListening();