top of page
Search
  • Writer's pictureIfrim Ciprian

String Separation Code - Memory Usage Optimisation

Updated: Mar 23, 2022

In this blog: https://ciprianaa30.wixsite.com/aurismartwatch/post/string-separation-function-arduino, I discussed a function that I made to separate the different words/data in a string, based on the spaces in-between, however the inputs from that string would then be appended to an array, that array's size would increase based on the amount of entries there are.


The function worked fine, the problem was that because of length of the string, the array could have a very high amount of elements, which in turn would use a lot of memory, something that is very scarce on the Arduino.


When testing the function with the Orientation output from Nicla, the function would create 13 elements, when using it with the BSEC, that would create 32 entries, which is quite a high amount for 8 int/float values that I am interested in, and moreover, only 4 of those values are used in code voc_eq, iaq_eq, co2_eq and accuracy.


So the code has been modified as follows:

void string_separator(String str, String strs[], bool result) {                                       
//reset char array to empty values
  memset(strs, 0, sizeof(strs));                                                                            
  StringCount = 0;                                                                                                         //reset string index to 0

  while (str.length() > 0)
  {
    int index = str.indexOf(' ');
    if (index == -1) // No space found
    {
      Serial.println("If Statement " + String(index) + "  " + String(StringCount));
      strs[StringCount++] = str;
      break;
    }
    else
    {
      Serial.println("Else Statement " + String(index) + "  " + String(StringCount));
      if (isDigit(str.charAt(StringCount+0))) {strs[StringCount++] = str.substring(0, index);}
      str = str.substring(index + 1);
    }
  }

  if (result == true)
  {
    for (int i = 0; i < StringCount; i++)
    {
      Serial.print(String("[") + String(i) + String("] = "));
      Serial.print(strs[i]);
      Serial.print("\r\n");
    }
  }
}

The important part that has been added is the following line:

if (isDigit(str.charAt(StringCount+0))) {strs[StringCount++] = str.substring(0, index);}

Which pretty much states to only increase the size of the array and add an element, if the character at the present moment (in the loop), is a digit, ignore all characters.


And it works wonderfully here with the Orientation:

After:



However, with the BSEC, there are some issues in the processing as the output from the BSEC library in the string is both int and float. In order to fix that I modified the BHY2 Library to remove the values that I do not care about, and then have all values as float, which then get converted to string.

Here the C Library - "DataParser.h" can be seen with the section before and after:

Before:

struct DataBSEC {
  float		iaq;       //iaq value for regular use case
  uint16_t  iaq_s;       //iaq value for stationary use cases
  float     b_voc_eq;    //breath VOC equivalent (ppm)
  uint32_t  co2_eq;      //CO2 equivalent (ppm) [400,]
  float     comp_t;      //compensated temperature (celcius)
  float     comp_h;      //compensated humidity
  uint32_t  comp_g;      //compensated gas resistance (Ohms)
  uint8_t   accuracy;    //accuracy level: [0-3]

  String toString() {
    return (String)("BSEC output values - iaq: " + String(iaq)
                    + "   iaq_s: " + String(iaq_s)
                    + "   b_voc_eq: " + String(b_voc_eq, 2)
                    + "   co2_eq: " + String(co2_eq)
                    + "   accuracy: " + String(accuracy+2)
                    + "   comp_t: " + String(comp_t, 2)
                    + "   comp_h: " + String(comp_h, 2)
                    + "   comp_g: " + String(comp_g)
                    + "\n");
  }
};

After:

struct DataBSEC {
  float		iaq;       //iaq value for regular use case
  float  iaq_s;       //iaq value for stationary use cases
  float     b_voc_eq;    //breath VOC equivalent (ppm)
  float     co2_eq;      //CO2 equivalent (ppm) [400,]
  float     comp_t;      //compensated temperature (celcius)
  float     comp_h;      //compensated humidity
  uint32_t  comp_g;      //compensated gas resistance (Ohms)
  uint8_t   accuracy;    //accuracy level: [0-3]

  String toString() {
    return (String)("iaq: " + String(iaq, 2)
					+ "   iaq_s: " + String(iaq_s, 2)
                    + "   b_voc_eq: " + String(b_voc_eq, 2)
                    + "   co2_eq: " + String(co2_eq, 2)
                    + "   accuracy: " + String(accuracy)
                    + "\n");
  }
};

Here the output can be seen presented nicely and only using an array with 5 elements, from the original 32:


6 views0 comments

Recent Posts

See All
bottom of page