Dear all,
I have a setup like the one described in the title installed on the field for years.
Since I started the software from scratch and have no training on C/C++ etc (just Fortran IV), I have read a LOT of tutorials and "glued" a lot of snippets of code to have the "working prototypes" of the two Tx's and the Receiver.
But, unfortunately the connection with one on the nodes drops from time to time, and to reestablish it I have to reset all the units.
That would not be a problem ina home setup, but in my case, one Tx is located 50m apart and 15m above ground and the other 70m apart.
He insisted that the best way to go was to drop the Tmrh20 RFnetwork (that I insisted on using) and use just the RF24 library.
After some more months of problems I decided (finally) to do as he advised and drop the Network layer.
So I went back to the internet looking for a WORKING example of a setup consisting of two transmitters and one receiver using tmrh20 RF24 library, without luck.
There is a very good tutorial on this forum from Robin2, which on post #17 should be "readily adaptable" for my case but, unfortunately, my programing skills are not "good enough" to make it work.
So can anyone help me on that?
What is the general opinion about using ackPayload() to detect the loss of connection with one of the nodes?
Is there a better solution to this?
Thank you all for your time.
Roger
have a look at post esp32-with-nrf24l01 which describes a receiver which can accept data from a number of transmitters (identified by id in the structure)
the run only shows one transmitter but is easily extended to more
in your case
are the data types sent by the transmitters the same or different
what happens if two transmitters transmit at the same time and corrupt each other
I did not posted the code I am using because they are BIG (the RX and one TX codes have more than 1100 lines.
answering your questions:
1 - I use structures to send the data
type or paste code here
// Structure of our payload
struct payload_t // 32 bytes max, used=7*4+2+1 = 31 bytes OK! corrected March 2023
{
uint32_t counter; // - 4 bytes number of packets transmitted
float val1; // - 4 bytes
float val2; // - 4 bytes
float val3; // - 4 bytes
float val4; // - 4 bytes
float val5; // - 4 bytes
float val6; // - 4 bytes
int16_t val7; // - 2 bytes
bool val8; // - 1 byte
};
payload_t payload; // create a variable with the above structure
2 - The data is sent once each 60 sec.
Note: I do not use delay() in the code.
But, does all the communications include a time-out waiting for a confirmation for each transmission? When the time-out expires without a confirmation reply, then it is time for a reset and restart of that devices communications. Without that you get the situation you described.
looks fairly straightforward
I. assume you use payload.counter to detect lost/corrupt packets
2. are lost packets critical?
3. do you get collisions which corrupt packets? I use polling to avoid this
Thank you for the replies.
I was not able find an example of packets loss check that I could adapt and make it work.
The variables I am monitoring are "slow" (levels, flowrates,...) so it loosing some packets is NOT critical.
However the receiver keep showing the last received value for the variables of the Txs even if no data has been received for a long time (say 10 min), and I would like to add an alarm to warn that it has happened in order to:
1- know that the values may be incorrect
2- correct the issue ( preferably using a software solution).
Can anyone suggest me one?
Or maybe just a snippet of code showing how to do it.
Thank you.
in the example I linked too in post 2 the
transmitter increments a sequence number on every transmission
data.seq++; // update test data
on every packet transmission
on receiving a packet the receiver checks the sequence number
if (seq_check == data.seq) Serial.print(" seq OK - ");
else {
Serial.print(" seq error! expected ");
Serial.print(seq_check);
seqErrors++;
}
on sequence error it just displays an error message but one could request retransmission of the missing packet(s)
there is an additional CRC check to ensure the integrity of the data
it all depends on how critical the data is - does the odd missing or corrupt packet matter?
e.g. if transmitting data on river heights, temperature, etc the odd missing packet is not critical
e.g. transmitting the company accounts would require extensive error checks
try a web search for tcp/ip sliding windows
you could also have a timeout at the receiver - it a packet has not been received within a set time you know something is wrong - request retransmission, alert operator, etc
Odd missing packets is NOT critical, due to the intrinsic nature of the variables.
However, I SHOULD have an indication that the data from one specific TX has not been updated recently.
Since each Tx transmits once every second the receiver should recognize that the last data for a specific TX has been received 5min ago (for example).
I have implemented the timeout alert in the previous version of the program, which used the RFNetwork header() instruction, but now I was convinced by several posts of this forum that the Network layer is causing more problems than solutions.
I have seen several posts informing that there is no software solution for a broken link (which would be the case for no new package in 5 min).
The reset() instruction does not seem to solve the issue.
Only recycling power would do.
Is this the general opinion of this forum?
Thanks
Are you not able to conceive of how you would use a timer to discover when the link was broken? Every time you get get a message, reset the timer value. If you find the timer expires, then you are sure nothing has been read that caused it to reset, and you now know the link was broken.
For your next project like this consider CAN. I use what I call a power dog (A watchdog that cycles the power if it is not petted). Reason it resets everything, that does not happen with most on chip watch dog timers.
Hi Paul, thank you for yor reply.
I used that successfully in an earlier version of the code that used the RF24Network library.
Everytime the network.header() was created, I started a timer and it was possible to detect awhen the link was broken.
However I decided, for other reasons decribed earlier to drop the Network layer so I am using the RF24 library insted.
What is happening now is that the variables related to the transmitters are kept in some buffer so I do not know WHICH VARIABLE I should monitor to identify that the link was broken.
Can you help?
thanks
Without seeing the complete code, do you really expect an answer? Granted, we may find it beyond us to comprehend, or unintelligible, but it's likely the only way someone is going to be able to tell you what to change to suppress things like "it may be held in a buffer". Really.