2 way serial arduino to vb6

Hello,

I am almost there with the code but last part fails.

I switch the Arduino on and it reads data from the eeprom.
I switch on VB program and by USB cable it copies data to some text boxes from Arduino to the program.

Then I send by button command from VB6 a single string of 7 variables to the Arduino.

Arduino receives the data but not all data now changes correctly.

VB code

Private Sub cmdSendDataToController_Click()
strOutput = "10,2,3,4,5,6,11:"
MSComm1.Output = strOutput
End Sub

Arduino code

const int NUMBER_OF_FIELDS = 7; // how many comma separated fields we expect
int fieldIndex = 0;            // the current field being received
int values[NUMBER_OF_FIELDS];   // array holding values for all the fields

void loop
if( Serial.available())
  {
    char ch = Serial.read();
    if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
    {
      // yes, accumulate the value
      values[fieldIndex] = (values[fieldIndex] * 10) + (ch - '0'); 
    }
    else if (ch == ',')  // comma is our separator, so move on to the next field
    {
      if(fieldIndex < NUMBER_OF_FIELDS-1)
        fieldIndex++;   // increment field index
    }
    else
    {
      // any character not a digit or comma ends the acquisition of fields
      for(int i=0; i <= fieldIndex; i++)
      {
        deadbandxValue = (values[0]);
        //brakeregenValue = (values[1]);
        //regbrakeState = (values[2]);
        //regenhyValue = (values[3]);
        //brakespeedValue = (values[4]);
        //brakespeedState = (values[5]);
        modelNumber = (values[6]);
        values[i] = 0; // set the values to zero, ready for the next message
      }
      fieldIndex = 0;  // ready to start over
      }
  }

deadbandxValue = (values[0]); parses 0 back to the vb program which should be 10!
modelNumber = (values[6]); correctly parses 11 back to the vb program.

Is there something I overlook as the array spliting is working partialy?
for some reason it only reads the last variable in the array.

Paco

I haven't test your version of ASCII digits for 0-9, but here is what I used and it works:

if ((ch>47)&&(ch<58))
{
             int actual_digit = ch-48;
             // do something iwth actual digit
}

Or, more intuitively:

if ((ch>='0')&&(ch<='9'))
{
             int actual_digit = ch-'0';
             // do something with actual digit
}

or even

if (isdigit(ch))
{
             int actual_digit = ch-'0';
             // do something with actual digit
}
      for(int i=0; i <= fieldIndex; i++)
      {
        deadbandxValue = (values[0]);
        //brakeregenValue = (values[1]);
        //regbrakeState = (values[2]);
        //regenhyValue = (values[3]);
        //brakespeedValue = (values[4]);
        //brakespeedState = (values[5]);
        modelNumber = (values[6]);
        values[i] = 0; // set the values to zero, ready for the next message
      }

On the first pass through this loop, think about what is in values[0] that is being assigned to deadbandxValue.

Then, what happens to values[ i ] at the end of loop?

Then, what is assigned to deadbandxValue on the next pass? And the one after that.

Why is the use of values[ i ] done inside the loop? That makes no sense, really.

const int NUMBER_OF_FIELDS = 7; // how many comma separated fields we expect
...
int values[NUMBER_OF_FIELDS];   // array holding values for all the fields
...
for(int i=0; i <= fieldIndex; i++)

Oops. try for(int i=0; i < fieldIndex; i++)

For what it is worth.

here the link from where I got the lead source for getting the data to the array.
http://my.safaribooksonline.com/9781449399368/sending_multiple_text_fields_from_ard#X2ludGVybmFsX0h0bWxWaWV3P3htbGlkPTk3ODE0NDkzOTkzNjglMkZyZWNlaXZpbmdfbXVsdGlwbGVfdGV4dF9maWVsZHNfaW5fYV9zJnF1ZXJ5PQ==

I expected this to work flawlessly after some changes but it is not. :frowning:

Will check all your answers and the options to see if I can manage to solve it.

Let you know the result.

Thanks, Paco

Someone should fire the proofreader.

I expected this to work flawlessly after some changes but it is not.

The "changes" you made introduced some of the problems you are having.

Have we ruled out a problem on the sending side?

Opening the serial port from the PC side resets the arduino. The Arduino isn't running your program for a couple seconds after reset. So, if you open the port and write to it right away / without a delay, some of the sent output gets dropped on the floor (by the bootloader).

