Language: EN

arduino-array-separado-comas

Comma separated array over serial port in Arduino

We have a series of entries aimed at deepening the use of the serial port in a processor like Arduino. In this post we will see how to receive a comma-separated array.

Previously we have seen how to receive characters and text strings, and how to receive integer and floating point numbers. Along with these, receiving a comma-separated array is another of the most common requests regarding the use of the serial port.

Of course, although we refer to a comma-separated array, the code is extendable to any other separator, such as a period, semicolon, or any other character that is needed.

But, before addressing the problem, it is worth reflecting on why you want to receive a comma-separated array. If what we want is to send/receive a series of elements (ints, floats…) between two devices, it is better to define a frame and send the bytes directly.

If out of ignorance (or laziness), we are going to send a series of elements as a comma-separated array and then perform the text conversion, we are making the process inefficient unnecessarily, both in speed and processor load.

Therefore, we should not use a comma-separated array when we control both agents (transmitter and receiver). Furthermore, in this case, we should never send anything other than bytes. That’s right, big boys send bytes.

Unfortunately, we do not always have the possibility to define the message sent/received. Sometimes the frame will be defined by a device, or a service with which we want to communicate. In that case, yes, we will have no choice but to deal with the comma-separated array (or the separator that applies).

Fortunately, it is not a complicated process. As in the previous entries, there is more than one way to carry out the process, with its advantages and disadvantages. Here’s how to receive the array with the help of the String class and “by hand”.

In the examples, we are going to use an array of int because it is the simplest and most common case, although it is easy to modify it to receive a float or another type of variables.

The DEBUG functions are only for visualizing the results, when you use this code you can remove the parts related to its definition and use.

Receiving with the String class

The first method we are going to use the String class, to receive, split the array and perform the conversion.

First, we read an entire line with Serial.readStringUntil(). Subsequently, we divide and convert the string using the functions of the String class.


#define DEBUG_ARRAY(a) {for (int index = 0; index < sizeof(a) / sizeof(a[0]); index++)   {Serial.print(a[index]); Serial.print('\t');} Serial.println();};

String str = "";
const char separator = ',';
const int dataLength = 3;
int data[dataLength];

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available())
  {
    str = Serial.readStringUntil('\n');
    for (int i = 0; i < dataLength ; i++)
    {
      int index = str.indexOf(separator);
      data[i] = str.substring(0, index).toInt();
      str = str.substring(index + 1);
    }
    DEBUG_ARRAY(data);
  }
}

This method is simple and efficient, and should be the preferred option for receiving comma-separated arrays.

Receiving with char array and naive method

If we cannot or do not want to use the functions of the String class, we can carry out the process “by hand”, which we have already become accustomed to calling in previous entries the “naive” method.


#define DEBUG_ARRAY(a) {for (int index = 0; index < sizeof(a) / sizeof(a[0]); index++)   {Serial.print(a[index]); Serial.print('\t');} Serial.println();};

String str = "";
const char separator = ',';
const int dataLength = 3;
int dataArray[dataLength];
int data = 0;
int dataIndex = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  while (Serial.available())
  {
    char incomingChar = Serial.read();
    if (incomingChar >= '0' && incomingChar <= '9')
    {
      data = (data * 10) + (incomingChar - '0');
    }
    else if (incomingChar == separator)
    {
      dataArray[dataIndex] = data;
      if (++dataIndex >= dataLength) dataIndex = 0;
      data = 0;
    }
    else if (incomingChar == '\n')
    {
      dataArray[dataIndex] = data;
      data = 0;
      dataIndex = 0;
      DEBUG_ARRAY(dataArray);
    }
  }
}

The process is not much more complex, although the code is longer, so we should only use it when it is really not possible to use the String class.

EasyComma library

And if we put it in a library? Of course, we can! Here is the EasyComma library, which allows us to read a series of integers delimited by a separator (by default the comma) comfortably and simply. Enjoy!.

Download the code

All the code from this post is available for download on Github. github-full