Pages: [1]   Go Down
Author Topic: mouse coordinates in vb.net to arduino  (Read 1120 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi.. how do u get 2 servos to respond to mouse coordinates? the processing code works but the vb.net code doesnt work.. please help!

Code:
//processing code that works

import processing.serial.*;

Serial port;

int p;

void setup()
{
  size(200,200);    
  port = new Serial(this, "COM7",9600);
}

void mouseMoved()
{
  p=mouseX;
  
  port.write(p);

  println(p);
}

void draw()
{
   }

corresponding arduino code:
Code:
int servoPin1 = 2;     // Control pin for servo motor
int servoPin2 = 9;

int minPulse = 600;   // Minimum servo position
int maxPulse = 3000;  // Maximum servo position

int pulse1 = 0;        // Amount to pulse the servo
int pulse2 = 0;

long lastPulse = 0;    // the time in milliseconds of the last pulse
int refreshTime = 20; // the time needed in between pulses

int sread=0;

void setup() {
 pinMode(servoPin1, OUTPUT);  // Set servo pin as an output pin
 pinMode(servoPin2, OUTPUT);
 
 pulse1 = minPulse;           // Set the motor position value to the minimum
 pulse2 = minPulse;
 
 Serial.begin(9600);
}

void loop() {
if (Serial.available()>0)
{
  
 sread=Serial.read();
  Serial.println(sread);


 pulse1 = map(sread,0,180,minPulse,maxPulse);    // convert the analog value
 pulse2 = map(sread,0,180,minPulse,maxPulse);                                                // to a range between minPulse
                                                  

 // pulse the servo again if rhe refresh time (20 ms) have passed:
 if (millis() - lastPulse >= refreshTime)
 {
   digitalWrite(servoPin1, HIGH);   // Turn the motor on
   delayMicroseconds(pulse1);       // Length of the pulse sets the motor position
   digitalWrite(servoPin1, LOW);    // Turn the motor off
      
    digitalWrite(servoPin2, HIGH);
    delayMicroseconds(pulse2);  
    digitalWrite(servoPin2, LOW);
      
    lastPulse = millis();           // save the time of the last pulse
 }
}
}



vb.net code that doesnt work.. please help me please!

Code:
Public Class Form1

    Dim port As System.IO.Ports.SerialPort

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        port.Close()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        port = My.Computer.Ports.OpenSerialPort("COM7")
    End Sub

    Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        port.Write(e.X)
    End Sub
End Class
Logged

Glasgow, Scotland
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi.

I've had similar problems getting Visual Basic programs and Ardunio to communicate correctly using a serial port. The issue is usually to do with what you are actually sending on the port - ASCII codes or Bytes.

I believe that if you use SerialPort.Write(e.X) then you will be sending an ASCII representation of the value of e.X. When the Arduino code receives this in your sread = Serial.read() it is receiving ASCII codes - these are not integer values that can then be mapped to your pulse values.

I've solved this problem in the past by making sure I send a single Byte from the Visual Basic code. Take your mouse.X value and first convert it to a single Byte. (you'll need to make sure the initial value is between 0 and 255 as a Byte can only hold up to 255). Place this value in a Byte array and then send the single byte from the byte array over the serial port. For example:

Code:
       'Single byte to hold mouse.X
        Dim mouseX As Byte
        'Convert the e.X integer into a byte
        mouseX = CByte(e.X)

        'Create a byte array
        Dim buffer() As Byte = {0}
        'Place the mouseX byte in index 0 of the array
        buffer(0) = mouseX

        'Use the write buffer method of the serial port
        'and send the byte at index 0 of the buffer array
        SerialPort1.Write(buffer, 0, 1)

The Arduino will then receive a Byte containing a value from 0 - 255 instead of ASCII code that represents the value.

Hope this helps. At least it seems to work for me.

Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks andrew! it worked perfectly!

ok now i want to try something else!

i want to send different commands to each of the two servos repectively via a textbox and button in vb.. so lets say servo 1 to move 180 degrees then i would type 1180.. servo 2 to move 90 degrees then i would type 290 ya? is this the way to control multiple servos?

i tried some code already and ofcourse it doesnt work! lol.. can some1 take a look please..

this is the vb.net part
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim myString As String = TextBox1.Text

        Dim head As Byte = CByte(myString.Substring(1, 1))
        Dim butt As Byte = CByte(myString.Substring(1))

        Dim buffer(1) As Byte

        buffer(0) = head
        buffer(1) = butt

        port.Write(buffer, 0, 2)

    End Sub

this is the arduino part:
Code:
int servoPin1 = 2;     // Control pin for servo motor
int servoPin2 = 9;

int minPulse = 600;   // Minimum servo position
int maxPulse = 3000;  // Maximum servo position

int pulse1 = 0;        // Amount to pulse the servo
int pulse2 = 0;

long lastPulse = 0;    // the time in milliseconds of the last pulse
int refreshTime = 20; // the time needed in between pulses

byte input[1];
int count=0;

void setup() {
  pinMode(servoPin1, OUTPUT);  // Set servo pin as an output pin
  pinMode(servoPin2, OUTPUT);

  pulse1 = minPulse;           // Set the motor position value to the minimum
  pulse2 = minPulse;

  Serial.begin(9600);
}

void loop()
{
  if (Serial.available()>0)
  {
    while(Serial.available())
    {
      input[count++]=Serial.read();
    }
  }

  count=0;

  if(input[0]==1)
  {
    pulse1 = map(input[1],0,180,minPulse,maxPulse);
  }

  if(input[0]==2)
  {      
 pulse2=map(input[1],0,180,minPulse,maxPulse);                                                
  }                                                  

  // pulse the servo again if rhe refresh time (20 ms) have passed:
  if (millis() - lastPulse >= refreshTime)
  {
    digitalWrite(servoPin1, HIGH);   // Turn the motor on
    delayMicroseconds(pulse1);       // Length of the pulse sets the motor position
    digitalWrite(servoPin1, LOW);    // Turn the motor off

    digitalWrite(servoPin2, HIGH);
    delayMicroseconds(pulse2);  
    digitalWrite(servoPin2, LOW);

    lastPulse = millis();           // save the time of the last pulse
  }
}

somebody please give me some pointers.. nothing i do in programming ever works.. lol!
« Last Edit: April 12, 2009, 02:14:29 pm by tableray » Logged

Glasgow, Scotland
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi again.

Glad to be of help. I don't know much about controlling servos but can give a few comments on the communications part of the code...

In the Visual Basic code I'd suggest you use more than one text box - one for each servo. It would make dealing with what's entered a bit easier.

In the code you currently have if you enter '1180 290' into the same text box then..

Code:
       Dim head As Byte = CByte(myString.Substring(1, 1))
        Dim butt As Byte = CByte(myString.Substring(1))
... head will equal 1 and butt will also equal 1!

myString.substring() returns as many characters (not words) as you ask it to. In both of the myString.Substrings you use you're asking for character at index 1 - the second 1 in the string. Strings are zero indexed in VB so the first character of a string is at index 0.

If you want to get the 1180 from the text box you would need the code myString.Substring(0, 4) and to get the 290 from it you would need the code myString.Substring(5, 3).

If, as i'm guessing, you're trying to get the 180 and the 90 then the codes should be...

Code:
       Dim head As Byte = CByte(myString.Substring(1, 3))
        Dim butt As Byte = CByte(myString.Substring(6, 2))
...that's assuming you've got a space between the 1180 and the 290.

Whilst this will work it will cause you problems if in future you use values of different lengths. For example if you want the next instruction to be '15 220' then you'd have to write completely different substring codes. Probably easier to have separate text boxes for each servo. Then you wouldn't need to use substrings at all or numbers to identify the servo...

Code:
       Dim head As Byte = CByte(TextBox1.Text)
        Dim butt As Byte = CByte(TextBox2.Text)

You would still need to make sure the numbers you were entering in each text box were only between 0-255 as a byte can't hold any more. It would also be a good idea to do some checking of the text entered into the text boxes to make sure they are valid numbers and not letters, spaces or punctuation. If they are you're program will throw all sorts of exceptions. This might help with that http://www.acraigie.com/programming/bitstobytes.html

Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

woohoo i got it! thanks again! nice link too
Logged

Pages: [1]   Go Up
Jump to: