Hi,
My setup is as follows:
Two transmitters sending data to one central unit.
The transmitting units do not receive data, they transmit only.
I am using the instruction ok = network.write(header,&payload,sizeof(payload)) to confirm that the data has been sent.
The curious thing is that the function returns a false but the data has been transmitted.
What am I missing?
I will attach the transmitter code, which is "short".
I will not post The receiver code because it has more than 1200 lines and a lot of calculations and functions that are not related to the question.
Thanks.
// Load driver for LED display
#include "Wire.h"
#include "hd44780.h" // main hd44780 header
#include "hd44780ioClass/hd44780_I2Cexp.h" // i2c expander i/o class header
// load RF related libraries
#include "RF24Network.h"
#include "RF24.h"
#include "SPI.h"
// Define LCD geometry and properties
hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip
// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;
// Define if we want to print values in serial monitor (DEBUG)
bool serialPrintFlag = HIGH; //<============ SET THE DEBUG OPTION HERE (ACTIVE HIGH)########################################
// Set a Flag to simulate that data to be transmitted (active HIGH)
bool simulateInputData = LOW; // <================================ Use this to input data to the sketch#######################
//---- Define sensor conections to Arduino
//???????? const int dpPort = 1; // changed in this revision (14/07/2020)
const byte dpPort = 1;
const byte flowSensor1_pin = 7; // In Arduino Promicro INT6 = Pin7
const byte flowSensor2_pin = 0; // In Arduino Promicro INT2 = Pin0 ####Do NOT use Serial1 #####
//----Define pin to activate the data sent ok!/ Tx failed messages
const byte activateMessages_pin = 21;
// The hall-effect flow sensor outputs approximately 7.0 pulses per second per litre/minute of flow
float calibrationFactor = 8.275; // ########Changed according to data on datasheet table pag 2
float altura = 120.00; //altura da caixa dagua em cm
float flow = 0.0;
float totalFlow = 0.0; //used only for sensor calibration
float auxVol = 0.0; // total volume pumped in this cycle
//------optFlowrate variables------
volatile byte FlowSensorPulseCount_1 = 0; // 255 counts is about 0.6 liters
volatile byte FlowSensorPulseCount_2 = 0;
float flowRate;
unsigned long oldTime;
float flowRateLPM = 0.0;
float totalLiters_1 = 0.0;
float totalLiters_2 = 0;
float vazaoPoco;
//------Display without delay variables and definitions-------------------
long previousLCDMillis = 0; // for LCD screen update
long lcdInterval = 4000;
int screen = 0;
int screenMax = 2;
bool screenChanged = true; // initially we have a new screen, by definition
// defines of the screens to show
#define LEVEL 0
#define FLOWRATE 1
#define BATCHVOL 2
#define DATATRANSMISSION 3
//------------ used to caclculate volume pumped in each pumping cycle
float old_Total = 0.0;
int i=0;
int levelDp = 0;
int rawDp = 0;
int rawDpMin = 32;
int rawDpMax = 192; // measured when actual tank was 100% full--revised 2/11/2020
float dummy1 = 0.0;
float dummy2 = 0.0;
bool dummy3 = 0;
float dummy4 = 0.0;
bool ok = LOW; // need to be initialised- can go HIGH even without nRF24L01 installed
// nRF24L01(+) radio attached (CE, CSN)
RF24 radio(9,10);
// Network uses that radio
RF24Network network(radio);
// Channel of our node
const uint16_t channel = 108;
// Address of our node
const uint16_t this_node = 02; //changed to 02 in rev3b (was 2)
// Address of the other node
const uint16_t other_node = 00; //changed to 00 in rev3b (was 0)
// How many packets have we sent already
unsigned long packets_sent;
//-------added on rev3_newtime----------
// How often to send data
const unsigned long Tx_interval = 1000; //ms //changed in julY 2023
// When did we last send?
unsigned long last_sent =0; //changed in rev Marco2021
//The data to be transmitted by lower and upper water tanks modules is:
// type cisterna caixa superior
// ------- ---------- --------------
// 1 float Irms auxVol (last pumping cycle volume)
// 2 float flow flow
// 3 float Pdisch totalLiters_1
// 4 float DpFilter vazaoPoco // changed in July 2023
// 5 float Pinlet dummy2
// 6 float lampCurrent dummy4 //added in March 2021
// 7 int rawDp rawDp
// 8 bool flapstate dummy3
// Structure of our payload, limited to 32 bytes
struct payload_t // 32 bytes max, used=7*4+2+1 = 31 bytes OK! updated March 2023
{
uint32_t counter; // number of packets transmitted 4-bytes
float auxVol; //-4 bytes
float flowRateLPM; //-4 bytes
float totalLiters_1; //-4 bytes
float vazaoPoco; //-4 bytes
float dummy2; //-4 bytes
float dummy4; //-4 bytes
int16_t rawDp; //-2 bytes
bool dummy3; //-1 byte
};
//??? payload_t payload = { packets_sent++, auxVol, flowRateLPM, totalLiters_1, vazaoPoco, dummy2, dummy4, rawDp, dummy3 }; // DOES NOT WORK HERE!!!!
// * Invoked by interrupt once per pulse of the flow sensor.
// * Interrupt handlers should be kept as small as possible so they return quickly.
void pulseCounter_1()
{
FlowSensorPulseCount_1++; // Increment the pulse counter
}
void pulseCounter_2() // Added July 2023
{
FlowSensorPulseCount_2++; // Increment the pulse counter
}
void setup()
{
Serial.begin(115200); // start serial communication
// Print a message to the LCD
lcd.begin(16, 2);
lcd.backlight();
//-----Welcome Display Function
showWelcome();
// Check if data input is simulated and print warning message
if (simulateInputData == HIGH)
{ lcd.clear();
lcd.print(F("DATA READ SIMULATED"));
}
// If message ok pin is HIGH, increase screenMax to 3 (data sent ok/ Tx failed case)
if (digitalRead(activateMessages_pin) == HIGH) screenMax = 3;
//*******Start Radio and define some parameters
SPI.begin();
radio.begin();
network.begin(channel, this_node);
radio.setPALevel(RF24_PA_HIGH);
radio.setAutoAck(false); // added Marco2021
radio.setDataRate( RF24_250KBPS ); // added on rev 3C
//??? radio.setRetries(15,15); // (delay, count) added on rev 3C----- No need if setAutoAck = false
radio.stopListening(); // added on rev 3C
// New Flowmeter initializations
pinMode(flowSensor1_pin, INPUT);
attachInterrupt(digitalPinToInterrupt(flowSensor1_pin), pulseCounter_1, RISING);
pinMode(flowSensor2_pin, INPUT);
attachInterrupt(digitalPinToInterrupt(flowSensor2_pin), pulseCounter_2, RISING);
} //------ end of setup
void loop()
{
//------ Initialize OptFlowrate & Display without Delay variables ------
unsigned long currentMillis = millis();
static unsigned long previousMillis = 0;
static unsigned long totalFlowSensorPulseCount_1 = 0;
static unsigned long totalFlowSensorPulseCount_2 = 0;
//--------- Calculate flow once per interval --------
const unsigned long interval = 1000; // count the number of pulses in one second ==> 1 pps = 1 Hz
if (currentMillis - previousMillis >= interval)
{
previousMillis += interval;
noInterrupts(); // Prevent an interrupt while we sample and reset the pulse count
byte currentFlowSensorPulseCount_1 = FlowSensorPulseCount_1;
byte currentFlowSensorPulseCount_2 = FlowSensorPulseCount_2;
FlowSensorPulseCount_1 = 0; // Re-start the counter for the next second
FlowSensorPulseCount_2 = 0;
interrupts();
totalFlowSensorPulseCount_1 += currentFlowSensorPulseCount_1;
totalFlowSensorPulseCount_2 += currentFlowSensorPulseCount_2;
flowRateLPM = (currentFlowSensorPulseCount_1 / calibrationFactor) * (1000.0 / interval); // 1 calibrationFactor pulses per second == 1 LPM
totalLiters_1 = totalFlowSensorPulseCount_1 / (calibrationFactor * 60.0); // 1 calibrationFactor pulses per second == 1 LPM so 7*60 P == 1 L
vazaoPoco = (currentFlowSensorPulseCount_2 / calibrationFactor) * (1000.0 / interval);
totalLiters_2 = totalFlowSensorPulseCount_2 / (calibrationFactor * 60.0);
if ( serialPrintFlag == HIGH)
{
Serial.print(F("currentMillis = "));
Serial.println(currentMillis);
Serial.print(F("currentFlowSensorPulseCount_1 = "));
Serial.println(currentFlowSensorPulseCount_1);
Serial.print(F("flowRateLPM = "));
Serial.println(flowRateLPM);
Serial.print(F("totalFlowSensorPulseCount_1 = "));
Serial.println(totalFlowSensorPulseCount_1);
Serial.print(F("totalLiters_1 = "));
Serial.println(totalLiters_1);
Serial.print(F("currentFlowSensorPulseCount_1 = "));
Serial.println(currentFlowSensorPulseCount_2);
Serial.print(F("Vazao Poco = "));
Serial.println(vazaoPoco);
Serial.print(F("totalFlowSensorPulseCount_2 = "));
Serial.println(totalFlowSensorPulseCount_2);
Serial.print(F("totalLiters_2 = "));
Serial.println(totalLiters_2);
}
}
// Calculate the volume pumped each time the pumping turns on-off
// check if the pump has started
if (flowRateLPM > 0.0 && i== 0 )
{ auxVol = totalLiters_1 - old_Total;
if (serialPrintFlag == HIGH)
{
Serial.println(F("esta bombeando"));
Serial.print(F("Total= "));
Serial.println(totalLiters_1);
Serial.print(F("old_Total= "));
Serial.println(old_Total);
Serial.print(F("Vol Bomb= "));
Serial.println(auxVol);
}
}
// If the pump stopped, store the current total flow
// making i=1 would prevent variables to be updated until the pump starts again
if (flowRateLPM == 0.0 && i==0 )
{
old_Total = totalLiters_1;
i=1;
}
// If the pump has started again, set i=0 and start over
if (flowRateLPM > 0.0 && i==1 ) i=0;
//********Read level from DP sensor************
rawDp = analogRead(dpPort);
delay (1000);
// ********Calculate level (in %) from measurements*********
levelDp = map(rawDp, rawDpMin, rawDpMax, 0, 100);
// print level on serial monitor
if ( serialPrintFlag == HIGH)
{
Serial.print (F("rawDp= "));
Serial.println (rawDp);
Serial.print (F("level= "));
Serial.println (levelDp);
Serial.print (F(" %"));
}
//******* Pump the network regularly*******
network.update();
// check if we want to define a set of value to the variables to be transmitted
if(simulateInputData == HIGH) input_Data();
//-----added in rev3_newtime-----------
// If it's time to send a message, send it!
unsigned long now = millis(); // move up after testing...
if ( now - last_sent >= Tx_interval )
{
last_sent = now;
sendPayload();
}
display_Data();
} // this is the end of the loop
//////////////////////////////////////////////////////////////////////////////////
// sendPayload //
//////////////////////////////////////////////////////////////////////////////////
// ********* Transmit data ********************
void sendPayload()
{
RF24NetworkHeader header(/*to node*/ other_node);
payload_t payload = { packets_sent++, auxVol, flowRateLPM, totalLiters_1, vazaoPoco, dummy2, dummy4, rawDp, dummy3 };
ok = network.write(header,&payload,sizeof(payload));
//------Debug--------
if ( serialPrintFlag == HIGH)
{
Serial.println(F("---------------------------"));
Serial.print(F("millis() = "));
Serial.println(millis());
}
}
///////////////////////////////////////////////////////////////////////////////
// Auxiliary display functions //
///////////////////////////////////////////////////////////////////////////////
void showWelcome()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(F("caixa Opt Flow"));
lcd.setCursor(0, 1);
lcd.print(F("rev A-Set 2023"));
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(F("23/08/2023"));
delay(2000);
}
void showLevel()
{
lcd.clear();
lcd.print(F("rawDp= "));
lcd.print(rawDp);
lcd.setCursor(0, 1);
lcd.print(F("nivelDp= "));
lcd.print(levelDp);
lcd.print(F(" %"));
}
void showFlowrate()
{
lcd.clear();
lcd.print(F("Flow= "));
lcd.print(flowRateLPM);
lcd.setCursor(0, 1);
lcd.print(F("Vazao Poco= "));
lcd.print(vazaoPoco);
}
void showBatchVolume()
{
lcd.clear();
lcd.print(F("Vol in this Cycle"));
lcd.setCursor(0, 1);
lcd.print(auxVol);
}
void showDataTransmission()
{
if (ok)
{ lcd.clear();
lcd.print(F( "data sent OK"));
if( serialPrintFlag == HIGH) Serial.println(F("data sent OK"));
}
else{
lcd.clear();
lcd.print( "TX FAILED");
if ( serialPrintFlag == HIGH) Serial.println(F("TX FAILED"));
}
}
////////////////////////////////////////////////////////////////////////////
// Display Function
////////////////////////////////////////////////////////////////////////////
// MUST WE SWITCH SCREEN?
void display_Data()
{
unsigned long currentLCDMillis = millis();
if(currentLCDMillis - previousLCDMillis > lcdInterval) // save the last time you changed the display
{
previousLCDMillis = currentLCDMillis;
screen++;
if (screen > screenMax) screen = 0; // all screens done? => start over
screenChanged = true;
}
// DISPLAY CURRENT SCREEN
if (screenChanged) // -- only update the screen if the screen is changed.
{
screenChanged = false; // reset for next iteration
switch(screen)
{
case LEVEL:
showLevel();
break;
case FLOWRATE:
showFlowrate();
break;
case BATCHVOL:
showBatchVolume();
break;
case DATATRANSMISSION:
showDataTransmission();
break;
default:
// cannot happen -> showError() ?
break;
}
}
}
//////////////////////////////////////////////////////////////////////
// input_Data - define values to variables to be transmitted
//////////////////////////////////////////////////////////////////
void input_Data()
{
auxVol = 123.4;
flowRateLPM =7.6;
vazaoPoco = 5.4;
rawDp = 120;
}