I think I have found the source of my problem.
The RF24 library has quite a few 'print' statements in it for debugging, etc. It defines its own PSTR to accomplish those printouts. There is some difficulty with using them when other SPI devices are in use. On the surface, it sounds absurd to make such a claim, but by using just the data acquisition methods of the RF24 class, all seems well.
Based on my limited c++ expertise, it seems the RF24 library defines PSTR and some other statements that ought to be the equivalent of the F() function from the Wire library which SurferTim's code example -- however, it directly conflicts with what RF24 does. I was not able to comprehend these mechanisms for using ProgMem well enough to 'fix' RF24 so it also used F().
Regardless, my test sketch hums along nicely without calling the RF24 printDetails() (which I had been using as a way to tell when it 'locks up'). Persumably as long as I steer clear of using any of the RF24 'print' statements, my code will work fine.
For future reference, this is the code I have been running for hours now without any (apparent) problems:
/*
Web server sketch for IDE v1.0.1 and w5100/w5200
Posted October 2012 by SurferTim
*/
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(8, 7);
uint64_t pipe = 0xF0F0F0F0E1LL;
uint16_t i = 0;
int data_rate = 0;
bool tx_ok;
bool tx_fail;
bool rx_ready;
// this must be unique
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEC };
char payload[32];
// change to your network settings
IPAddress ip( 192,168,0,11 );
IPAddress gateway( 192,168,0,1 );
IPAddress subnet( 255,255,255,0 );
EthernetServer server(80);
void setup()
{
Serial.begin(9600);
// disable w5100 while setting up SD
// uncomment next 5 lines if using a microSD card
// pinMode(10,OUTPUT);
// digitalWrite(10,HIGH);
// Serial.print("Starting SD..");
// if(!SD.begin(4)) Serial.println("failed");
// else Serial.println("ok");
Ethernet.begin(mac, ip, gateway, gateway, subnet);
digitalWrite(10,HIGH);
delay(2000);
server.begin();
Serial.println("Ready");
radio.begin();
// optionally, increase the delay between retries & # of retries
radio.setRetries(15,15);
// optionally, reduce the payload size. seems to
// improve reliability
radio.setPayloadSize(32);
//
// Open pipe to other node for communication
//
radio.openReadingPipe(1,pipe);
//
// Start listening
//
radio.startListening();
radio.printDetails();
Serial.println("Radio ready");}
void loop()
{
EthernetClient client = server.available();
if(client) {
boolean currentLineIsBlank = true;
boolean currentLineIsGet = true;
int tCount = 0;
char tBuf[64];
int r,t;
char *pch;
Serial.print("Client request: ");
while (client.connected()) {
while(client.available()) {
char c = client.read();
if(currentLineIsGet && tCount < 63)
{
tBuf[tCount] = c;
tCount++;
tBuf[tCount] = 0;
}
if (c == '\n' && currentLineIsBlank) {
// send a standard http response
Serial.println(tBuf);
Serial.print("POST data: ");
while(client.available()) Serial.write(client.read());
Serial.println();
pch = strtok(tBuf,"?");
while(pch != NULL)
{
if(strncmp(pch,"t=",2) == 0)
{
t = atoi(pch+2);
Serial.print("t=");
Serial.println(t,DEC);
}
if(strncmp(pch,"r=",2) == 0)
{
r = atoi(pch+2);
Serial.print("r=");
Serial.println(r,DEC);
}
pch = strtok(NULL,"& ");
}
Serial.println("Sending response");
client.print("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<html>");
client.print("<head><script type=\"text/javascript\">");
client.print("setInterval(function(){document.forms[0].submit()},1000);");
client.print("function show_alert() {alert(\"This is an alert\");}");
client.print("</script></head");
client.print("<body><H1>TEST</H1>");
client.print("<form method=GET onSubmit=\"show_alert()\">T: <input type=text name=t value=\""); client.print(data_rate); client.print("\">
");
client.print("R: <input type=text name=r value=\""); client.print(millis()); client.print("\">
<input type=submit></form>");
data_rate = 0; // Clear it so we know if radio contines to set it
client.print("</body></html>\r\n\r\n");
client.stop();
}
else if (c == '\n') {
currentLineIsBlank = true;
currentLineIsGet = false;
}
else if (c != '\r') {
currentLineIsBlank = false;
}
}
}
Serial.println("done");
}
if (millis() % 5000 == 0) {
// radio.printDetails();
radio.whatHappened(tx_ok, tx_fail, rx_ready);
Serial.print("Data Rate ============================== ");
Serial.println( data_rate = radio.getPALevel());
Serial.print(tx_ok);
Serial.print(", ");
Serial.print(tx_fail);
Serial.print(", ");
Serial.println(rx_ready);
Serial.println(++i);
}}
(Whoops, initially didn't paste my test sketch, just the WebserverST code I started from. Fixed. It's all there now.)