Controlar ServoMotor desde PC con aplicación JAVA

Buenas Tardes.

Hace un tiempo que llevo utilizando Arduino UNO R3, pero hace un mes aproximadamente que empecé a realizar conexiones via Serial (USB) con el PC. He creado varias aplicaciones en el PC con JAVA, como semáforos para encender leds en la protoboard, o sensores de distancia en arduino, que envía los datos al pc. Hasta ahí, todo correcto. Entiendo la conexión serial hasta cierto punto, pero el problema llega cuando estoy interesado en realizar un mecanismo de Dirección de un coche, basado en un Servo TowerPro MicroServo 9g y controlado desde el Pc por usb.

El problema viene siendo cuando creo una Interfaz en Java con un boton, al cual le aplico un evento de KeyPressed, para que detecte cuando hay una tecla presionada, y según la tecla:

  • A o a --> 0º
  • D o d --> 180º
  • Si no pulso ninguna, vuelve a 90º

De esta forma, simulo un sistema de dirección sencillo.

Utilizo la libreria PanamaHitek_Arduino, para mayor sencillez a la hora de crear aplicaciones para comunicar con Arduino el pc.

El código de la función en Java que detecta la tecla pulsada es:

private void jButton1KeyPressed(java.awt.event.KeyEvent evt) {
char c = evt.getKeyChar();
try {
if(c == 'a' || c == 'A') {
Ard.sendData("1");
} else {
if(c == 'd' || c == 'D') {
Ard.sendData("2");
}
}
} catch(Exception e) {}
}

Anteriormente, he creado PanamaHitek_Arduino Ard = new PanamaHitek_Arduino();
y en el constructor de la clase: Ard.arduinoTX("COM3",9600);

El código introducido en el Arduino es el siguiente:

#include <Servo.h>
#define SERVO 10

Servo S;

void setup(){
Serial.begin(9600);
S.attach(SERVO);
S.write(90);
}

void loop(){
while(Serial.available() > 0){
int op = Serial.parseInt();
if(op == 1){
S.write(0);
} else {
if(op == 2){
S.write(180);
}
}
}
S.write(90);
}

El problema viene siendo, que pulso A o D y el Arduino, se enciende el led RX, como que recibe la señal, pero el ServoMotor ni se inmuta, no se mueve, no hace nada, permanece en 90º.

Hice también una versión donde:

  • A o a --> 0º
  • D o d --> 180º
  • W o w --> 90º

y el arduino recibía:

  • 1, si pulsas a.
  • 2, si pulsas d.
  • 3, si pulsas w.

y según el valor que recibía, lanzaba la instrucción S.write(0 ó 90 ó 180);

Pero unicamente funcionaba cuando pulsaba una vez A, D o W, rápidamente, esperaba un breve periodo de tiempo, y entonces el servo, reaccionaba y conseguía la posición que deseaba, pero para pulsar otra tecla diferente, tenia que esperar un periodo corto de tiempo tambien. Es decir, si Pulso A y mientras se mueve a la posición 0º, pulso D, el servo ni se inmuta, se queda en 0º, y de esta forma no obtengo un sistema de dirección eficiente, porque si tengo que esperar siempre un periodo de tiempo para poder enviarle un valor, y esperar otro tiempo a que éste reaccione, el sistema de dirección no es eficiente.

He estado revisando mucha información por internet sobre Servo Motores, y he visto que los servos funcionan por tiempo de pulso, es decir, si le das un pulso de 1ms, va a la posición 0, si le das 2ms, va a la posición 180... (dependiendo del Servo, claro). Pero pienso que el problema está en la conexión Serial, que por así decirlo, mientras que está recibiendo Datos, el programa se congela.

¿Como podría solucionarlo?

Un saludo de Antemano y muchas gracias.

nandopi:
Buenas Tardes.

