Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Pages: [1]   Go Down
Author Topic: Interaction with Visual Basic 2010  (Read 1336 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am trying to control stepper motors from visual basic 2010.

I am having trouble either reading the number of bytes, or setting the delay time on arduino.
On VB,
Code:
Dim message As String = "11"
If drawing Then
         Dim j As Integer
          For j = 1 To Len(message)
                Printer.Write(message)
          Next j
          Threading.Thread.Sleep(2000)
End If

Arduino->
Code:
void loop()
{
    if(Serial.available()>0){
      steps=0;
      while(Serial.available()>0){
        incomingbyte=Serial.read();
        *tmp=incomingbyte;
        int digit=atoi(tmp);
        if(steps!=0){
          steps=steps*10;
        }
        steps=steps+digit;
      }
     
     Serial.write(steps);
     motor1.step(steps,FORWARD,SINGLE);
     delay(10);
     
    }
}
 

When the message is one byte, "1" to "9" it works perfectly.
When "10" is sent, the motors moves a lot more than 10.
For self-feedback, Serial.write(steps) returns the desired value, but when 10 is sent out from VB, i get back 10, 1, 10, 1....
When 11 is sent, i get back 111, 1, 111, 1...

I am not sure where or how it went wrong. Please help me.

thank you!
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 131
Posts: 8690
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You're only reading a single byte then the while loop will exit because it's done the work before the next char arrived.

Try something like

Code:
    if(Serial.available()>= 2){
      steps=0;
        *tmp++ = Serial.read();
        *tmp++ = Serial.read();
        *tmp = '\0';
        int digit=atoi(tmp);
        if(steps!=0){
          steps=steps*10;
        }
        steps=steps+digit;
      }

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried to add delay in the while loop but the code didn't work well.
Sometimes more than 3 bytes will be sent so I don't want to restrict to Serial.available() >= number..

Thank you!
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 131
Posts: 8690
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Sometimes more than 3 bytes will be sent
How many?

If we're just looking and a number then send it in binary so the number of characters is always the same.

OR

Continue sending as ASCII but 0 fill, ie "023" instead of "23" then you know how many chars you will get,

OR

Send a delimiter so you know when the data has finished.

Also I just noticed

Code:
         For j = 1 To Len(message)
                Printer.Write(message)
          Next j

This will send the string twice. The longer the string the more times it gates sent.

______
Rob

Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

At first, I just had Printer.Write(message), but it only sent the first digit of the message. I thought that was weird, but it just didn't work without the loop.

From the code you gave me, I modified it so that it fits in all cases
Code:
data=Serial.available();
      if (data>0){
          int i;
        for(i=0;i<data;i++){
        *tmp++=Serial.read();
        }
        *tmp='\0';
        steps=atoi(tmp);
      }
     Serial.write(steps);
     motor1.step(steps,FORWARD,SINGLE);
     delay(10);

This didn't work, so I just added your code with the original one
Code:
  steps=0;
    if(Serial.available()>1){
        *tmp++=Serial.read();
        *tmp++=Serial.read();
        *tmp='\0';
        steps=atoi(tmp);
      }
    else if(Serial.available()>0){
      while(Serial.available()>0){
        incomingbyte=Serial.read();
        *tmp=incomingbyte;
        steps=atoi(tmp);
        //delay(100);
      }
    }

and it works for one digit. it works for 2 digit ONCE (sometimes).
I began to think something is wrong with the motor...?
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 131
Posts: 8690
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The modified code does not fit all cases, because the Arduino is 10,000 times faster than the serial line it does the entire loop for every character it receives. That's why you either have to wait for N characters to arrive (and know when there is an idle line) OR have a delimiter.

Also how do you know when a new batch of data starts? Lets say VB is sending three characters at 2sec intervals

Code:
123-----------------------234-------------------456--------------------567
                           ^

and you start reading the serial port at the ^ position.

You will read 344.

Now if VB sends "<123>", Arduino ignores all characters until it sees < and reads until > then you both have a method to sync on the data and know when a packet ends.

______
Rob
« Last Edit: March 25, 2011, 12:29:30 pm by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rob, thank you so much for helping me.
I understand more about the functionality of serial port more each time you give me a reply smiley

I was hoping thread.sleep(2000) will give enough time for arduino to move the motor and listen to the next lines of bytes sent through, but I guess it doesn't stack up...
I added <> in VB to send though the message. < is 60 and > is 62 for ascii
Code:
steps=0;
  if(Serial.available()>0){
    if(Serial.read()==60){
      incomingbyte=Serial.read();
      while(incomingbyte<58){
        Serial.write(incomingbyte);
        *tmp++=incomingbyte;
        incomingbyte=Serial.read();
      }
    }
  }
  *tmp='\0';
  steps=atoi(tmp);
  motor1.step(steps,FORWARD,SINGLE);

I had it while(incomingbyte!=62) but it didn't work, so I changed it to less than 58.
The motor is not working and I am getting 63(? for ascii) for Serial.write().

Adding Serial.flush() was no help...
What am I doing wrong this time?

Thank you!
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 73
Posts: 3819
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're still reading and using serial data when you don't really know that you have any.

Try this:
Code:
steps=0;
if(Serial.available()>0 && Serial.read()=='<')
  {
  incomingbyte=0;
  do
    {
    if(Serial.available()>0)
      {
      incomingbyte=Serial.read();
      Serial.write(incomingbyte);
      *tmp++=incomingbyte;     
      }
    }
  while(incomingbyte != '>');
  }
  *tmp='\0';
  steps=atoi(tmp);
  motor1.step(steps,FORWARD,SINGLE);

Note that the string you end up with that tmp points to will have a '>' on the end of it. Atoi won't care, just make sure your buffer is big enough. Alternatively, write the terminating zero on it.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi again,

I copied and pasted it but it still doesn't work. I sent "<10>", and it gives me 49 and 48 (1 and 0) and then visual basic freezes. I put serial.write right after while, and not getting anything so I am assuming it is in the while loop and not getting out of it.

why?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Finally worked... To be honest, I don't know why the others didn't work.

Here's the code
Code:
  if(Serial.available()>0){
    data=Serial.read();
    if(data=='<'){
      *tmp=Serial.read();
      steps=atoi(tmp);
    }
    else if(data=='>'){
      Serial.write(steps);
      motor1.step(steps,FORWARD,SINGLE);
      steps=0;
    }
    else{
      *tmp=data;
       steps=10*steps;
       steps=steps+atoi(tmp);
    }
  }

Thank you so much!
Logged

Pages: [1]   Go Up
Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Jump to: