I want to control two servos via PC, using a mouse x-y coordinates. x-y coordinates of the cursor is sent to the serial port. This code is written in C#:
public partial class Form1 : Form
{
SerialPort port;
public Form1()
{
InitializeComponent();
init();
}
private void init()
{
port = new SerialPort();
port.PortName = "COM1";
port.BaudRate = 9600;
//porty = new SerialPort();
try
{
port.Open();
}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}
}
int x = 0, y = 0;
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
Graphics g = CreateGraphics();
Pen p = new Pen(Color.Navy);
Pen erase = new Pen(Color.White);
x = e.X; y = e.Y;
double curWidth = this.Width / 180;
double x2 = Math.Round(x / curWidth);
double curHeight = this.Height / 180;
double y2 = Math.Round(y / curHeight);
label1.Text = x2.ToString(); label2.Text = y2.ToString();
string valx = x2.ToString();
string valy = y2.ToString();
while(valx.Length < 3)
{
valx = '0' + valx;
}
while(valy.Length < 3)
{
valy = '0' + valy;
}
string valsum = valx+valy;
label3.Text = valsum.ToString();
if (port.IsOpen)
{
port.WriteLine(valsum);
}
}
}
In the above code I am taking x and y coordinates and converting it to approx 180 range. After I join the values into one string to send it through serial port.
For the arduino part, I am getting 6 character string and dividing it into 2 parts. Then these parts are converted into integer value and send to arduino pins to set servo position. This code is arduino code:
#include <Servo.h>
String readString, servo1, servo2;
Servo myservo1; // create servo object to control a servo
Servo myservo2;
void setup() {
Serial.begin(9600);
myservo1.attach(6); //the pin for the servo control
myservo2.attach(7);
}
void loop() {}
void serialEvent() {
while (Serial.available()) {
delay(2);
if (Serial.available() >0) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
}
}
if (readString.length() >0) {
Serial.println(readString); //see what was received
// expect a string like 07002100 containing the two servo positions
servo1 = readString.substring(0, 3); //get the first three characters
servo2 = readString.substring(3, 6); //get the next three characters
Serial.println(servo1); //print ot serial monitor to see results
Serial.println(servo2);
int n1; //declare as number
int n2;
char carray1[6]; //magic needed to convert string to a number
servo1.toCharArray(carray1, sizeof(carray1));
n1 = atoi(carray1);
char carray2[6];
servo2.toCharArray(carray2, sizeof(carray2));
n2 = atoi(carray2);
myservo1.write(n1); //set servo position
myservo2.write(n2);
readString="";
}
}
I want to control two servos via PC, using a mouse x-y coordinates. x-y coordinates of the cursor is sent to the serial port:
public partial class Form1 : Form
{
SerialPort port;
public Form1()
{
InitializeComponent();
init();
}
private void init()
{
port = new SerialPort();
port.PortName = "COM1";
port.BaudRate = 9600;
//porty = new SerialPort();
try
{
port.Open();
}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}
}
int x = 0, y = 0;
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
Graphics g = CreateGraphics();
Pen p = new Pen(Color.Navy);
Pen erase = new Pen(Color.White);
x = e.X; y = e.Y;
double curWidth = this.Width / 180;
double x2 = Math.Round(x / curWidth);
double curHeight = this.Height / 180;
double y2 = Math.Round(y / curHeight);
label1.Text = x2.ToString(); label2.Text = y2.ToString();
string valx = x2.ToString();
string valy = y2.ToString();
while(valx.Length < 3)
{
valx = '0' + valx;
}
while(valy.Length < 3)
{
valy = '0' + valy;
}
string valsum = valx+valy;
label3.Text = valsum.ToString();
if (port.IsOpen)
{
port.WriteLine(valsum);
}
}
}
In the above code I am taking x and y coordinates and converting it to approx 180 range. After I join the values into one string to send it through serial port.
For the arduino part, I am getting 6 character string and dividing it into 2 parts. Then these parts are converted into integer value and send to arduino pins to set servo position:
#include <Servo.h>
String readString, servo1, servo2;
Servo myservo1; // create servo object to control a servo
Servo myservo2;
void setup() {
Serial.begin(9600);
myservo1.attach(6); //the pin for the servo control
myservo2.attach(7);
}
void loop() {}
void serialEvent() {
while (Serial.available()) {
delay(2);
if (Serial.available() >0) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
}
}
if (readString.length() >0) {
Serial.println(readString); //see what was received
// expect a string like 07002100 containing the two servo positions
servo1 = readString.substring(0, 3); //get the first three characters
servo2 = readString.substring(3, 6); //get the next three characters
Serial.println(servo1); //print ot serial monitor to see results
Serial.println(servo2);
int n1; //declare as number
int n2;
char carray1[6]; //magic needed to convert string to a number
servo1.toCharArray(carray1, sizeof(carray1));
n1 = atoi(carray1);
char carray2[6];
servo2.toCharArray(carray2, sizeof(carray2));
n2 = atoi(carray2);
myservo1.write(n1); //set servo position
myservo2.write(n2);
readString="";
}
}
However, the code is very slow. I need to move the mouse very slowly to make servos move. Instant movement from let's say from 50 degree to 170 takes 1 second to move the servo. Could you offer a better option to control two servos in this case?
Controlling only one servo works very well, and it moves servo instantly without any lags:
#include <Servo.h>
Servo x;
int xval;
void setup() {
Serial.begin(9600);
x.attach(9);
}
void loop() {
}
void serialEvent() {
xval = Serial.parseInt();
if(xval!=0) {
x.write(xval);
}
}
Thank you in advance