Hello, Robin!
Thank you for all of your help you've given us some time ago. I hope you are staying safe and well in these hectic times.
Since our last post, we've made a lot of progress! We ended up getting the cheap non-antenna nRF24 modules and ended up having them communicate! To our "sensor" Arduino, we hooked up a simple analog water sensor whose data we then analyze and send over to the "master" Arduino that simply prints the data out.
After that, we decided to add a button, so that the "master" Arduino can "request" data from the "sensor" Arduino whenever the button is pushed. We followed your slave-master switching code example for our prototype. However, we keep getting "FAILED: Request for Data" on the "master" Arduino while our "sensor" Arduino's Serial Monitor remains empty.
We would really appreciate it if you took a quick look at our code. I think we must be missing something.
This is our "master" Arduino code (the one that is supposed to first send a request by button then read data):
// SimpleRx - the slave or the receiver
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 8
#define BUTTON 4
int buttonState = 0; // the status of the button
int prevButtonState = 0; // the previous state of the button
const byte slaveAddress[5] = {'R','x','A','A','A'};
const byte masterAddress[5] = {'T','X','a','a','a'};
RF24 radio(CE_PIN, CSN_PIN);
char dataReceived[20]; // this must match dataToSend in the TX
int requestData[2] = {109, -4000}; // the two values to be sent to the master
bool newData = false;
//===========
void setup() {
pinMode(BUTTON, INPUT);
Serial.begin(9600);
Serial.println("---------------------------------------------------------");
Serial.println("SimpleRx Starting");
Serial.println("---------------------------------------------------------");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openWritingPipe(masterAddress);
radio.openReadingPipe(1, slaveAddress);
radio.setRetries(3,5); // delay, count
}
//=============
void loop() {
buttonState = digitalRead(BUTTON);
if (buttonState != prevButtonState) {
prevButtonState = buttonState;
send();
getData();
showData();
}
}
//==============
void send() {
radio.stopListening();
bool rslt;
rslt = radio.write(&requestData, sizeof(requestData));
radio.startListening();
if (rslt) {
Serial.println("Request for Data Sent");
}
else {
Serial.println("FAILED: Request for Data");
}
Serial.println();
}
//==============
void getData() {
for (int i = 0; i < 2; i++) {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
newData = true;
}
}
}
void showData() {
for (int i = 0; i < 2; i++) {
if (newData == true) {
Serial.print("Data received ");
Serial.println(dataReceived);
}
}
Serial.println("---------------------------------------------------------");
newData = false;
}
This is our "sensor" Arduino code that waits for a request for data collection, the collects data and sends it back.
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
//---------------------------------------------------------------------------------------
#define CE_PIN 9
#define CSN_PIN 8
// Configuration values:
#define SERIES_RESISTOR 2000 // Value of the series resistor in ohms.
#define SENSOR_PIN 0 // Analog pin which is connected to the sensor.
#define ZERO_VOLUME_RESISTANCE 2320000 // Resistance value (in ohms) when no liquid is present. [546]
#define CALIBRATION_RESISTANCE 637000 // Resistance value (in ohms) when liquid is at max line. [188]
#define CALIBRATION_VOLUME 980 // Volume (in mL) when liquid is at max line.
char volumeDataToSend[20];
char heightDataToSend[20];
int dataReceived[2]; // to accept the request for data
bool request = false;
//---------------------------------------------------------------------------------------
// CONSTANTS: volume of container = , radius of container = 3.0 cm
float radius = 3.0;
const byte slaveAddress[5] = {'R','x','A','A','A'};
const byte masterAddress[5] = {'T','X','a','a','a'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
//---------------------------------------------------------------------------------------
// SET UP TRANSMISSION
void setup(void) {
Serial.begin(9600);
Serial.println("SimpleTx Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openWritingPipe(slaveAddress);
radio.openReadingPipe(1, masterAddress);
radio.setRetries(3,5); // delay, count
}
//---------------------------------------------------------------------------------------
void loop(void) {
radio.startListening();
getRequest();
radio.stopListening();
if (!request) {
return;
}
request = false;
// Measure sensor resistance.
float resistance = 0;
for (int i = 0; i < 20000; i++) {
resistance += readResistance(SENSOR_PIN, SERIES_RESISTOR); // get 20 readings
}
resistance = resistance / 20.0;
Serial.print("Resistance: ");
Serial.print(resistance, 2);
Serial.println(" ohms");
// Map resistance to volume.
float volume = resistanceToVolume(resistance, ZERO_VOLUME_RESISTANCE, CALIBRATION_RESISTANCE, CALIBRATION_VOLUME);
Serial.print("Calculated volume: ");
Serial.println(volume, 5);
// Map resistance to height.
float height = volume / (3.1415 * radius * radius);
Serial.print("Calculated height: ");
Serial.println(height, 5);
// send the data
String s = "Volume: " + String(volume) + " mL";
s.toCharArray(volumeDataToSend, sizeof(volumeDataToSend));
String s2 = "Height: " + String(height) + " cm";
s2.toCharArray(heightDataToSend, sizeof(heightDataToSend));
// sendTest();
send();
}
//---------------------------------------------------------------------------------------
//void sendTest() {
// bool rslt;
// // SENDINNG VOLUME
// char volumeDataToSend[20] = "I have coronavirus.";
// rslt = radio.write( &volumeDataToSend, sizeof(volumeDataToSend));
//
// Serial.print(volumeDataToSend);
// if (request) {
// Serial.println(" Acknowledge received: volume successfully sent");
// }
// else {
// Serial.println(" Tx failed volume");
// }
//}
//---------------------------------------------------------------------------------------
void getRequest() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
request = true;
}
}
//---------------------------------------------------------------------------------------
void send() {
bool rslt;
// SENDINNG VOLUME
rslt = radio.write( &volumeDataToSend, sizeof(volumeDataToSend));
Serial.print(volumeDataToSend);
if (rslt) {
Serial.println(" Acknowledge received: volume successfully sent");
}
else {
Serial.println(" Tx failed volume");
}
// SENDING HEIGHT
rslt = radio.write( &heightDataToSend, sizeof(heightDataToSend));
Serial.print(heightDataToSend);
if (rslt) {
Serial.println(" Acknowledge received: height successfully sent");
}
else {
Serial.println(" Tx failed height");
}
Serial.println("\n---------------------------------------------------------");
}
//---------------------------------------------------------------------------------------
float readResistance(int pin, int seriesResistance) {
// Get ADC value.
float resistance = analogRead(pin);
// Convert ADC reading to resistance.
resistance = (1023.0 / resistance) - 1.0;
resistance = seriesResistance / resistance;
return resistance;
}
//---------------------------------------------------------------------------------------
float resistanceToVolume(float resistance, float zeroResistance, float calResistance, float calVolume) {
if (resistance > zeroResistance || (zeroResistance - calResistance) == 0.0) {
// Stop if the value is above the zero threshold, or no max resistance is set (would be divide by zero).
return 0.0;
}
// Compute scale factor by mapping resistance to 0...1.0+ range relative to maxResistance value.
float scale = (zeroResistance - resistance) / (zeroResistance - calResistance);
// Scale maxVolume based on computed scale factor.
return calVolume * scale;
}
Any help would be appreciated. Have a great week!