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:

Comments