Streamlining from PC serial

I have a program that pulls data from a software api and through USB sends the data to a Nano to control a series of lights. I have a current setup which follows in my C# code which works great, but from what I understand limits my output to 8 variables while I would like to send more. First off, please let me know if I am wrong in that understanding.

Here is the code that I am currently using in Visual Studio that works:

serialdata[0] = 255;
serialdata[1] = Convert.ToByte(var1);
serialdata[2] = Convert.ToByte(var2);
serialdata[3] = Convert.ToByte(var3);
serialdata[4] = Convert.ToByte(var4);
serialdata[5] = Convert.ToByte(var5);
serialdata[6] = Convert.ToByte(var6);
serialdata[7] = Convert.ToByte(var7);

SP.Write(serialdata, 0, 8);

And the Arduino side:

void loop() {
if (Serial.available() > 0) {
if (Serial.available() > 8) {
if (Serial.read() == 255) {
Var1 = Serial.read();
Var2 = Serial.read();
Var3 = Serial.read();
Var4 = Serial.read();
Var5= Serial.read();
Var6 = Serial.read();
Var7 = Serial.read();

The variables are then applied as needed to switch lights on and off based on the value.

Now what I am trying to do in order to send a larger number of variables is write them to a string in visual studio and send them over. I am using this code which I have verified with a serial monitor to be sending the correct string to the serial port:

Send = (Var1 + "," + Var2 + "," + Var3 + "," + Var4 + "," + Var5 + "," + Var6 + "," + Var7);
SP.Write(Send.ToString());

Based on my serial monitor, it is concatenating the screen correctly with the comma delimiting. The plan was to parse the string on the arduino side using an array since it will never be more than 10 values and speed isn't a huge factor. The problem I am encountering seems to be in my arduino code not properly reading the string. I can't use the Arduino serial monitor since the port is already opened from the program, so I can't verify what the variables are. The code I used to parse comes from eecs.blog here https://eecs.blog/sending-multiple-values-over-serial-to-arduino/:

void loop() {

String rxString = "";

if (Serial.available())
{
Var1 = "";

while (Serial.available())
{
delay(2);
char ch =Serial.read();
rxString += ch;
}

int stringStart = 0;
int arrayIndex = 0;

for (int i = 0; i< rxString.length(); i++)
{
if (rxString.charAt(i) == ',')
{
strArr[arrayIndex] = "";
strArr[arrayIndex] = rxString.substring(stringStart,i);
stringStart = (i+1);
arrayIndex++;
}
}

Var1 = strArr[0];
Var2 = strArr[1];
Var3 = strArr[2];
Var4 = strArr[3];
Var5 = strArr[4];
Var6 = strArr[5];
Var7 = strArr[6];

Based on other posts I have read through it seems like this is not the preferred method, but logically it is the method I understand (just not how to get the code to work). If anyone has any ideas on how I could streamline this process or fix what is going on I would really appreciate it. Let me know if you need to see more code, but the rest of it isn't changed in functionality whatsoever.

Thank you for your help!

The String class can cause memory problems. See the Evils of Strings. The serial input basics tutorial shows reliable ways to read serial data without string and in a non-blocking fashion.

groundFungus:
The String class can cause memory problems. See the Evils of Strings. The serial input basics tutorial shows reliable ways to read serial data without string and in a non-blocking fashion.

Great reply; I wish I had read the "Evil of Strings" years ago - it would have saved me numerous days of anguish.

Thanks, I will take a look and see if I can build a better solution with this information.

If you add a nl at the end you can use this code
https://www.forward.com.au/pfod/ArduinoProgramming/Serial_IO/index.html#GPS
based on my SafeStrings library which avoids all the evils of Strings but keeps the convenient functionality

If you don't want to add a newline, you can set a non-blocking timeout for the read()

You can send data in a format that is compatible with the 3rd example in Serial Input Basics with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

You are not limited to a specific number of variables but it would be a good idea to make sure the total message does not exceed 64 bytes.

Note also that the code in Serial Input Basics expects no more than 32 bytes but that can easily be changed.

...R

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