2016-02-13 4 views
1

Я хочу управлять двумя сервомашинами через ПК, используя координаты x-y мыши. x-y координаты курсора отправляются на последовательный порт:Управление двумя сервомоторами через компьютер с помощью мыши arduino

Для части arduino я получаю 6 символов и разделяю их на 2 части. Затем эти части преобразуются в целочисленное значение и отправить ARDUINO булавки, чтобы установить положение сервопривода:

#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=""; 
} 
} 

Тем не менее, код очень медленно. Мне нужно перемещать мышь очень медленно, чтобы заставить сервомоторы двигаться. Мгновенное движение, скажем, от 50 до 170, занимает 1 секунду, чтобы переместить серво. Могли бы вы предложить лучший вариант для управления двумя сервоприводами в этом случае?

Управление только один сервопривод работает очень хорошо, и он движется сервопривод мгновенно без каких-либо задержек:

#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); 
    } 
} 

код в 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); 
      } 
     } 
    } 

В приведенном выше коде я принимаю координаты х и у и преобразует его в диапазон примерно 180. После того, как я присоединяюсь к значениям в одну строку, отправлю их через последовательный порт.

+0

'в то время как (Serial.available()> 0)' будет цикл в то время как символ доступен, поэтому сразу же с помощью 'задержки (2); 'будет просто замедлять цикл. 'read' символ и' if (Serial.available() == 0) delay (2); '. Таким образом, вы не будете ждать, пока в буфере будут доступны дополнительные символы. – HABO

+0

@HABO большое спасибо мой друг! Теперь я понял. Я помещаю так, как вы сказали, задержка, когда в цикле происходит нулевое число, чтобы строка была построена, и производительность заметно увеличилась. Однако, во всяком случае, существует задержка, потому что, когда я перемещаю мышь и отправляю слишком много часто изменяющихся значений через последовательный порт на микроконтроллер, он не справляется с этим ... :( – Olimjon

+0

Пожалуйста, отредактируйте свой вопрос, чтобы включить обновленный код Это поможет другим помочь вам. Возможно, вы захотите попробовать добавить код для определения количества обновлений в секунду. Если вы отправляете восемь символов на обновление (шесть цифр плюс два для новой строки.) Со скоростью 960 символов в секунду (Начальный бит, восемь бит данных, стоповый бит на символ.), Тогда вы не сможете получить более 120 обновлений в секунду. Добавьте задержку в 2 мс и упасть до 96 обновлений в секунду. Пример вашего одного сервопривода не имеет задержки и только половина передаваемые данные, поэтому он должен быть намного быстрее. – HABO

ответ

0

Для того, чтобы улучшить производительность вашего кода вы можете удалить задержку и использовать максимальной скорости передачи данных (115200). Ради простоты я уплотняется ваш Arduino код ниже:

#include <Servo.h> 

// create 2 servos x and y 
Servo x; 
Servo y; 

void setup() { 
    Serial.begin(115200); 
    x.attach(6); 
    y.attach(7); 
} 

void loop() { 
    //empty 
} 

void serialEvent() { 
    //set servo position. 
    if (Serial.available()>0) { 
     //Receives 2 angles separated per a comma 
     x.write(Serial.parseInt()); //Returns first angle 
     y.write(Serial.parseInt()); //Returns second angle 
     Serial.read(); //Read the '\n'. I am not sure if it is necessary. 
    } 
} 

Увеличение скорости передачи данных также в исходном C# код:

port.BaudRate = 115200; 

Кроме того, я предлагаю вам отправить углы, разделенные запятой через серию. Таким образом, вместо того, чтобы:

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); 
}  

Заменить:

if (port.IsOpen) { 
    port.WriteLine(valx + ',' + valy); //Note that WriteLine appends a '\n' character in the end. 
} 
+0

Ура! Это работает! Нет никакого отставания! Спасибо вам большое за это!)) Я так счастлив! – Olimjon

Смежные вопросы