Why is parseInt so Slow? Alternatives?

   while (!lora.available()) {}    //Loop here until data is available.
ET=millis();  
//From here to "incomingString" = 21mS.
    fromID = lora.parseInt(SKIP_ALL, '\n');
    len = lora.parseInt(SKIP_ALL, '\n');
    SonarEcho = (lora.parseInt(SKIP_ALL, '\n')) / 2;
    RSSI = lora.parseInt(SKIP_ALL, '\n');
    SNR = lora.parseInt(SKIP_ALL, '\n');
    Distance = map(SonarEcho, crest, trough, 0, 48);  //Scale echo time for graphing.
Serial.println(millis() - ET); 
    incomingString = lora.readString();  //9mS 

I'm receiving this string from a LoRa module (10 samples/sec):
+RCV=1,4,3996,-34,13

I stumbled on "parseInt" and used it to extract the numeric fields from the string. Works as expected, except it's slow as molasses. 21mS to extract 5 fields. Why is it so slow and is there a better way? (I'm running out of time and if I don't trim down the processing time I'm afraid I wont have enough time to do what else needs to be done in my loop.)

For LoRa there is an 0.1% and 1.0% duty cycle per day depending on the channel. 10Hz is high


if you know the packet you receive holds "+RCV=1,4,3996,-34,13" then keep It simple. read the payload into a buffer and use sscanf() to extract the elements. Reading from the "stream" might not be the most effective way to solve this.

if you have a c-string, you could extract the content with sscanf(). the function is pretty versatile and tells you if the parsing was matching the expected format.

here is something to try:

void setup() {
  Serial.begin(115200);

  int fromID;
  int len;
  int sonarEcho;
  int rssi;
  int snr;
  char message[] = "+RCV=1,4,3996,-34,13"; // canned response for testing purpose

  int pos = 0;
  if (sscanf(message, "+RCV=%d,%d,%d,%d,%d", &fromID, &len, &sonarEcho, &rssi, &snr) == 5) {
    // we could read the 5 parameters based on the format
    Serial.print("fromID: ");     Serial.println(fromID);
    Serial.print("len: ");        Serial.println(len);
    Serial.print("sonarEcho: ");  Serial.println(sonarEcho);
    Serial.print("rssi: ");       Serial.println(rssi);
    Serial.print("snr: ");        Serial.println(snr);
  } else {
    Serial.print("Error parsing message: "); Serial.println(message);
  }
}

void loop() {}

so if you want to apply that to LoRa then just do something like this

void loop() {
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    int fromID;
    int len;
    int sonarEcho;
    int rssi;
    int snr;

    Serial.print("Received packet '");
    char message[packetSize + 1]; // +1 for trailing null char
    int pos = 0;
    while (LoRa.available()) message[pos++] = (char) LoRa.read();
    message[pos] = '\0'; // "+RCV=1,4,3996,-34,13"
    if (sscanf(message, "+RCV=%d,%d,%d,%d,%d", &fromID, &len, &sonarEcho, &rssi, &snr) == 5) {
      // we could read the 5 parameters based on the format
      Serial.print("fromID: ");     Serial.println(fromID);
      Serial.print("len: ");        Serial.println(len);
      Serial.print("sonarEcho: ");  Serial.println(sonarEcho);
      Serial.print("rssi: ");       Serial.println(rssi);
      Serial.print("snr: ");        Serial.println(snr);
    } else {
      Serial.print("Error parsing message: "); Serial.println(message);
    }
  }
}

For what it's worth, compared to an Arduino running non-blocking code (like parseInt and delay), serial speeds are dead slow to slow.

You have time between received chars to process the message and still do other tasks even at 250000 baud, 40 usec intervals are 640 cycles on a CPU that does most operations in 1 or 2 cycles.

If you process chars you should have your answer very close on the arrival of the last message char arriving. I'm not joking or guessing, I've done it with parse and lex text to match words and put examples up here, 9us per char matched on average let me parse on the fly at 25000 cps.

It's possible but you have to get real serious and then still have to (as the programming adage goes) write the program twice and throw the first one out. I picked that up from the inventor of Pascal when he introduced Modula 2 and stated that Pascal was his first attempt and should be thrown out in a 1985 issue of Byte Magazine. Ever heard of Modula or Pascal?

Couldn’t have agreed more.
At the time Pascal was like Python is nowadays… a great teaching language, with strict structure, and quite easy to learn, but there are far better options for hard core coding.

1 Like

I have helped fix bugs in school Pascal for a friend but like COBOL, the language is too "retentive" for my liking. AFAIK more people have heard of Pascal than Modula.

I really appreciate the help guys. Right now I don't know what I'm going to do - leave it the way it is, or undertake one of your suggestions. If I leave it, I have 20mS to do what I need to do. I'll finish that then I'll know which way to go.

And yes, I remember Pascal, all too well. :slight_smile:

I bought a Forth79 cartridge for my VIC-20. It's a very unique language, fit on an 8K ROM with editor and I learned to write self-extending code, it was my No-Rails intro to Object Oriented Programming, it literally changed how I wrote in every language i knew!

Forth.com has free Forth and PDF of the book I paid $35 for in 83, Starting Forth. If you don't like the more conventional languages, Forth is different.

My favorite language of all time.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.