Hace un tiempo que llevo utilizando Arduino UNO R3, pero hace un mes aproximadamente que empecé a realizar conexiones via Serial (USB) con el PC. He creado varias aplicaciones en el PC con JAVA, como semáforos para encender leds en la protoboard, o sensores de distancia en arduino, que envía los datos al pc. Hasta ahí, todo correcto. Entiendo la conexión serial hasta cierto punto, pero el problema llega cuando estoy interesado en realizar un mecanismo de Dirección de un coche, basado en un Servo TowerPro MicroServo 9g y controlado desde el Pc por usb.

El problema viene siendo cuando creo una Interfaz en Java con un boton, al cual le aplico un evento de KeyPressed, para que detecte cuando hay una tecla presionada, y según la tecla:

  • A o a --> 0º
  • D o d --> 180º
  • Si no pulso ninguna, vuelve a 90º

De esta forma, simulo un sistema de dirección sencillo.

Utilizo la libreria PanamaHitek_Arduino, para mayor sencillez a la hora de crear aplicaciones para comunicar con Arduino el pc.

El código de la función en Java que detecta la tecla pulsada es:

private void jButton1KeyPressed(java.awt.event.KeyEvent evt) {
char c = evt.getKeyChar();
try {
if(c == 'a' || c == 'A') {
Ard.sendData("1");
} else {
if(c == 'd' || c == 'D') {
Ard.sendData("2");
}
}
} catch(Exception e) {}
}

Anteriormente, he creado PanamaHitek_Arduino Ard = new PanamaHitek_Arduino();
y en el constructor de la clase: Ard.arduinoTX("COM3",9600);

El código introducido en el Arduino es el siguiente:

#include <Servo.h>
#define SERVO 10

Servo S;

void setup(){
Serial.begin(9600);
S.attach(SERVO);
S.write(90);
}

void loop(){
while(Serial.available() > 0){
int op = Serial.parseInt();
if(op == 1){
S.write(0);
} else {
if(op == 2){
S.write(180);
}
}
}
S.write(90);
}

El problema viene siendo, que pulso A o D y el Arduino, se enciende el led RX, como que recibe la señal, pero el ServoMotor ni se inmuta, no se mueve, no hace nada, permanece en 90º.

Hice también una versión donde:

  • A o a --> 0º
  • D o d --> 180º
  • W o w --> 90º

y el arduino recibía:

  • 1, si pulsas a.
  • 2, si pulsas d.
  • 3, si pulsas w.

y según el valor que recibía, lanzaba la instrucción S.write(0 ó 90 ó 180);

Pero unicamente funcionaba cuando pulsaba una vez A, D o W, rápidamente, esperaba un breve periodo de tiempo, y entonces el servo, reaccionaba y conseguía la posición que deseaba, pero para pulsar otra tecla diferente, tenia que esperar un periodo corto de tiempo tambien. Es decir, si Pulso A y mientras se mueve a la posición 0º, pulso D, el servo ni se inmuta, se queda en 0º, y de esta forma no obtengo un sistema de dirección eficiente, porque si tengo que esperar siempre un periodo de tiempo para poder enviarle un valor, y esperar otro tiempo a que éste reaccione, el sistema de dirección no es eficiente.

He estado revisando mucha información por internet sobre Servo Motores, y he visto que los servos funcionan por tiempo de pulso, es decir, si le das un pulso de 1ms, va a la posición 0, si le das 2ms, va a la posición 180... (dependiendo del Servo, claro). Pero pienso que el problema está en la conexión Serial, que por así decirlo, mientras que está recibiendo Datos, el programa se congela.

¿Como podría solucionarlo?

Un saludo de Antemano y muchas gracias.

Has visto si esta bien configurada el modelo de tu placa Arduino?, me paso algo parecido, cuando intentaba cargar el programa en mi placa Arduino MEGA, y en el software estaba configurado como Arduino UNO, encendía el mismo led que mencionaste y no hacia nada, despues cambie de modelo y funcionó a la perfección.

nandopi:
Buenas Tardes.