If you don't delay after opening the port, it might be worth a try. And could you post your whole sending-side code?

-br

OK,

Thanks for all replies and suggestions.
Two steps forward one step back.
PaulS his comment was something I already tried but did not solved the problem this morning while debugging.

values[i] = 0; // set the values to zero, ready for the next message

But reading once again he was rigth it does not belong there so I commented the line and it worked.

After start up of Arduino and VB program and I hit the VB data write button now all the values are set correctly in the Arduino variables and are returned to the VB program correctly.
So I though YES..........but,
When I in the VB program hit the button again with the same values it looks like the serial buffer was not cleared and random data is received and returned to the VB program.
From what I have read as soon as serial.read is called it clears the buffer and the next call to the buffer should be correct but it is not.

Paco

From what I have read as soon as serial.read is called it clears the buffer and the next call to the buffer should be correct but it is not.

It removes the character read from the serial buffer. It does not clear all the rest of the data, and it does not clear the buffer you are writing to.

I don't know how you changed the code, but it should be:

        deadbandxValue = (values[0]);
        //brakeregenValue = (values[1]);
        //regbrakeState = (values[2]);
        //regenhyValue = (values[3]);
        //brakespeedValue = (values[4]);
        //brakespeedState = (values[5]);
        modelNumber = (values[6]);

        for(int i=0; i <= fieldIndex; i++)
        {
          values[i] = 0; // set the values to zero, ready for the next message
        }
for(int i=0; i <= fieldIndex;

No, really, no.

Yeah, yeah.

        for(int i=0; i < fieldIndex; i++)
        {
          values[i] = 0; // set the values to zero, ready for the next message
        }

With the current code this is the behavior.

Start arduino and data is read from EEPROM to variables.
I start the VB program and it reads the data that during setup of arduino is written from the EEPROM into the variables of the Arduino.
Sofar so good.
I press the VB button and voila the code changes in VB to the required setting. Still good.
Then I press the VB button again with same combobox settings and thevalues of the variables of the arduino are those as if they are read again from the EEPROM.
Strange as it does not read the EEPROM values in the void loop........only once in the void setup.

if( Serial.available())
  {
    char ch = Serial.read();
    if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
    {
      // yes, accumulate the value
      values[fieldIndex] = (values[fieldIndex] * 10) + (ch - '0'); 
    }
    else if (ch == ',')  // comma is our separator, so move on to the next field
    {
      if(fieldIndex <= NUMBER_OF_FIELDS-1)
        fieldIndex++;   // increment field index
    }
    else
    {
      deadbandxValue = (values[0]);
      brakeregenValue = (values[1]);
      regbrakeState = (values[2]);
      regenhyValue = (values[3]);
      speedbrakeValue = (values[4]);
      speedbrakeState = (values[5]);
      modelNumber = (values[6]);

      for(int i=0; i <= fieldIndex; i++)
      {
        values[i] = 0; // set the values to zero, ready for the next message
      }
    }
  }

Knipsel2.jpg shows the two collums with on the left hand side the text boxes that read the data from the variabels from the Arduino.
The right hand side collum has the combo boxes with the new values that need to be send to the Arduino and again need to be returned into the text boxes of the VB APP. This picture shows the data before the button is pressed and EEPROM data.
Knipsel.jpg is the after the button is pressed once and the EEPROm data is overwritten.

for(int i=0; i <= fieldIndex

When I said "no", I really meant it.

PaulS and AWOL,

I tried all your options if I understand correctly what you both mean.

I changed from for(int i=0; i <= fieldIndex; i++)
to for(int i=0; i <= fieldIndex
but that gives an compile error as there is no round brakcet at the end.
So I made it for(int i=0; i <= fieldIndex;) I even removed the whole line.
All giving the same result as described in my previous post.

I might misunderstand your way of thinking and the way you try to descibe it to me.

Paco

The test is "less than", not "less than or equal to".

for(int i=0; i < fieldIndex; i++)

If you use "less than or equal to", you will write past the end of your array, which is a Bad Thingtm

The example in the book is wrong too, which is why I said the proofreader should be fired.

I changed to for(int i=0; i < fieldIndex; i++)

Now I see what you tried to tell.
But same problem still.

Paco

So, post your code.

AWOL,

Whole code too large to put it in the response code tags.
Have it zipped.

Thanks for looking in advance.
Curious where I made a mistake.

Paco

slotracecontroller_nano_71_16x2_display.zip (4.96 KB)