Hi
Catha is right. The Tx done interrupt flag appears not to get cleared the first time. When you clear them a second time they are.
Rather then skinning my software I realized that one of the differences with rf95_client is that there
Code:
rf95.waitPacketSent()
is called directly after the call to
Code:
rf95.send(data, sizeof(data))
In my code I'm not doing that since I intend to transmit only once a minute and the function
Code:
rf95.send(data, sizeof(data))
starts with the same function anyway
Code:
bool RH_RF95::send(const uint8_t* data, uint8_t len)
{
if (len > RH_RF95_MAX_MESSAGE_LEN)
return false;
waitPacketSent(); // Make sure we dont interrupt an outgoing message
That makes the call to
Code:
rf95.waitPacketSent()
in rf95_client superfluous but possibly also the reason why the example code works.
Skinning the rf95_client example code to the bone you get.
(Note only a iterations counter got added and the total delay in loop was shortened from 3000+400 ms to 1000ms to save some time.)
Code:
// rf95_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messageing client
// with the RH_RF95 class. RH_RF95 class does not provide for addressing or
// reliability, so you should only use RH_RF95 if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example rf95_server
// Tested with Anarduino MiniWirelessLoRa, Rocket Scream Mini Ultra Pro with
// the RFM95W, Adafruit Feather M0 with RFM95
#include <SPI.h>
#include <RH_RF95.h>
// Singleton instance of the radio driver
RH_RF95 rf95(10,2); // Teensy 3.5
uint16_t iterations;
void setup()
{
Serial.begin(9600);
while (!Serial) ; // Wait for serial port to be available
if (!rf95.init())
Serial.println("init failed");
iterations = 1; //humans start at 1 :-)
}
void loop()
{
//debug
Serial.print (iterations);
// debug end
Serial.println(" Sending to rf95_server");
//debug
iterations++;
//debug end
// Send a message to rf95_server
uint8_t data[] = "Hello World!";
rf95.send(data, sizeof(data));
/*
rf95.waitPacketSent();
// Now wait for a reply
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf95.waitAvailableTimeout(1000))
{
// Should be a reply message for us now
if (rf95.recv(buf, &len))
{
Serial.print("got reply: ");
Serial.println((char*)buf);
// Serial.print("RSSI: ");
// Serial.println(rf95.lastRssi(), DEC);
}
else
{
Serial.println("recv failed");
}
}
else
{
Serial.println("No reply, is rf95_server running?");
}
*/
delay(1000);
}
This code does reliably lockup after 1 iteration through loop().
Then modifications to RH_RF95.cpp showed indeed that the Tx done IRQ flag appears to get cleared only the second time you bang it.
Here is the relavant piece of RF_RF95.cpp
Code:
void RH_RF95::handleInterrupt()
{
// Read the interrupt register
// Serial.println("RH_RF95.cpp: RH_RF95::handleInterrupt");
uint8_t irq_flags = spiRead(RH_RF95_REG_12_IRQ_FLAGS);
Serial.print("i1 "); Serial.println(_mode<<8 | irq_flags, HEX); // DEBUG: output _mode & irq flags
//Serial.print ("irq_flags (reg 0x12) = ");
//Serial.println(irq_flags, HEX);
if (_mode == RHModeRx && irq_flags & (RH_RF95_RX_TIMEOUT | RH_RF95_PAYLOAD_CRC_ERROR))
{
_rxBad++;
}
else if (_mode == RHModeRx && irq_flags & RH_RF95_RX_DONE)
{
// Have received a packet
uint8_t len = spiRead(RH_RF95_REG_13_RX_NB_BYTES);
// Reset the fifo read ptr to the beginning of the packet
spiWrite(RH_RF95_REG_0D_FIFO_ADDR_PTR, spiRead(RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR));
spiBurstRead(RH_RF95_REG_00_FIFO, _buf, len);
_bufLen = len;
//debug
Serial.print("i2 "); Serial.println(_mode<<8 | irq_flags, HEX); // DEBUG: output _mode & irq flags
//debug end
spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags
// debug
uint8_t debug_pim = spiRead(RH_RF95_REG_12_IRQ_FLAGS);
Serial.print("i3 "); Serial.println(_mode<<8 | debug_pim, HEX); // DEBUG: output _mode & irq flags
// debug end
// debug
// Clear IRQ flags again.
spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags
// and read them back
debug_pim = spiRead(RH_RF95_REG_12_IRQ_FLAGS);
Serial.print("i4 "); Serial.println(_mode<<8 | debug_pim, HEX); // DEBUG: output _mode & irq flags
// debug end
// Remember the RSSI of this packet
// this is according to the doc, but is it really correct?
// weakest receiveable signals are reported RSSI at about -66
_lastRssi = spiRead(RH_RF95_REG_1A_PKT_RSSI_VALUE) - 137;
// We have received a message.
validateRxBuf();
if (_rxBufValid)
setModeIdle(); // Got one
}
else if (_mode == RHModeTx && irq_flags & RH_RF95_TX_DONE)
{
_txGood++;
setModeIdle();
}
//debug
Serial.print("i5 "); Serial.println(_mode<<8 | irq_flags, HEX); // DEBUG: output _mode & irq flags
//debug end
spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags
// debug
uint8_t debug_pim = spiRead(RH_RF95_REG_12_IRQ_FLAGS);
Serial.print("i6 "); Serial.println(_mode<<8 | debug_pim, HEX); // DEBUG: output _mode & irq flags
// debug end
// debug
// Clear IRQ flags again.
spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags
// and read them back
debug_pim = spiRead(RH_RF95_REG_12_IRQ_FLAGS);
Serial.print("i7 "); Serial.println(_mode<<8 | debug_pim, HEX); // DEBUG: output _mode & irq flags
// debug end
And here is the edited debug output.
1 Sending to rf95_server
i1 308
i5 208
i6 208 (This should be 200 now)
i7 200 (like this)
So, why is this happening?
On to the spiWrite and spiRead functions I guess
To be continued tomorrow.
Pim