Hi,
I have developed the Android code so that when I send a large message, I send it in pieces, each as a separate message. This way, they are all sent at the same time. Now, the problem is that some of the messages (pieces) aren’t sent. How I understand is that when ACK or NACK is received, the sending of the message piece is finished. Sometimes they are sent, sometimes not. I want to figure it that every piece is sent. Is there anybody out there that can guide me with this? Maybe how I understand my problem is not correct, if so… what’s the problem?
Any help would be REALLY appreciated! I am dying here…
You don’t want to send them all at the same time that is going to use a lot of airtime and lead to failures. Meshtastic uses flood routing and ACKS are a separate message so it is possible that the message is received but the ACK response does not make it back, especially if you fire off a lot of messages at once. The bandwidth is really low, so doing TCP like things is generally going to be difficult, you want to have appropriate delays or a queue if you are going to try and manage sending a lot of messages.
Thanks @garth !
Ok, so you say to have appropriate delays or the queue in order to do this… could you guide me on this? Like, where and in what way can I add extras queues or add delays??
Did you build on top of the current Android app? It has a more sophisticated transmit queue from version 2.0.13 on.
Yes, I am using the latest version 2.0.20.
Today, maybe I figured something out… I increased ‘PROCESSING_TIME_MSEC’, normally it is 4500, I made it 15000 (so quite a significant change!). Now all my packets are sent and sent really quickly too. Is there any risk in increasing this processing time? Or any adverse effects?
Thanks!
You mean in the firmware, right? By fine-tuning that, you might just be lucky with a certain LoRa setting and packet length, but it might not always work well.
Actually, which firmware and hardware are you using? There were some bug fixes in 2.0.21 related to this. Especially SX1276 radios benefit from this. There’s some improvement for SX1262 as well, but I’ve found a remaining issue there.
Yes, the firmware.
The firmware I’m using is 2.0.22 and the hardware is SX1276.
I wanted to understand if by changing the “processing_time_msec” , are there any other effects? Until now, it is working well, but maybe that’s just my luck, or…?
If you increase that, it means it actually takes longer before it tries a retransmission. So if it failed, it would actually make it slower. But if you’re sending a lot of packets after each other, it might retransmit too soon if it was still receiving the ACK of a previous message. So under high load it makes sense to increase it, but not for normal messaging.
Ideally we would add some delay to the retransmission attempt if you received a packet that was not an ACK to the current packet.
For normal messaging, it hasn’t made any problem for me so far
If i want to add a delay for ACK like you say, where would I add it?
It will make it somewhat slower, but indeed should not really create problems.
You would have to add the delay to the ‘nextTxMsec’ field of all pending packets in ReliableRouter::shouldFilterReceived().
I will try it and if there’s something else I will ask again.
Thanks for all your help…
Ok, it hasn’t worked out like I wanted. I’m not sure where the problem is now. Is there anything else I can try to make it that all the message pieces are sent and never missed?
Since I was already planning to do this, I will try to come up with something that doesn’t influence normal messaging, but might be better when there’s higher load. Hopefully it works for your use-case as well. I will keep you informed.
Can you try with the changes I applied in this commit?
For me it works well when sending one packet from T-Beam 1 and during that one, 4 packets quickly after each other from the T-Beam 2.
Then first T-Beam 2 sends the ACK, then the 4 packets and then T-Beam 1 sends 4 ACKs. There are no unnecessary retransmissions and the packets follow each other quickly:
Ok I will try that commit and let you know how it goes.
There is something that I am thinking… What I have done is take a file and separate it into small pieces using Kotlin. These pieces are then sent to the Lora device as separate packets (this is where I am trying to develop the meshtastic code, with problems!) I think what would be good is if the firmware can understand if the packet is part of a file, or if it a regular message. For example, if at the head of the message there are certain characters (ie $T%%), then when it sees this it doesn’t send like a regular messages (with 3 attempts at sending etc) and instead it will send it more than 3 times to ensure it is sent and also ACK/NAK isn’t necessary.
This is my goal… do you think it is possible? I’m always working with Android and Arduino, and not so familiar with C++, so all your help is really appreciated.
Please let me know if it works out. It seems to be a valuable addition for the firmware. The same scenario with the current master produces 2x as much packets:
I think LoRa isn’t really suited for transmitting files without a higher-level protocol like TCP (which on the other hand would add a lot of overhead), because you would want sequence numbers. Only when there are no failures at all during the full process, it might work. Also take into account that if you are in the EU there is a 10% duty cycle limit.
If you still want to try this, you can set the wantAck
flag of the packet to ‘false’ in Kotlin, then there will also be no retransmissions. Are you sending it via a DM or broadcast? If you did via a broadcast, I would advise to do it with a DM, otherwise the other node will also rebroadcast it.
In the beginning I want to thank you for the code you share with me.
You asked about if I send via a DM or broadcast, I’m sending via a DM not broadcast.
I have tried to send much packets with the “new” code, I can send much packets but not every time. After a while I get a error:
channel utilization is > 40 percent. Skipping this opportunity to send
and after I get this error I noticed that the Bluetooth connection turns off. This does happen a several times.
To solve this I tried:
I looked at the channel utilization and got that it is ideal between 25-50.
In the airtime.cpp (the 128th line) I added 10 more to percentage, but I still got same failure but with the percent I’ve give.
I even tried with 60 percent but the failure I got was:
ELF file…
esp_core_dump_flash: core dump flash config is corrupted instead of 0x0 … Rebooting.
The high channel utilization log is only a warning, not an error. It is coming from another module, text messages will still be send.
However, if the Bluetooth connection turns off, it is likely that the device is crashing as you show at the end as well. The logs before the core dump should give you a clue about where it is going wrong. I can imagine that e.g. the device cannot handle so much packets coming from the phone quickly after each other. There’s probably not much one can do about that.
The package is send without any problems from the phone, but the problem is when it sends from the device - we can even send packages in interval from the phone to the device.
If you could help me with the thread I wrote yesterday maybe we could get results, if you can’t maybe you could direct me how to do with e.g. where to control the messages in the commit.
Ok I will try that commit and let you know how it goes.
There is something that I am thinking… What I have done is take a file and separate it into small pieces using Kotlin. These pieces are then sent to the Lora device as separate packets (this is where I am trying to develop the meshtastic code, with problems!) I think what would be good is if the firmware can understand if the packet is part of a file, or if it a regular message. For example, if at the head of the message there are certain characters (ie $T%%), then when it sees this it doesn’t send like a regular messages (with 3 attempts at sending etc) and instead it will send it more than 3 times to ensure it is sent and also ACK/NAK isn’t necessary.
This is my goal… do you think it is possible? I’m always working with Android and Arduino, and not so familiar with C++, so all your help is really appreciated.
You could look at the logs before it crashes to figure out what goes wrong.
If you don’t want and ACK, then set the wantACK
flag to false in Kotlin.
You could create your own PortNum to let the firmware handle these type of packets differently. Packets from the phone that should be send to the mesh start at ReliableRouter::send and propagate via FloodingRouter::send, to Router::send, to the RadioInterface.