Electron: UDP problem, connection unreliable

Hi all,
today I’m facing a strange UDP send/receive strange behaviour and I’d like to know the causes.

Setting:
Electron in Paris with a 3rd party SIM card (ThingsMobile)

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(MANUAL);
STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));

const size_t UDP_BUFFER_SIZE = 513;
const int REMOTE_UDP_PORT = 60004;
const IPAddress REMOTE_UDP_ADDR = IPAddress( *HIDDEN* );
const int LOCAL_UDP_PORT = 60004;
const unsigned long SEND_INTERVAL_MS = 15000;

My connection loop is:

Cellular.connect(); //Connect
if (!waitFor(Cellular.ready, 60000*2)){
        Serial.println("Connection attempt timeout.");
        connFailed = true;
}
else{
        connFailed = false;
}
if(!connFailed){ //Connecting
        Serial.print("Connected in ");
        Serial.print((millis () - initialTime) / 1000);
        Serial.println(" seconds");
        
        cConnecting = 0;
        while(Cellular.connecting()) {
            cConnecting++;
            if(cConnecting == 60){
                cConnecting = 0;
                Serial.println("Connectioning attempt timeout.");
                connFailed = true;
                break;
            }
            delay(1000);
        }
    }
if(!connFailed){
     //Sampling and sending to the server
     int sendAttemps = 0;
     while(!sentToServer(sentC)){
            if((sendAttemps++) == 4){
                Serial.println("Server timeout");
                break;
            }         
        }
     connFailed = false;

sentToServer(char* sent):

udp.begin(LOCAL_UDP_PORT);
Serial.println(Cellular.localIP());
int sentByte = udp.sendPacket(sent, strlen(sent), REMOTE_UDP_ADDR, REMOTE_UDP_PORT);
if (sentByte < 0){ //CONNECTION ERROR
        Serial.println("SendPacket error");
        udp.stop();
        return false;
}
else{
        char udpBuffer[UDP_BUFFER_SIZE];
        while (udp.available() <= 0) {
               int count = udp.receivePacket((uint8_t * ) udpBuffer, UDP_BUFFER_SIZE - 1);
               if (count > 0) { //OK parse the server ACK
                     Serial.print("Byte received: ");
                     Serial.println(count);
                     Serial.printlnf(">>> %s:%d %s", udp.remoteIP().toString().c_str(), udp.remotePort(), udpBuffer);
                     parseResponse(udpBuffer, count);
                     break;
                }
                else if (count == 0) { //WAITING FOR ACK
                     attemps++;
                     Serial.printlnf("** No packets %d", count);
                     if (attemps == 20){ //NO ACK
                         attemps = 0;
                         udp.stop();
                         return false;
                      }
                 delay(500);
                 }
                else { //CONNECTION ERROR
                     Serial.printlnf("** receivePacket error %d", count);
                     udp.stop();
                     return false;
                 }

          }
}
udp.stop();
delay(500);
return true;

It usually runs every minute without any problems, but last night it sent 10/15 values out of 60 per hour.
In the picture below you, every dot is a loop with connection success to the server.

07

To help you checking the log, let’s analyze the sample at 11:10 (1569402600 epoch time).

The log:

Connection...
Connected in 1 seconds
Char array to send: {1,41260563,7,1569402600,1:45.188529,2:5.724524,3:0.000000,7:6,8:6,9:0,4:26.23,5:47.85,6:1001.64,10:4.04}

Sending
  4932.085 AT send       4 "AT\r\n"
  4932.947 AT read OK    6 "\r\nOK\r\n"
  4932.947 AT send      15 "AT+USOCTL=0,0\r\n"
  4932.954 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  4932.955 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 (UDP) open, closing...
  4932.955 AT send      12 "AT+USOCL=0\r\n"
  4933.222 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 was closed.
  4933.222 AT send      15 "AT+USOCTL=1,0\r\n"
  4933.231 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4933.232 AT send      15 "AT+USOCTL=2,0\r\n"
  4933.240 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4933.241 AT send      15 "AT+USOCTL=3,0\r\n"
  4933.250 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4933.251 AT send      15 "AT+USOCTL=4,0\r\n"
  4933.259 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4933.260 AT send      15 "AT+USOCTL=5,0\r\n"
  4933.269 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4933.270 AT send      15 "AT+USOCTL=6,0\r\n"
  4933.278 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
socketSocket: closed stale socket handle(s)
socketSocket(UDP)
  4933.279 AT send      19 "AT+USOCR=17,60004\r\n"
  4933.287 AT read  +   13 "\r\n+USOCR: 0\r\n"
  4933.288 AT read OK    6 "\r\nOK\r\n"
Socket 0: handle 0 was created

//First attempt

Connected: 10.162.188.11
socketSendTo(0,**MY_SERVER_IP**,60004,,105)
  4934.289 AT send      38 "AT+USOST=0,\"**MY_SERVER_IP**\",60004,105\r\n"
  4934.297 AT read  >    3 "\r\n@"
  4934.297 AT send     105 "{1,41260563,7,1569402600,1:45.188529,2:5.724524,3:0.000000,7:6,8:6,9:0,4:26.23,5:47.85,6:1001.64,10:4.04}"
  4934.439 AT read  +   17 "\r\n+USOST: 0,105\r\n"
  4934.440 AT read OK    6 "\r\nOK\r\n"
  4934.440 AT send       4 "AT\r\n"
  4934.443 AT read OK    6 "\r\nOK\r\n"
  4934.443 AT send      14 "AT+USORF=0,0\r\n"
  4934.449 AT read  +   15 "\r\n+USORF: 0,0\r\n"
Socket 0: handle 0 has 0 bytes pending
  4934.450 AT read OK    6 "\r\nOK\r\n"
Byte sent: 105
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
  4949.170 AT send      15 "AT+USOCTL=0,0\r\n"
socketClose(0)(UNK)
  4950.172 AT send      12 "AT+USOCL=0\r\n"
  4950.700 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  4950.701 AT read OK    6 "\r\nOK\r\n"
socketFree(0)
  4951.201 AT send       4 "AT\r\n"
  4951.205 AT read OK    6 "\r\nOK\r\n"
  4951.205 AT send      15 "AT+USOCTL=0,0\r\n"
  4951.212 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  4951.213 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 (UDP) open, closing...
  4951.213 AT send      12 "AT+USOCL=0\r\n"
  4951.479 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 was closed.
  4951.479 AT send      15 "AT+USOCTL=1,0\r\n"
  4951.487 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4951.488 AT send      15 "AT+USOCTL=2,0\r\n"
  4951.496 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4951.497 AT send      15 "AT+USOCTL=3,0\r\n"
  4951.505 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4951.506 AT send      15 "AT+USOCTL=4,0\r\n"
  4951.514 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4951.515 AT send      15 "AT+USOCTL=5,0\r\n"
  4951.523 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4951.524 AT send      15 "AT+USOCTL=6,0\r\n"
  4951.532 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
socketSocket: closed stale socket handle(s)
socketSocket(UDP)
  4951.533 AT send      19 "AT+USOCR=17,60004\r\n"
  4951.541 AT read  +   13 "\r\n+USOCR: 0\r\n"
  4951.542 AT read OK    6 "\r\nOK\r\n"
Socket 0: handle 0 was created

//Second attempt

Connected: 10.162.188.11
socketSendTo(0,**MY_SERVER_IP**,60004,,105)
  4952.543 AT send      38 "AT+USOST=0,\"**MY_SERVER_IP**\",60004,105\r\n"
  4952.551 AT read  >    3 "\r\n@"
  4952.551 AT send     105 "{1,41260563,7,1569402600,1:45.188529,2:5.724524,3:0.000000,7:6,8:6,9:0,4:26.23,5:47.85,6:1001.64,10:4.04}"
  4952.694 AT read  +   17 "\r\n+USOST: 0,105\r\n"
  4952.695 AT read OK    6 "\r\nOK\r\n"
  4952.695 AT send       4 "AT\r\n"
  4952.698 AT read OK    6 "\r\nOK\r\n"
  4952.698 AT send      14 "AT+USORF=0,0\r\n"
  4952.704 AT read  +   15 "\r\n+USORF: 0,0\r\n"
Socket 0: handle 0 has 0 bytes pending
  4952.705 AT read OK    6 "\r\nOK\r\n"
Byte sent: 105
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
  4967.426 AT send      15 "AT+USOCTL=0,0\r\n"
socketClose(0)(UNK)
  4968.428 AT send      12 "AT+USOCL=0\r\n"
  4968.827 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  4968.828 AT read OK    6 "\r\nOK\r\n"
socketFree(0)
  4969.328 AT send       4 "AT\r\n"
  4969.332 AT read OK    6 "\r\nOK\r\n"
  4969.332 AT send      15 "AT+USOCTL=0,0\r\n"
  4969.339 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  4969.340 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 (UDP) open, closing...
  4969.340 AT send      12 "AT+USOCL=0\r\n"
  4969.606 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 was closed.
  4969.606 AT send      15 "AT+USOCTL=1,0\r\n"
  4969.614 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4969.615 AT send      15 "AT+USOCTL=2,0\r\n"
  4969.623 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4969.624 AT send      15 "AT+USOCTL=3,0\r\n"
  4969.632 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4969.633 AT send      15 "AT+USOCTL=4,0\r\n"
  4969.641 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4969.642 AT send      15 "AT+USOCTL=5,0\r\n"
  4969.650 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4969.651 AT send      15 "AT+USOCTL=6,0\r\n"
  4969.659 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
socketSocket: closed stale socket handle(s)
socketSocket(UDP)
  4969.660 AT send      19 "AT+USOCR=17,60004\r\n"
  4969.668 AT read  +   13 "\r\n+USOCR: 0\r\n"
  4969.669 AT read OK    6 "\r\nOK\r\n"
Socket 0: handle 0 was created

//Third attempt

Connected: 10.162.188.11
socketSendTo(0,**MY_SERVER_IP**,60004,,105)
  4970.670 AT send      38 "AT+USOST=0,\"**MY_SERVER_IP**\",60004,105\r\n"
  4970.679 AT read  >    3 "\r\n@"
  4970.679 AT send     105 "{1,41260563,7,1569402600,1:45.188529,2:5.724524,3:0.000000,7:6,8:6,9:0,4:26.23,5:47.85,6:1001.64,10:4.04}"
  4970.821 AT read  +   17 "\r\n+USOST: 0,105\r\n"
  4970.822 AT read OK    6 "\r\nOK\r\n"
  4970.822 AT send       4 "AT\r\n"
  4970.825 AT read OK    6 "\r\nOK\r\n"
  4970.825 AT send      14 "AT+USORF=0,0\r\n"
  4970.832 AT read  +   15 "\r\n+USORF: 0,0\r\n"
Socket 0: handle 0 has 0 bytes pending
  4970.833 AT read OK    6 "\r\nOK\r\n"
Byte sent: 105
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
  4985.556 AT send      15 "AT+USOCTL=0,0\r\n"
socketClose(0)(UNK)
  4986.557 AT send      12 "AT+USOCL=0\r\n"
  4986.907 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  4986.908 AT read OK    6 "\r\nOK\r\n"
socketFree(0)
  4987.408 AT send       4 "AT\r\n"
  4987.412 AT read OK    6 "\r\nOK\r\n"
  4987.412 AT send      15 "AT+USOCTL=0,0\r\n"
  4987.419 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  4987.420 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 (UDP) open, closing...
  4987.420 AT send      12 "AT+USOCL=0\r\n"
  4987.686 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 was closed.
  4987.686 AT send      15 "AT+USOCTL=1,0\r\n"
  4987.695 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4987.696 AT send      15 "AT+USOCTL=2,0\r\n"
  4987.704 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4987.705 AT send      15 "AT+USOCTL=3,0\r\n"
  4987.713 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4987.714 AT send      15 "AT+USOCTL=4,0\r\n"
  4987.723 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4987.724 AT send      15 "AT+USOCTL=5,0\r\n"
  4987.733 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  4987.734 AT send      15 "AT+USOCTL=6,0\r\n"
  4987.742 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
socketSocket: closed stale socket handle(s)
socketSocket(UDP)
  4987.743 AT send      19 "AT+USOCR=17,60004\r\n"
  4987.751 AT read  +   13 "\r\n+USOCR: 0\r\n"
  4987.752 AT read OK    6 "\r\nOK\r\n"
Socket 0: handle 0 was created
Connected: 10.162.188.11
socketSendTo(0,**MY_SERVER_IP**,60004,,105)
  4988.753 AT send      38 "AT+USOST=0,\"**MY_SERVER_IP**\",60004,105\r\n"
  4988.762 AT read  >    3 "\r\n@"
  4988.762 AT send     105 "{1,41260563,7,1569402600,1:45.188529,2:5.724524,3:0.000000,7:6,8:6,9:0,4:26.23,5:47.85,6:1001.64,10:4.04}"
  4988.905 AT read  +   17 "\r\n+USOST: 0,105\r\n"
  4988.906 AT read OK    6 "\r\nOK\r\n"
  4988.906 AT send       4 "AT\r\n"
  4988.909 AT read OK    6 "\r\nOK\r\n"
  4988.909 AT send      14 "AT+USORF=0,0\r\n"
  4988.915 AT read  +   15 "\r\n+USORF: 0,0\r\n"
Socket 0: handle 0 has 0 bytes pending
  4988.916 AT read OK    6 "\r\nOK\r\n"
Byte sent: 105
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
  5003.640 AT send      15 "AT+USOCTL=0,0\r\n"
socketClose(0)(UNK)
  5004.641 AT send      12 "AT+USOCL=0\r\n"
  5004.889 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  5004.890 AT read OK    6 "\r\nOK\r\n"
socketFree(0)
  5005.390 AT send       4 "AT\r\n"
  5005.394 AT read OK    6 "\r\nOK\r\n"
  5005.394 AT send      15 "AT+USOCTL=0,0\r\n"
  5005.401 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  5005.402 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 (UDP) open, closing...
  5005.402 AT send      12 "AT+USOCL=0\r\n"
  5005.668 AT read OK    6 "\r\nOK\r\n"
Socket handle 0 was closed.
  5005.668 AT send      15 "AT+USOCTL=1,0\r\n"
  5005.677 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  5005.678 AT send      15 "AT+USOCTL=2,0\r\n"
  5005.686 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  5005.687 AT send      15 "AT+USOCTL=3,0\r\n"
  5005.695 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  5005.696 AT send      15 "AT+USOCTL=4,0\r\n"
  5005.704 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  5005.705 AT send      15 "AT+USOCTL=5,0\r\n"
  5005.713 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
  5005.714 AT send      15 "AT+USOCTL=6,0\r\n"
  5005.722 AT read ERR  37 "\r\n+CME ERROR: operation not allowed\r\n"
socketSocket: closed stale socket handle(s)
socketSocket(UDP)
  5005.723 AT send      19 "AT+USOCR=17,60004\r\n"
  5005.732 AT read  +   13 "\r\n+USOCR: 0\r\n"
  5005.733 AT read OK    6 "\r\nOK\r\n"
Socket 0: handle 0 was created

//Fourth attempt

Connected: 10.162.188.11
socketSendTo(0,**MY_SERVER_IP**,60004,,105)
  5006.734 AT send      38 "AT+USOST=0,\"**MY_SERVER_IP**\",60004,105\r\n"
  5006.743 AT read  >    3 "\r\n@"
  5006.743 AT send     105 "{1,41260563,7,1569402600,1:45.188529,2:5.724524,3:0.000000,7:6,8:6,9:0,4:26.23,5:47.85,6:1001.64,10:4.04}"
  5006.886 AT read  +   17 "\r\n+USOST: 0,105\r\n"
  5006.887 AT read OK    6 "\r\nOK\r\n"
  5006.887 AT send       4 "AT\r\n"
  5006.890 AT read OK    6 "\r\nOK\r\n"
  5006.890 AT send      14 "AT+USORF=0,0\r\n"
  5006.896 AT read  +   15 "\r\n+USORF: 0,0\r\n"
Socket 0: handle 0 has 0 bytes pending
  5006.897 AT read OK    6 "\r\nOK\r\n"
Byte sent: 105
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
** No packets 0
  5021.622 AT send      15 "AT+USOCTL=0,0\r\n"
socketClose(0)(UNK)
  5022.623 AT send      12 "AT+USOCL=0\r\n"
  5023.088 AT read  +   19 "\r\n+USOCTL: 0,0,17\r\n"
  5023.089 AT read OK    6 "\r\nOK\r\n"
socketFree(0)

Server timeout

In this case I actually got the UDP packet to the server, in fact server side I had:

1569402613.77 Received 105 bytes from ('5.35.166.171', 4292)
< {1,41260563,7,1569402600,1:45.188529,2:5.724524,3:0.000000,7:6,8:6,9:0,4:26.23,5:47.85,6:1001.64,10:4.04}
41260563 > INSERT INTO ....
41260563 10 records inserted
1569402613.78 Sending 25 bytes to ('5.35.166.171', 4292) //ACK
> {1,41260563,7,1569402613}

Then the server stopped receiving samples for 12minutes
Any idea why the connection electron/server is unreliable? Am I missing something?

Thank you for the help :wink:

Just out of curiosity - why are you using UDP vs TCP?

Hi @shanevanj, we’re using UDP since other sensors are spread even in wild areas where unreliability is accepted, so the protocol is UDP based at the moment.

In addition to the log above: Turning electron off (we have a switch to the battery) and on again ““solved”” the problem.

57

The connection unreliability from the thread is still a problem to solve though :frowning:

Is there a reason for unconditionally calling Cellular.connect() over and over in loop()?
Why is this?

  if (!connFailed) {
    ...
    while (Cellular.connecting()) {
      ...
    }
    ...
  }
  if (!connFailed) {
    ...
  }

When the connection has not* failed (aka Cellular.ready() == true) it’s highly unlikely the device is still trying to do what it already has successfully finished doing :confused:

And why then chekcing again what already was established in the previous step?

It might be that this makes sense in the full context of loop() but we only seem to see parts of it - which isn’t that helpful either.

Also this puzzles me

  // send request
  ...
  while (udp.available() <= 0) {
    int count = udp.receivePacket((uint8_t * ) udpBuffer, UDP_BUFFER_SIZE - 1);
    if (count > 0) { //OK parse the server ACK
      Serial.print("Byte received: ");
      Serial.println(count);
      Serial.printlnf(">>> %s:%d %s", udp.remoteIP().toString().c_str(), udp.remotePort(), udpBuffer);
      parseResponse(udpBuffer, count);
      break;
    }
    else if (count == 0) { //WAITING FOR ACK
      attemps++;
      Serial.printlnf("** No packets %d", count);
      if (attemps == 20) { //NO ACK
        attemps = 0;
        udp.stop();
        return false;
      }
      delay(500);
    }
    else { //CONNECTION ERROR
      Serial.printlnf("** receivePacket error %d", count);
      udp.stop();
      return false;
    }
  }
  ...

If I’m not mistaken this seems to assume your response will take some minumum but unknown time to come back. But if it does - for whatever reason - come back faster than that, you’ll not enter the loop to actually process the received packet.

Hi @ScruffR and thanks for the reply.
The call Cellular.connect() was there in case we want to put the sensor to sleep with:
`System.sleep(SLEEP_MODE_DEEP,SLEEPING_TIME, SLEEP_NETWORK_STANDBY);
I could be wrong, but I remember some connection issues in case I don’t call again Connect/Connecting…

That combination of Connect/Cellular.ready/Connecting never gave me problems with NO_SLEEP/SLEEP loops but I trust you more than my code :sweat_smile: Ready to test new connection loops if you say it’s more reliable.

To full (I pasted setup/loop/sendToServer) code: https://pastebin.com/hLCBjBYS

Now seeing your full code I’d focus on the latter part of my previous post and one note in the docs about udp.available()

On the other hand udp.receivePacket() should be waiting for a packet anyway, so I’m not entirely sure why you’d need that loop at all - or are you expecting an unknown number of packets in response to a single request?

BTW, I’d guard against unnecesary Cellular.connect() calls with an if (!Cellular.ready() && !Cellular.connecting()) check.

1 Like

About ACK reading, are you suggesting to add UDP.parsePacket() before the while loop?
I wanted to wait for the server ack, avoiding the count==0 case that sometimes happens before the real packet.
I actually need to wait only 1 ACK from the server, or zero if it’s lost.
Do you suggest another way?

I added
if(!Cellular.ready() && !Cellular.connecting())
before calling Cellular.Connect() :wink:

Hi! I’m back to this ‘problem’ since I’d like to improve my Electron connection realibility.

I moved all the connection functions in a parallel Thread called ‘connecting’

system_tick_t lastThreadTime = 0;
void connecting(){
    while(true){
        Log.info("Connection...");
        unsigned long initialTime = millis();
        if(!Cellular.ready() && !Cellular.connecting())
            Cellular.connect();
        
        delay(1000);
        
        if (!waitFor(Cellular.ready, 30000)){
            Log.info("Connection attempt timeout.");
            connFailed = true;
        }
        else{
            connFailed = false;
        }
        
        Log.info("Connected?");
        
        if(!connFailed){
            Log.info("Connected in %d seconds", (millis () - initialTime) / 1000 );
            
            cConnecting = 0;
            while(Cellular.connecting()) {
                Log.info("Connecting...");
                Serial.flush();
                cConnecting++;
                if(cConnecting == 60){
                    cConnecting = 0;
                    Log.info("Connectioning attempt timeout.");
                    connFailed = true;
                    break;
                }
                delay(1000);
            }
        }
        os_thread_delay_until(&lastThreadTime, 1000*60);
    }
}

The main thread samples the air and send data to my server.
The loop is:

 if (Cellular.ready()) { // CONNECTED == SEND
        Log.info(">> CONNECTED!");
        getTime();
        while(!sendToServer(sentC, LOCAL_UDP_PORT)){ //Send Data
            Log.info("Server timeout #%d", serverTimeout);
            attempts++;
            if(attempts < 3){
                continue; //Retry to open the Socket
            }
            
            //After 3 attempts, stop trying sending
            serverTimeout++;
            if(serverTimeout >= 3){ // Do SLEEP_MODE_DEEP to reset the modem
                Log.info("!! RESET MODEM !!");
                serverTimeout = 0;
                Serial.flush();
                System.sleep(SLEEP_MODE_DEEP, 5); //Reset Modem
            }     
            break; //Next loop
        }
    }
    else{ // NOT CONNECTED == SAVE to FileSystem
        Log.info(">> NOT CONNECTED!");
        if(timeSynced){
            savetoFS(sentC); //Store the value into flash memory
        }
    }

The sending function is:

bool sentToServer(char* sent, int PORT){
    Log.info("OPENING UDP %d", PORT);
    udp_conn.begin(PORT);
    Log.info("%d Connected: ", PORT);
    Serial.println(Cellular.localIP());
    Serial.flush();
    Log.info("%d SENDPACKET", PORT);
    
    int sentByte = udp_conn.sendPacket(sent, strlen(sent), REMOTE_UDP_ADDR, REMOTE_UDP_PORT);
        
    Log.info("%d OK SENDPACKET", PORT);
    if (sentByte < 0){ //CONNECTION ERROR
        Log.info("%d SendPacket error", PORT);
        udp_conn.stop(); //Close the socket
        delay(2000);
        Log.info("FALSE: CLOSING UDP %d", PORT);
        return false;
    }
    else{ //Packet sent
        Log.info("Byte sent: %d", sentByte);
        delay(100);
        ....waiting for the ACK....

Many times happens that It fails sending the packet even if Cellular.ready is true and I have an IP.
Log calls give me more details about socketSendTo.
It seems like it tries to send the packet without waiting for the UDP.begin succeeded, in fact the log prints:

0000175593 [app] INFO: OK OPENING UDP 60004
0000175593 [app] INFO: 60004 Connected: 10.57.71.130 <---- Cellular has IP. Electron breathes green
0000175593 [app] INFO: 60004 SENDPACKET
socketSendTo(-1,18.184.137.24,60004,,120) <-------- -1??
0000175594 [app] INFO: 60004 SendPacket error
0000177594 [app] INFO: FALSE: CLOSING UDP 60004
0000177694 [app] INFO: OPENING UDP 60004
   177.692 AT send       4 "AT\r\n" <--- New attempt
0000178696 [app] INFO: OK OPENING UDP 60004

Sometimes retrying calling sendToServer() fixes the problem but sometimes doesn’t.
Going in deep_sleep usually restores a working situation. I guess Cellular.disconnect()+Cellular.connect() may work as well but I’d like to have a stable socket…
I’m indoor in my flat in the centre of Bologna with a TM sim card.

How can I better this behaviour?
Thank you

Anyone could help me about this problem? A way to debug it deeply?
Thanks

Hi Gorgo,

You mention you are making use of a third party SIM card, correct? I’m not seeing anything about your keepAlive value. Have you experimented with lowering the keepAlive value from the default 23 minutes that is set by default on Particle devices? Most third party carriers will generally make use of a much lower keepAlive timeout compared to Particle SIM timeouts.

Hi @mstanley,
Isn’t keepAlive() dedicated to keep the connection to the Particle Cloud?
I’m not using the Cloud at all but I’m sending UDP packets to my server.

Hi @Gorgo,

Not necessarily. keepAlive() is actually a value set to prevent the cellular operator/tower from dropping the UDP session with the device after a period of inactivity. Obviously, this has negative impacts on Cloud connectivity – but could absolutely all non-cloud data operations as well.

3 Likes