Sending array values over serial?

Hey guys,

I have a few text boxes in VB6, and I'd like to send them all to the Arduino and assign them into an array.

I'm having a pretty hard time understanding exactly how to process serial data from the Arduino, so am asking for a bit of help.

If, for example, I had the numbers: 48, 60, 62, 63, 65, 67, 69, 70, 72, 74 in VB6, and I wanted to send them to the Arduino, and put them into a multidimensional array, how could I send all these numbers at once (Probably with an identifier, so the Arduino knows where they need to go in the array).

I have this code here

   char c, t;
   int nnn;

   if(Serial.available() > 0) // If there is data to read
   {
	 c = Serial.read(); // Get a character

	 delay(50);

	 if(c >= 'a' && c <= 'z') // If it's a command
	 {
	    nnn = 0;
	    while(Serial.available() > 0) // While there is still data
	    {
		 t = Serial.read(); // Read next character

		 if(t == ',' || t == ' ')
		   continue; // Skip commas and spaces
		 if(t >= '0' && t <= '9') // If it's a number
		 {
		    nnn *= 10; // Multiply previous value by 10
		    nnn += t - '0'; // Add the new digit
		 }
		 else
		    break;

		 delay(50);
	    }
	 }
   }

   // Now, do something with c and nnn
   switch(c)
   {
	case 'a':
	  EEPROM.write(1,nnn);
	  break;
	case 'b':
	  EEPROM.write(2,nnn);
	  break;
   }

However, for my application, I'd require almost 42 different letters for my application!

So basically, a string of numbers and an identifier sent over serial, processed by an Arduino and dumped into an array? Is it possible to send all the numbers at once?

For example, if I send: a, 48, 60, 62, 63, 65, 67, 69, 70, 72, 74
Over serial, the Arduino would know to put it in the first "dimension" of the array, and the numbers are the 10 data values for that dimension.

Cheers,
Dan

Is it possible to send all the numbers at once?

No. Serial data transmission takes time. If you mean "all the numbers, one after another, as fast as possible", then the answer is yes.

How you do that is a VB issue, though.

How you receive data on the Arduino depends on how you send it from the VB app.

You need to keep the cart and the horse in the right order.

Yes, sorry, by all at once I meant in just a big stream.

I have code in VB that will send the serial data in whatever form I want, that is not an issue.

It's just getting the Arduino to determine which dimension to put the data in, and what all the values are.

That code in the post above, I'm pretty sure you wrote for me a while ago.

Basically, I'd need just an extended version of that. So it could take a single letter, followed by say 10 values, seperated by commas.

For example, a would be the switch,

Then 48 would go in variable1, 60 in variable2 (May be up to triple digit numbers, though, thus wanting to use commas as seperators)

OK, I'll make up 10 numbers here (10 will be the max)

48, 60, 62, 123, 65, 67, 114, 70, 110, 74

Now, I need to somehow get these numbers from serial, into a multidimensional array. Using that code above, I could use a letter identifier, to specify which dimension.

For example, a = dimension 1, b = dimension 2 etc

Now, I can get VB to send those numbers, with the identifier infront, so

a, 48, 60, 62, 123, 65, 67, 114, 70, 110, 74

The letter a is stored to a variable, and then used in that switch to determine which dimension these values go into.

So now, the Arduino stores 48 to a variable, then it see's the comma, so stores 60 to a new variable, another comma so stores 62 to a new variable, then 123 etc.

Hopefully that clarifies a bit better.

Thanks for helping :slight_smile:

I have code in VB that will send the serial data in whatever form I want, that is not an issue.

OK. So, make VB output the data in the form you want. Then, we can work on parsing that form on the Arduino.

If VB spits out "A:8, 10, 20, 30, 40, 100, 200, 300, 400" this would mean that there are 8 values to be stored in an array.

Once all the data has been received by the Arduino, and stored in an array, the strtok() function can be used to parse the code (It would return "A", "8", "10", "20", etc.) and atoi() can be used to convert the tokens to numbers.

All that is left is to define whether the Arduino should create a new array, or simply store the values in an existing array. If it is to use an existing array, is there room for the number of values to be sent, and which array would it be writing to.

Sorry, added a bit more information about what I was hoping to achieve in my above post before realizing you had posted.

Over serial, the Arduino would know to put it in the first "dimension" of the array, and the numbers are the 10 data values for that dimension.

Maybe a bit less handwaving, and a bit more specificity is called for.

If the data is to be stored in a 2D array, for instance, one would have to know whether the data was to be stored in row N or column N, and what the value of N is. Talk about storing something in the 1st dimension of an array doesn't make sense.

I'm talking about an array like this:

byte array[3][10] = {
  {variable1, variable2, variable3, variable4, variable5, variable6, variable7, variable8, variable9, variable10},   // Go here if identifier = a
  {variable1, variable2, variable3, variable4, variable5, variable6, variable7, variable8, variable9, variable10},   // Go here if identifier = b
  {variable1, variable2, variable3, variable4, variable5, variable6, variable7, variable8, variable9, variable10}    // Go here if identifier = c
};

If I did it this way, I could fill the entire array row by row, specified by an identifier, followed by values.

This array would already exist, always have 3 rows, and always be filled with 10 values per row.

If I send these from VB:

a, 36, 41, 43, 44, 46, 48, 49, 51, 53, 55
b, 35, 47, 54, 55, 57, 59, 60, 61, 62, 64
c, 48, 60, 62, 63, 65, 67, 69, 70, 72, 74

The array would look like this:

byte array[3][10] = {
  {36, 41, 43, 44, 46, 48, 49, 51, 53, 55},   
  {35, 47, 54, 55, 57, 59, 60, 61, 62, 64},   
  {48, 60, 62, 63, 65, 67, 69, 70, 72, 74}    
};

Thanks again :slight_smile:

I think, like your recent EEPROM question, the answer lies in "for" loops.

The problem is, I really have no idea how to implement this stuff. The Arduino reference is great n all, though I'm having troubles piecing it all together for my application. 

Like, this code here does what I want,