Hace un tiempo que llevo utilizando Arduino UNO R3, pero hace un mes aproximadamente que empecé a realizar conexiones via Serial (USB) con el PC. He creado varias aplicaciones en el PC con JAVA, como semáforos para encender leds en la protoboard, o sensores de distancia en arduino, que envía los datos al pc. Hasta ahí, todo correcto. Entiendo la conexión serial hasta cierto punto, pero el problema llega cuando estoy interesado en realizar un mecanismo de Dirección de un coche, basado en un Servo TowerPro MicroServo 9g y controlado desde el Pc por usb.

El problema viene siendo cuando creo una Interfaz en Java con un boton, al cual le aplico un evento de KeyPressed, para que detecte cuando hay una tecla presionada, y según la tecla:

  • A o a --> 0º
  • D o d --> 180º
  • Si no pulso ninguna, vuelve a 90º

De esta forma, simulo un sistema de dirección sencillo.

Utilizo la libreria PanamaHitek_Arduino, para mayor sencillez a la hora de crear aplicaciones para comunicar con Arduino el pc.

El código de la función en Java que detecta la tecla pulsada es:

private void jButton1KeyPressed(java.awt.event.KeyEvent evt) {
char c = evt.getKeyChar();
try {
if(c == 'a' || c == 'A') {
Ard.sendData("1");
} else {
if(c == 'd' || c == 'D') {
Ard.sendData("2");
}
}
} catch(Exception e) {}
}

Anteriormente, he creado PanamaHitek_Arduino Ard = new PanamaHitek_Arduino();
y en el constructor de la clase: Ard.arduinoTX("COM3",9600);

El código introducido en el Arduino es el siguiente:

#include <Servo.h>
#define SERVO 10

Servo S;

void setup(){
Serial.begin(9600);
S.attach(SERVO);
S.write(90);
}

void loop(){
while(Serial.available() > 0){
int op = Serial.parseInt();
if(op == 1){
S.write(0);
} else {
if(op == 2){
S.write(180);
}
}
}
S.write(90);
}

El problema viene siendo, que pulso A o D y el Arduino, se enciende el led RX, como que recibe la señal, pero el ServoMotor ni se inmuta, no se mueve, no hace nada, permanece en 90º.

Hice también una versión donde:

  • A o a --> 0º
  • D o d --> 180º
  • W o w --> 90º

y el arduino recibía:

  • 1, si pulsas a.
  • 2, si pulsas d.
  • 3, si pulsas w.

y según el valor que recibía, lanzaba la instrucción S.write(0 ó 90 ó 180);

Pero unicamente funcionaba cuando pulsaba una vez A, D o W, rápidamente, esperaba un breve periodo de tiempo, y entonces el servo, reaccionaba y conseguía la posición que deseaba, pero para pulsar otra tecla diferente, tenia que esperar un periodo corto de tiempo tambien. Es decir, si Pulso A y mientras se mueve a la posición 0º, pulso D, el servo ni se inmuta, se queda en 0º, y de esta forma no obtengo un sistema de dirección eficiente, porque si tengo que esperar siempre un periodo de tiempo para poder enviarle un valor, y esperar otro tiempo a que éste reaccione, el sistema de dirección no es eficiente.

He estado revisando mucha información por internet sobre Servo Motores, y he visto que los servos funcionan por tiempo de pulso, es decir, si le das un pulso de 1ms, va a la posición 0, si le das 2ms, va a la posición 180... (dependiendo del Servo, claro). Pero pienso que el problema está en la conexión Serial, que por así decirlo, mientras que está recibiendo Datos, el programa se congela.

¿Como podría solucionarlo?

Un saludo de Antemano y muchas gracias.

Has visto si esta bien configurada el modelo de tu placa Arduino?, me paso algo parecido, cuando intentaba cargar el programa en mi placa Arduino MEGA, y en el software estaba configurado como Arduino UNO, encendía el mismo led que mencionaste y no hacia nada, despues cambie de modelo y funcionó a la perfección.