Created a non-blocking write and an example for how to use it.
This commit is contained in:
parent
bb37e88094
commit
d3fff68a7c
33
RF24.cpp
33
RF24.cpp
|
@ -356,17 +356,8 @@ boolean RF24::write( const void* buf, uint8_t len )
|
|||
{
|
||||
boolean result = false;
|
||||
|
||||
// Transmitter power-up
|
||||
write_register(CONFIG, ( read_register(CONFIG) | _BV(PWR_UP) ) & ~_BV(PRIM_RX) );
|
||||
delay(2);
|
||||
|
||||
// Send the payload
|
||||
write_payload( buf, len );
|
||||
|
||||
// Allons!
|
||||
ce(HIGH);
|
||||
delayMicroseconds(15);
|
||||
ce(LOW);
|
||||
// Begin the write
|
||||
startWrite(buf,len);
|
||||
|
||||
// ------------
|
||||
// At this point we could return from a non-blocking write, and then call
|
||||
|
@ -379,7 +370,7 @@ boolean RF24::write( const void* buf, uint8_t len )
|
|||
uint8_t observe_tx;
|
||||
uint8_t status;
|
||||
uint32_t sent_at = millis();
|
||||
const uint32_t timeout = 100; //ms to wait for timeout
|
||||
const uint32_t timeout = 500; //ms to wait for timeout
|
||||
do
|
||||
{
|
||||
status = read_register(OBSERVE_TX,&observe_tx,1);
|
||||
|
@ -420,6 +411,22 @@ boolean RF24::write( const void* buf, uint8_t len )
|
|||
|
||||
return result;
|
||||
}
|
||||
/******************************************************************/
|
||||
|
||||
void RF24::startWrite( const void* buf, uint8_t len )
|
||||
{
|
||||
// Transmitter power-up
|
||||
write_register(CONFIG, ( read_register(CONFIG) | _BV(PWR_UP) ) & ~_BV(PRIM_RX) );
|
||||
delay(2);
|
||||
|
||||
// Send the payload
|
||||
write_payload( buf, len );
|
||||
|
||||
// Allons!
|
||||
ce(HIGH);
|
||||
delayMicroseconds(15);
|
||||
ce(LOW);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
|
@ -507,6 +514,8 @@ void RF24::whatHappened(bool& tx_ok,bool& tx_fail,bool& rx_ready)
|
|||
tx_ok = status & _BV(TX_DS);
|
||||
tx_fail = status & _BV(MAX_RT);
|
||||
rx_ready = status & _BV(RX_DR);
|
||||
|
||||
//print_status(status);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
|
18
RF24.h
18
RF24.h
|
@ -252,9 +252,6 @@ public:
|
|||
* getPayloadSize(). However, you can write less, and the remainder
|
||||
* will just be filled with zeroes.
|
||||
*
|
||||
* @todo Write a non-blocking write to support users who want to
|
||||
* check on progress separately or use an interrupt.
|
||||
*
|
||||
* @param buf Pointer to the data to be sent
|
||||
* @param len Number of bytes to be sent
|
||||
* @return True if the payload was delivered successfully false if not
|
||||
|
@ -403,6 +400,21 @@ public:
|
|||
*/
|
||||
boolean available(uint8_t* pipe_num);
|
||||
|
||||
/**
|
||||
* Non-blocking write to the open writing pipe
|
||||
*
|
||||
* Just like write(), but it returns immediately. To find out what happened
|
||||
* to the send, catch the IRQ and then call whatHappened().
|
||||
*
|
||||
* @see write()
|
||||
* @see whatHappened()
|
||||
*
|
||||
* @param buf Pointer to the data to be sent
|
||||
* @param len Number of bytes to be sent
|
||||
* @return True if the payload was delivered successfully false if not
|
||||
*/
|
||||
void startWrite( const void* buf, uint8_t len );
|
||||
|
||||
/**
|
||||
* Enable custom payloads on the acknowledge packets
|
||||
*
|
||||
|
|
|
@ -7,12 +7,10 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Example of using Ack Payloads
|
||||
* Example of using interrupts
|
||||
*
|
||||
* This is an example of how to do two-way communication without changing
|
||||
* transmit/receive modes. Here, a payload is set to the transmitter within
|
||||
* the Ack packet of each transmission. Note that the payload is set BEFORE
|
||||
* the sender's message arrives.
|
||||
* This is an example of how to user interrupts to interact with the radio.
|
||||
* It builds on the pingpair_pl example, and uses ack payloads.
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
|
@ -58,6 +56,13 @@ const char* role_friendly_name[] = { "invalid", "Sender", "Receiver"};
|
|||
// The role of the current running sketch
|
||||
role_e role;
|
||||
|
||||
// Message buffer to allow interrupt handler to print messages
|
||||
bool message_ready;
|
||||
char message[100];
|
||||
|
||||
// Interrupt handler, check the radio because we got an IRQ
|
||||
void check_radio(void);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
|
@ -81,9 +86,15 @@ void setup(void)
|
|||
|
||||
Serial.begin(57600);
|
||||
printf_begin();
|
||||
printf("\n\rRF24/examples/pingpair_pl/\n\r");
|
||||
printf("\n\rRF24/examples/pingpair_irq/\n\r");
|
||||
printf("ROLE: %s\n\r",role_friendly_name[role]);
|
||||
|
||||
//
|
||||
// Attach interrupt handler to interrupt #0 (using pin 2)
|
||||
//
|
||||
|
||||
attachInterrupt(0, check_radio, FALLING);
|
||||
|
||||
//
|
||||
// Setup and configure rf radio
|
||||
//
|
||||
|
@ -93,6 +104,9 @@ void setup(void)
|
|||
// We will be using the Ack Payload feature, so please enable it
|
||||
radio.enableAckPayload();
|
||||
|
||||
// Pick a high channel
|
||||
radio.setChannel(110);
|
||||
|
||||
//
|
||||
// Open pipes to other nodes for communication
|
||||
//
|
||||
|
@ -123,9 +137,10 @@ void setup(void)
|
|||
radio.printDetails();
|
||||
}
|
||||
|
||||
static uint32_t message_count = 0;
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
static uint32_t message_count = 0;
|
||||
|
||||
//
|
||||
// Sender role. Repeatedly send the current time
|
||||
|
@ -133,17 +148,10 @@ void loop(void)
|
|||
|
||||
if (role == role_sender)
|
||||
{
|
||||
// Take the time, and send it. This will block until complete
|
||||
// Take the time, and send it.
|
||||
unsigned long time = millis();
|
||||
printf("Now sending %lu...",time);
|
||||
radio.write( &time, sizeof(unsigned long) );
|
||||
|
||||
if ( radio.isAckPayloadAvailable() )
|
||||
{
|
||||
radio.read(&message_count,sizeof(message_count));
|
||||
printf("Ack: [%lu] ",message_count);
|
||||
}
|
||||
printf("OK\n\r");
|
||||
radio.startWrite( &time, sizeof(unsigned long) );
|
||||
|
||||
// Try again soon
|
||||
delay(2000);
|
||||
|
@ -176,5 +184,47 @@ void loop(void)
|
|||
++message_count;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Message handler. Display messages from the interrupt
|
||||
//
|
||||
if ( message_ready )
|
||||
{
|
||||
message_ready = false;
|
||||
Serial.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
void check_radio(void)
|
||||
{
|
||||
// What happened?
|
||||
bool tx,fail,rx;
|
||||
radio.whatHappened(tx,fail,rx);
|
||||
|
||||
char *messageptr = message;
|
||||
message_ready = true;
|
||||
sprintf(message,"Unknown");
|
||||
|
||||
if ( tx )
|
||||
{
|
||||
radio.powerDown();
|
||||
sprintf(messageptr,"Send:OK ");
|
||||
messageptr += strlen(messageptr);
|
||||
}
|
||||
|
||||
if ( fail )
|
||||
{
|
||||
radio.powerDown();
|
||||
sprintf(messageptr,"Send:Failed ");
|
||||
messageptr += strlen(messageptr);
|
||||
}
|
||||
|
||||
if ( rx )
|
||||
{
|
||||
radio.read(&message_count,sizeof(message_count));
|
||||
sprintf(messageptr,"Ack:%lu ",message_count);
|
||||
messageptr += strlen(messageptr);
|
||||
}
|
||||
}
|
||||
|
||||
// vim:ai:cin:sts=2 sw=2 ft=cpp
|
||||
|
|
Loading…
Reference in New Issue