[code[   char c, t;
   int nnn;

   if(Serial.available() > 0) // If there is data to read
   {
	 c = Serial.read(); // Get a character

	 delay(50);

	 if(c >= 'a' && c <= 'z') // If it's a command
	 {
	    nnn = 0;
	    while(Serial.available() > 0) // While there is still data
	    {
		 t = Serial.read(); // Read next character

		 if(t == ',' || t == ' ')
		   continue; // Skip commas and spaces
		 if(t >= '0' && t <= '9') // If it's a number
		 {
		    nnn *= 10; // Multiply previous value by 10
		    nnn += t - '0'; // Add the new digit
		 }
		 else
		    break;

		 delay(50);
	    }
	 }
   }

   // Now, do something with c and nnn
   switch(c)
   {
	case 'a':
	  EEPROM.write(1,nnn);
	  break;
	case 'b':
	  EEPROM.write(2,nnn);
	  break;
   }

I just need help modifying it to put more than 1 number into different variables. But, because it picks up a new character each time, it can't start reading the new number until the previous one is complete, but then you also don't know whether it's going to be 2 or 3 digits.

Also, thought I'd mention, getting the identifier to relate to a row in the array isn't needed. As these variables will be stored to eeprom, they can just be read back into the array in their appropriate rows. I just need something that'll put the letter, and all the numbers into seperate variables :slight_smile:

Thanks

In the code that you have:

		 if(t == ',' || t == ' ')
		   continue; // Skip commas and spaces
		 if(t >= '0' && t <= '9') // If it's a number
		 {
		    nnn *= 10; // Multiply previous value by 10
		    nnn += t - '0'; // Add the new digit
		 }

When t is a comma or space, you know you have a complete value in nnn. By counting the commas or spaces, you know which column to store nnn in. So, get rid of the continue. You have something to do there.

OK, I think I see where this is going. How do you increment variables, so to speak?

Since I need say, 10 instances of nnn to store the 10 lots of numbers ?

EDIT: I just tried this, but keep getting huge values on totalval??

void loop(){

   char c, t;
   int nnn;

   if(Serial.available() > 0) // If there is data to read
   {
	 c = Serial.read(); // Get a character


	 delay(50);

	 if(c >= 'a' && c <= 'z') // If it's a command
	 {
	    nnn = 0;
	    while(Serial.available() > 0) // While there is still data
	    {
		 t = Serial.read(); // Read next character

		 if(t == ',' || t == ' '){
                   totalvals = ++totalvals;
                   continue;
}
		 if(t >= '0' && t <= '9') // If it's a number
		 {
		    nnn *= 10; // Multiply previous value by 10
		    nnn += t - '0'; // Add the new digit
		 }
		 else
		    break;
                    Serial.print(totalvals);

		 delay(50);
	    }
            if (totalvals == 1){
              bankval1 = nnn;
              nnn = 0;
            }
            if (totalvals == 2){
              bankval2 = nnn;
              nnn = 0;
            }
            if (totalvals == 3){
              bankval3 = nnn;
              nnn = 0;
            }
            if (totalvals == 4){
              bankval4 = nnn;
              nnn = 0;
            }
            if (totalvals == 5){
              bankval5 = nnn;
              nnn = 0;
            }
            if (totalvals == 6){
              bankval6 = nnn;
              nnn = 0;
            }
            if (totalvals == 7){
              bankval7 = nnn;
              nnn = 0;
            }
            if (totalvals == 8){
              bankval8 = nnn;
              nnn = 0;
            }
            if (totalvals == 9){
              bankval9 = nnn;
              nnn = 0;
            }
            if (totalvals == 10){
              bankval10 = nnn;
              nnn = 0;
              totalvals = 0;
            }
          Serial.print("Command:");
          Serial.println(c);
          Serial.print("Val1:");
          Serial.println(bankval1);
          Serial.print("Val2:");
          Serial.println(bankval2);
          Serial.print("Val3:");
          Serial.println(bankval3);
          Serial.print("Val4:");
          Serial.println(bankval4);
          Serial.print("Val5:");
          Serial.println(bankval5);
          Serial.print("Val6:");
          Serial.println(bankval6);
          Serial.print("Val7:");
          Serial.println(bankval7);
          Serial.print("Val8:");
          Serial.println(bankval8);
          Serial.print("Val9:");
          Serial.println(bankval9);
          Serial.print("Val10:");
          Serial.println(bankval10);
          
	 }
   }

Yeah, completely lost at this stage. Am I even on the right track? :frowning:

Thanks

How do you increment variables, so to speak?

n++;
n = n + 1;
n += 1;

Pick the style you like.

Since I need say, 10 instances of nnn to store the 10 lots of numbers ?

Why? You are only dealing with one number at a time from the serial stream.

                   totalvals = ++totalvals;

++totalvals is equivalent to totalvals = totalvals + 1, so that statement is equivalent to

                   totalvals = totalvals = totalvals +1;

Notice anything unnecessary there?

Where does totalvals get set initially or reset?

totalvals gets reset down near the bottom, when it reaches 10 in value (Signifying it has the 10 values?)

It is set to 0 at the start of the code, which I didn't post to save space.

If I change totalvals to just ++totalvals, and send a, 36, 41, 43, 44, 46, 48, 49, 51, 53, 55 I get this in return:

22446688101012121414161618182020Command:a
Val1:0
Val2:0
Val3:0
Val4:0
Val5:0
Val6:0
Val7:0
Val8:0
Val9:0
Val10:0

Totalvals seem to be picking up extra numbers from somewhere. If I send: b,1 I get Command: b Val1: 1 , and totalvals = 1.

But then if I send: b,1,2 , suddenly totalvals = 12 and Val2:23 (This is resetting the Arduino each time, so totalvals is reset to zero.

Thanks,
Dan

I can't see what speed you're running the serial line at, but, assuming 9600 bps, for every character that you receive, you're waiting long enough to receive nearly another 50.
That could mean you'll run out of receiver buffer rather quickly.

I think your handling of comma and space is flawed.

What I don't understand is, totalvals is incremented only when a comma or space is in the data. If I only send it 3 commas and no spaces, where is it getting all the extra values from??

totalvals is incremented only when a comma or space is in the data

No, look at your logic (and input data) again

Where are you printing totalvals? The Serial.print(totalvals); after the break; in the while loop is never executed (the break statement exits the while loop).

OK, I think I'm starting to get somewhere now.

Here is the code:

int bankval1;
int bankval2;
int bankval3;
int bankval4;
int bankval5;
int bankval6;
int bankval7;
int bankval8;
int bankval9;
int bankval10;
int totalvals = 0;

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

   char c, t;
   int nnn;

   if(Serial.available() > 0) // If there is data to read
   {
	 c = Serial.read(); // Get a character


	 delay(50);

	 if(c >= 'a' && c <= 'z') // If it's a command
	 {
	    nnn = 0;
	    while(Serial.available() > 0) // While there is still data
	    {
		 t = Serial.read(); // Read next character

		 if(t == ','){
                   ++totalvals; 
                   continue;
                  }
		 if(t >= '0' && t <= '9') // If it's a number
		 {
		    nnn *= 10; // Multiply previous value by 10
		    nnn += t - '0'; // Add the new digit
		 }

                    else
		    break;
             if (totalvals == 1){
              bankval1 = nnn;
              nnn = 0;
            }
            if (totalvals == 2){
              bankval2 = nnn;
              nnn = 0;
            }
            if (totalvals == 3){
              bankval3 = nnn;
              nnn = 0;
            }
            if (totalvals == 4){
              bankval4 = nnn;
              nnn = 0;
            }
            if (totalvals == 5){
              bankval5 = nnn;
              nnn = 0;
            }
            if (totalvals == 6){
              bankval6 = nnn;
              nnn = 0;
            }
            if (totalvals == 7){
              bankval7 = nnn;
              nnn = 0;
            }
            if (totalvals == 8){
              bankval8 = nnn;
              nnn = 0;
            }
            if (totalvals == 9){
              bankval9 = nnn;
              nnn = 0;
            }
            if (totalvals == 10){
              bankval10 = nnn;
              nnn = 0;
              totalvals = 0;
            }
		 delay(50);
	    }
          Serial.print(totalvals);
          Serial.print("Command:");
          Serial.println(c);
          Serial.print("Val1:");
          Serial.println(bankval1);
          Serial.print("Val2:");
          Serial.println(bankval2);
          Serial.print("Val3:");
          Serial.println(bankval3);
          Serial.print("Val4:");
          Serial.println(bankval4);
          Serial.print("Val5:");
          Serial.println(bankval5);
          Serial.print("Val6:");
          Serial.println(bankval6);
          Serial.print("Val7:");
          Serial.println(bankval7);
          Serial.print("Val8:");
          Serial.println(bankval8);
          Serial.print("Val9:");
          Serial.println(bankval9);
          Serial.print("Val10:");
          Serial.println(bankval10);
          
	 }
   }

   // Now, do something with c and nnn
   switch(c)
   {
	case 'a':
          break;
	case 'b':
	  break;
   }
}

If I input b,1,2,3,4,5,6,7,8,9,10

I get:

0Command:b
Val1:1
Val2:2
Val3:3
Val4:4
Val5:5
Val6:6
Val7:7
Val8:8
Val9:9
Val10:1

So it appears I'm just not getting all the values yet.

Thanks

Aha, got it! :smiley: :smiley:

int bankval1;
int bankval2;
int bankval3;
int bankval4;
int bankval5;
int bankval6;
int bankval7;
int bankval8;
int bankval9;
int bankval10;
int totalvals = 0;

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

   char c, t;
   int nnn;

   if(Serial.available() > 0) // If there is data to read
   {
	 c = Serial.read(); // Get a character


	 delay(50);

	 if(c >= 'a' && c <= 'z') // If it's a command
	 {
	    nnn = 0;
	    while(Serial.available() > 0) // While there is still data
	    {
		 t = Serial.read(); // Read next character

		 if(t == ','){
                   ++totalvals; 
                   continue;
                  }
		 if(t >= '0' && t <= '9') // If it's a number
		 {
                    if (totalvals == 1){
		    bankval1 *= 10; // Multiply previous value by 10
		    bankval1 += t - '0'; // Add the new digit
                    }
                                        if (totalvals == 2){
		    bankval2 *= 10; // Multiply previous value by 10
		    bankval2 += t - '0'; // Add the new digit
                    }
                                        if (totalvals == 3){
		    bankval3 *= 10; // Multiply previous value by 10
		    bankval3 += t - '0'; // Add the new digit
                    }
                                        if (totalvals == 4){
		    bankval4 *= 10; // Multiply previous value by 10
		    bankval4 += t - '0'; // Add the new digit
                    }
                                        if (totalvals == 5){
		    bankval5 *= 10; // Multiply previous value by 10
		    bankval5 += t - '0'; // Add the new digit
                    }
                                        if (totalvals == 6){
		    bankval6 *= 10; // Multiply previous value by 10
		    bankval6 += t - '0'; // Add the new digit
                    }
                                        if (totalvals == 7){
		    bankval7 *= 10; // Multiply previous value by 10
		    bankval7 += t - '0'; // Add the new digit
                    }
                                        if (totalvals == 8){
		    bankval8 *= 10; // Multiply previous value by 10
		    bankval8 += t - '0'; // Add the new digit
                    }
                                        if (totalvals == 9){
		    bankval9 *= 10; // Multiply previous value by 10
		    bankval9 += t - '0'; // Add the new digit
                    }
                                        if (totalvals == 10){
		    bankval10 *= 10; // Multiply previous value by 10
		    bankval10 += t - '0'; // Add the new digit
                    }
		 }

                    else
		    break;
		 delay(50);
	    }
          totalvals = 0;
          Serial.print(totalvals);
          Serial.print("Command:");
          Serial.println(c);
          Serial.print("Val1:");
          Serial.println(bankval1);
          Serial.print("Val2:");
          Serial.println(bankval2);
          Serial.print("Val3:");
          Serial.println(bankval3);
          Serial.print("Val4:");
          Serial.println(bankval4);
          Serial.print("Val5:");
          Serial.println(bankval5);
          Serial.print("Val6:");
          Serial.println(bankval6);
          Serial.print("Val7:");
          Serial.println(bankval7);
          Serial.print("Val8:");
          Serial.println(bankval8);
          Serial.print("Val9:");
          Serial.println(bankval9);
          Serial.print("Val10:");
          Serial.println(bankval10);
          
	 }
   }

   // Now, do something with c and nnn
   switch(c)
   {
	case 'a':
          break;
	case 'b':
	  break;
   }
}

It's very messy, but it works :smiley:

Thanks guys :slight_smile: