desktop

Controlar paso a paso un servo motor con Arduino

Buenas, compañeros.

Estoy tratando de hacer un control manual en C# simple con 2 servomotores. Estoy ultilizando 2 TrackBar en c# para controlar los angulos de cada uno a "paso" segun traslade de un lado a otro el cursor,
Logro controlar uno de estos servos, pero no logro entender como hacer para controlar ambos de forma individual. He dejado solo el codigo en el que me funciona solo un servo.
Espero que me puedan brindar su ayuda.

codigo en C#
Código:
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            if(serialPort1.IsOpen)
            {
                serialPort1.WriteLine(pinzas_trackBar1.Value.ToString());
                pinzas_label_angulo.Text = "El angulo =" + pinzas_trackBar1.Value.ToString();

            }

codigo en Arduino
Código:
#include <Servo.h>
Servo myservo1;
Servo myservo2;
int val;

void setup() {
Serial.begin(9600);
myservo1.attach(5);//servo1
myservo2.attach(4);//servo2
}

void loop() {

}

void serialEvent()
{
  val = Serial.parseInt();
  if(val!=0)
  {
    myservo1.write(val);
  }
  
}
...
 
Prueba implementar Firmata o crear una instrucción para separar los servos, podría ser usando JSON, pero con firmata puedes controlar directamente el Arduino, Microsoft incluso da ejemplos de ello aunque estos son de aplicaciones universales de Windows 10.
 
Prueba implementar Firmata o crear una instrucción para separar los servos, podría ser usando JSON, pero con firmata puedes controlar directamente el Arduino, Microsoft incluso da ejemplos de ello aunque estos son de aplicaciones universales de Windows 10.

Como podria crear una instruccion que separe los servos? Esa seria la solucion ideal, pero no tengo claro como enviar los datos respectivos para cada servo para que la rutina del arduino opere. :confused: yo envio los datos correspondientes del trackbar con esta instruccion
Código:
 serialPort1.WriteLine(pinzas_trackBar1.Value.ToString());
si manejara un solo servo, estaria bien.
Pero al utilizar otro trackbar que envie otros datos "otros angulos" y sean recibidos por el otro servo.:confused:
 
Lo que tienes que modificar es el Arduino, debes enviar un mensaje tipo "Parámetro, Valor" hay dos formas de hacerlo, una es usando cadena de caracteres, aquí te dejo esto, esta basado en el ejemplo de SerialEvent para obtener la cadena, una ves que esta se completa es procesada
Código:
#include <Servo.h>

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

Servo myservo1;
Servo myservo2;

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);

  myservo1.attach(8);//servo1
  myservo2.attach(9);//servo2
}

void loop() {
  // Procesamiento de la candena
  if (stringComplete) {
    int inicioObj = 0;
    int separadorObj = 0;
    int finObj = 0;
    int finComando = inputString.lastIndexOf(">");
    while(1){
      inicioObj = inputString.indexOf("<", finObj);
      separadorObj = inputString.indexOf(":",inicioObj);
      finObj = inputString.indexOf(">",inicioObj);
      String Objeto = inputString.substring((inicioObj + 1),separadorObj);
      String Argumento = inputString.substring((separadorObj+1),finObj);
      
      //Esta parte solo es para visualizar ya que no estoy usando interfaz, solo la terminal.
      Serial.print("Objeto: ");
      Serial.print(Objeto);
      Serial.print(" Argumento: ");
      Serial.println(Argumento);
      
      //Aquí van las condicionales de las acciones según el objeto que recibe.
      if(Objeto == "servo1") myservo1.write(Argumento.toInt());
      if(Objeto == "servo2") myservo2.write(Argumento.toInt());

      if(finObj == finComando) break;
    }
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

Para enviar el comando es simple, solo envía "<objeto:argumento>", como verás, estos son delimitados con <> y separados con :, puedes enviar todos los que quieras en la misma línea mientras no desbordes el buffer, por ejemplo enviar "<servo1:30><servo2:170>" en una misma línea o enviarlos separados como "<servo1:78>" y luego "<servo2:38>" y agregar mas objetos es simple.
 
Última edición:
Para enviar el comando es simple, solo envía "<objeto:argumento>", como verás, estos son delimitados con <> y separados con :, puedes enviar todos los que quieras en la misma línea mientras no desbordes el buffer, por ejemplo enviar "<servo1:30><servo2:170>" en una misma línea o enviarlos separados como "<servo1:78>" y luego "<servo2:38>" y agregar mas objetos es simple.

Para entenderte mejor cuando dices enviar el comando "<objeto:argumento>", te refieres desde C#, desde el Trackbar? Y la funcion de todo el codigo que enviaste es para controlar estos servos con el mismo Trackbar? :unsure:
 

Adjuntos

  • Captura.PNG
    Captura.PNG
    2 KB · Visitas: 15
Última edición:
Envías esa cadena de texto al puerto serie

serialPort1.WriteLine("<servo1:" + pinzas_trackBar1.Value.ToString() + ">");

servo1 es el objeto para el primer servo, para la otra seria servo2, si quieres seguir poniendo más servos, LEDs, o cualquier otra cosa, usarías la misma dinámica.
 
Envías esa cadena de texto al puerto serie

serialPort1.WriteLine("<servo1:" + pinzas_trackBar1.Value.ToString() + ">");

servo1 es el objeto para el primer servo, para la otra seria servo2, si quieres seguir poniendo más servos, LEDs, o cualquier otra cosa, usarías la misma dinámica.

Muchisimas gracias por tu ayuda, funciona perfecto. :apreton::aplauso: me has salvado a darle forma a este proyecto.
 
¿qué no sale? el código que subí es para el Arduino, para enviar los comandos cualquier terminal al puerto serie sirve (Termite, HyperTerminal), solo recuerda que debe ser correctamente terminado con el carácter de nueva línea (\n) que es enviado por defecto si usas serial.WriteLine() en C#
 
Si, tengo el mismo código en arduino, y en c# tengo la misma idea que Edo0707 pero cuanto intentó mover el servo sólo se mueve unos cuantos grados ya de ahí no se mueve
 
mmm... sí, cuando experimente podía haber un problema por que si usas un evento al variar el valor del scroll, la comunicación del Arduino y el procesado podría ser más lenta y darle problemas atorando el proceso, yo lo que hice fue actualizar los datos usando un timer en lugar de usar el evento del scroll.

Igual, seria recomendable que la aplicación esperara una confirmación de ejecución completada desde el Arduino antes de enviar otro comando.
 
Si, tengo el mismo código en arduino, y en c# tengo la misma idea que Edo0707 pero cuanto intentó mover el servo sólo se mueve unos cuantos grados ya de ahí no se mueve

Intentaste revisar el minimo y maximo del trackbar, quizas se encuentra limitado y por eso solo gira muy poco. O tambien la frecuencia con la que envia los datos "TickFrecuency" en las propiedades del trackbar



No experimente con el tiempo, solo di un valor arbitrario.

Amigo tengo otra consulta para ti, como crear un tipo de "programado" desde el form ya sea con los trackbar o con un simple textBox y luego enviarlo al arduino.:confused:.

Para ser mas exacto, Si pongo el trackbar 1 en 100 (servo1), el trackbar 2 en 200(servo2). y cuando le de click a un boton enviar, envie esa "programacion" en orden. O por ejemplo desde un textbox, estuve viendo un video en youtube en donde hacen esto pero para un robot, yo lo necesito pero para otro sistema y es esa la funcion que necesito ahora.

Les dejo el link, por si tienen el chance de ver la parte en donde el "programa" las trayectorias del robot.

 
Última edición:
Atrás
Arriba