Pages: [1] 2 3   Go Down
Author Topic: consulta. PID u otro modo- para posicion de motor-avances  (Read 7385 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 2
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hola gente. aqui nuevamente consultando. hace tiempo que tengo una idea y no he podido concretarla.
el tema es el siguiente. necesito un servo con gran torque. para ello la idea era utilizar un atornillador a bateria.
una idea similar a esta http://www.fieroaddiction.com/servo.html

inicialmente he intentado utilizar un servo RC (aprovechando la simpleza del codigo para moverlo) utilizando como señal la alimentacion del motor del mismo, luego a esto lo llevaba a las entradas de un puente H, in a, in b. este puente H haria mover el atornillador, quien a su vez por unas varillas moveria el servo rc, determinando la posicion. con esta idea surgieron problemas. como ser que los servos al estar inmovil envian positivo en ambas salidas al motor, esto genero cortos al puente H, que no esta preparado para recibir señal en in a y b al mismo tiempo. para solucionar esto intente hacer un interlock. quien funciono bien en una prueba solitaria. pero al utilizarlo con el puente y el servo,,,,, bueno no anduvo...
lo que comente anteriormente fue inspirado en estos ejemplos y muchos otros que se encuentran en internet:
http://www.fieroaddiction.com/servo.html


tras el fracaso anterior smiley-sad comenze a investigar sobre PID para utilizar solamente el arduino y un potenciometro mas un puente h.

el tema es que no se de programacion... apenas estoy comenzando con arduino... y algunos codigos...
podrian uds indicarme como comenzar con PID.... como utilizar el ejemplo basico que creo que esta en la libreria?
basicamente necesito mover un motor (como el atornillador) a la posicion que necesito como un servo normal.
es muy dificil lo que pienzo?
gracias gente por pasar por aqui
« Last Edit: December 14, 2012, 01:29:46 pm by nicko_esx » Logged

Colombia
Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Hola,

Te cuento que estoy en algo similar pero a menor escala, ya tuve un avance pero sin usar PID, puedes verlo acá : http://disquegeek.blogspot.com/2012/10/progreso-4-7-oct-arduino-rf-links-y.html

es muy sencillo lo que hice, pero te puede dar una idea de hacia donde ir, ahora quiero implementar PID para mejorar la retroalimentación del pot del motoreductor.

Si has encontrado información que me puedas compartir te lo agradecería, cualquier cosa te cuento si avanzo en algo.
Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hola
muchas gracias por responder. la verdad tu idea es lo que estoy buscando justamente. smiley-grin
al no saber usar pid en mi caso, pensaba en utilizar solo funciones de apagado encendido y comparaciones. no me habia puesto a escribir pero pensaba algo similar a lo tuyo. el problema es que al no saber tanto de programacion no sabia por donde comenzar. esto tuyo creo que me va a ser super util.
lo de la escala de motor ya solo depende seguramente del puente h que usemos cada uno
yo uso el siguiente por si te gusta. es muy simple de hacer. yo lo hice y soy novato total en electronica
http://www.pyroelectro.com/tutorials/h_bridge_4_transistor/

en cuanto tenga un poco de tiempo voy a intentar lo de tu ejemplo. esta barbaro para mi.
solo algunas dudas tengo pero seguro tendre respuesta u otras dudas cuando lo pruebe.
te aviso si avanzo en algo.
PD esta muy interesante ese blog tuyo si te interesa arduino y videos juegos puedes ver lo que postie antes. un tacometro. y un mini simulador para xsim.
saludos. muchas gracias maestro
Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hola gente estuve intentando escribir algo para lo que mencione antes. intentar definir la posicion de un motor como si fuera un servo
entre lo que busque en internet y lo que compartio selda, pude definir algo....
queria saber que opinan uds. sobre este codigo a ver si funcionaria o que le falta...
aclaro. anterior a este codigo que subo, habia probado uno mas simple. que funciono bien. era para apagar o encender un led dependiendo si el valor del potenciometro era mayor o menor a un valor ya definido en una variable.
el siguiente codigo no pude probarlo aun. pero queria ver que opinan.
muchas gracias por pasar por aqui smiley-grin

Code:
/*
 ejemplo encender 2 leds y apagar respectivamente, izquierda y derecha, dependendiendo
 del valor del potenciometro se enciende uno y otro.comparado con el serial read, por donde se envia un valor para la posicion actual deseada. los leds se utilizan indicando el sentido de giro del motor. emulando la señal que se envia a un puente h para el movimiento respectivo.
 
 */
 
int pinSensor = A0;    // Entrada para el potenciómetro.posicion actual del motor. en este ejemplo moveria el pot manualmente emulando el moviento del motor, indicado por los leds.
int pinLed2= 10; // led de posicion derecha, emularia la señal para el encendido del motor por el puente h en direccion a la derecha
int pinLed = 9; //led de posicion izquierda. idem anterior a la izquierda.
int valorSensor = 0;   // variable para el valor del sensor.
int posact = 0; //creo que es necesario que la variable empiece de cero.

int sigpos = 0; // abreviatura de siguiente posición, valor que seria enviado por serial.

void setup() {
  // Declaramos el pin del Led como salida:
  pinMode(pinLed, OUTPUT);
  pinMode(pinLed2, OUTPUT);
  Serial.begin(9600);
}
 
void loop() {
  // verificamos que haya valores enviados y lo almacena en sigpos,
  if (Serial.available()>0 ){
  int sigpos = Serial.read();
  valorSensor = analogRead(pinSensor); //valorsensor igual al valor del potenciometro de posicion actual
  Serial.println(  valorSensor); // para chequear en que posición esta el potenciometro.
  
  //en este caso si el valor siguiente es menor al del potenciometro, enciende el led de la izquierda, seria el atraso del motor.
   if (sigpos < valorSensor) {
    digitalWrite (pinLed, HIGH);
    digitalWrite (pinLed2,LOW);
  }
// en este caso si el valor siguiente es superior al del potenciometro, entonces enciende el led de la derecha, que seria el avance del motor.
else if (sigpos > valorSensor) {
  digitalWrite (pinLed2, HIGH);
  digitalWrite (pinLed,LOW);
}
//en este caso al ser iguales los valores se apagarian los led.
else if (sigpos == valorSensor) {
  digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW); }

  
  
  
 
}}
« Last Edit: October 30, 2012, 07:41:59 pm by nicko_esx » Logged

Forum Moderator
Zaragoza
Offline Offline
Newbie
*****
Karma: 0
Posts: 16
Aprende a desarrollar por ti mismo!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola!

Entiendo por tu código, que quieres mandarle un valor por puerto serie para compararlo con la lectura del conversor analógico-digital de Arduino y en función del resultado de esa comparación, hacer una u otra cosa.

Si te puede ayudar, aquí tienes un tuto sobre servos http://www.arduteka.com/2011/12/componentes-el-servomotor/

Al final de él, también tienes un enlace en el que hice un "chupitómetro" para mostrar como enviar a un servo a una posición determinada.

Si lo que quieres es mover un servo directamente con un potenciómetro, échale un vistazo a la instrucción map, con ella puedes transformar proporcionalmente los 1024 valores de la entrada analógica al rango de grados del motor.

Un saludo!
Logged

Aprende a desarrollar por ti mismo!!

@Arduteka
Facebook

Colombia
Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Viejo,

Así había hecho inicialmente, voy a probar el PID ver que tal y te cuento.

slds
Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hola gente.
Arduteca (pablo?). gracias por responder. soy seguidor de tu pagina. es una de las mejores de arduino en español. te hice comentarios en algun post.
te comento que lo que en realidad quiero hacer es utilizar un motor DC como servo motor(con un puente h obvio) . es decir poder ubicar al motor en la posicion que yo necesite. ya sea a travez de serial u otro modo. no importa tanto eso. sino el hecho de poder lograr que el arduino lea la posicion en la que se encuentre el motor a travez de un potenciometro y realizar una accion.

Selda81. espero tu avance smiley-grin. tu post en tu blog me inspiro para saber por donde ir. difiero en algunas cosas... pero es obvio todo esta a prueba. espero que el pid te de resultado. smiley-grin exitos smiley-grin

bueno esta noche intentare probar mi codigo cuando salga del trabajo  smiley-sleep

saludos amigos.
Logged

Madrid
Offline Offline
Sr. Member
****
Karma: 5
Posts: 481
Life isn't about finding yourself, life is about creating yourself!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


te comento que lo que en realidad quiero hacer es utilizar un motor DC como servo motor(con un puente h obvio) . es decir poder ubicar al motor en la posicion que yo necesite. ya sea a travez de serial u otro modo.
saludos amigos.

Por curiosidad el PID que pinta en todo esto?
Para ubicar la posición de un motor DC de forma exacta tienes que usar un encoder.
« Last Edit: October 30, 2012, 03:24:45 pm by yOPERO » Logged

Engineering is the art of
making what you want from
things you can get.

     

[SOLUCIONADO]

Offline Offline
Jr. Member
**
Karma: 2
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

yOPERO hola
gracias por comentar. en realidad cuando estuve averiguando que necesitaba para manejar posicionamiento de motor.. encontre en internet muchas respuestas que se vinculaban a PID.  smiley-roll-blue y como dije al comienzo. no se utilizarlo. averigue que es pero no se mas que eso...
por eso consulto sobre algun otro modo.
necesito basicamente poder mover un motor y retroalimentacion de posicion del mismo y arduino actuara en base a eso. repito la intencion es hacer un servo grande con un motor DC. utilizando arduino como controladora + un puente h.

yOPERO no se como utilizaria el encoder... se que es. pero no imagino como utilizarlo. creo que se me complicaria determinar posiciones en grados.
Logged

Colombia
Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

El encoder es el feedback, si, vas a saber donde esta (o cuantas vueltas dió) pero como haces efectivo tu posicionamiento...con el PID (método de sistema de control) vas a optimizar la salida del sistema, reduciendo el error, ya que lo ajustas progresivamente.

Aunque su uso depende de la aplicación ( si lo amerita) yo personalmente he revisado varios post acerca del uso de este método en fabricación de servos casero, y la precisión es bárbara ( claro que para lograr esta precisión, se requiere de caracterización matemática del proceso - mathlab/simulink/labview)

Yo voy a tratar de hacer un seudo (PD) realizando el ajuste manual (sin la caracterización) ya que lo que estoy haciendo, no tiene que ser tan preciso (aplicación de motor en un sistema de dirección de un carro RC)

Slds
Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Selda81
buena explicación. smiley-grin
espero con ganas ese seudo pid smiley-grin
lo del encoder si lei en internet. pero es todo un tema lograr fijar posicion. algunos me dijeron que podria usarlo como motor pap. y para saber la posicion seria necesario que el motor se mueva de un punto extremo a otro de deste modo se contarian los "pasos" y ubicariamos al motor por pasos que en el caso del encoder serian pulsos... es muy complejo me parece para lo que queremos hacer.
Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hola gente. aqui otra vez. pude probar el codio que subi antes. funciona. pero se genera una confucion. y es el hecho que al enviar datos por serial y a la vez imprimir por serial un valor. aparentemente por no haberlos distinguido correctamente entonces se genera una confucion de valores.... estoy viendo como separar estos valores.. tal vez con caracteres anteponiendolos....

por ahora quiero compartir otro modelo de codigo. en este caso utilizo un potenciometro para ingresar un valor, con el cual el potenciometro anterior de posicion actual se comparan. es decir un pote indica una posicion futura y se compara con el actual. en base a esto encienden los leds de izq o derecha. al mover el pote de posicion actual al valor indicado. se apagan los leds... funciona ok. espero explicarme bien. tal vez a alguien le sirva este codigo como ejemplo de practica.... tengo esperanzas que al utilizarlo con un motor y un puente h funcione de igual manera....

Code:
/*
 ejemplo encender 2 leds y apagar respectivamente, izquierda y derecha, dependendiendo
 del valor del potenciometro se enciende uno y otro.comparado con el potenciometro2 de posicion requerida o futura,
 o actual deseada. los leds se utilizan indicando el sentido de giro del motor. emulando la señal que se envia a un puente h para el movimiento respectivo.
 
 */
 
int pinSensor = A0;    // Entrada para el potenciómetro.posicion actual del motor. en este ejemplo moveria el pot manualmente emulando el moviento del motor, indicado por los leds.
int pinSensor2 = A1; //potenciometro de posicion requerida o futura
int pinLed2= 10; // led de posicion derecha, emularia la señal para el encendido del motor por el puente h en direccion a la derecha
int pinLed = 9; //led de posicion izquierda. idem anterior a la izquierda.
int valorSensor = 0;   // variable para el valor del sensor.
int posact = 0; //creo que es necesario que la variable empiece de cero.
int valorSensor2 = 0; //variable para el potenciometro 2
int sigpos = 0; // abreviatura de siguiente posición, valor que seria enviado por serial.

void setup() {
  // Declaramos el pin del Led como salida:
  pinMode(pinLed, OUTPUT);
  pinMode(pinLed2, OUTPUT);
  Serial.begin(9600);
}
 
void loop() {
   
 
  valorSensor2 = analogRead (pinSensor2);//lee los datos del potenciometro 2 de posicion requerida
    int sigpos = valorSensor2 ;
  valorSensor = analogRead(pinSensor); //valorsensor igual al valor del potenciometro de posicion actual
  Serial.print ("valorSensor");
  Serial.println ( valorSensor); // para chequear en que posición esta el potenciometro del motor.
  delay(200); //le doy delay para que se pueda leer los datos impresos. de lo contrario pasan demaciado rapido
  Serial.print ("valor del sensor sig");
  Serial.println(valorSensor2); //para chequear la posicion requerida del pote2
  delay(200);
  //en este caso si el valor siguiente es menor al del potenciometro, enciende el led de la izquierda, seria el atraso del motor.
   if (sigpos < valorSensor) {
    digitalWrite (pinLed, HIGH);
    digitalWrite (pinLed2,LOW);
    delay(200);
  }
// en este caso si el valor siguiente es superior al del potenciometro, entonces enciende el led de la derecha, que seria el avance del motor.
else if (sigpos > valorSensor) {
  digitalWrite (pinLed2, HIGH);
  digitalWrite (pinLed,LOW);
  delay(200);
}
//en este caso al ser iguales los valores se apagarian los led.
else if (sigpos == valorSensor) {
  digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(200); }
 
 
}

espero les guste
Logged

Colombia
Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Amigo, por ahí estuve cacharreando con lo del PID y ya va tomando forma, entra a mi blog y revisa el ejemplo, todavía se debe mejorar el sketch, o mejor aún usar la libreria PID existente.

Como te ha ido a ti? que has avanzado?

Cualquier cosa me cuentas.
Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hola selda. estoy parado esperando que me lleguen uns TIP que queme en la puente h en una prueba. teoricamente esta semana deberian tener los tip.
yo probe el ultimo codigo que subi con leds y funciona... pero bueno hay que ver con el motor que onda.
me parese muyyyy interesante lo tuyo. esta muy bueno. creo que terminaras con algo bueno. y sera de mucho interes para muchos. es un lindo proyecto smiley-grin
nos vemos.
Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 88
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

amigo Selda.
tengo algunos avances...
comienzo comentando que el puente h que utilizo es el siguiente.http://www.pyroelectro.com/tutorials/h_bridge_4_transistor/
por su facilidad de construccion y posibilidades de potencia.

el codigo que logre hasta hoy es el siguiente.
Code:
/*
 ejemplo mover motor a direcciones dependiendo valores comparados de dos potenciometros.
 uno de posicion actual y otro de posicion futura
 
 */
 
int pinSensor = A0;    // Entrada para el potenciómetro.posicion actual del motor. en este ejemplo moveria el pot manualmente emulando el moviento del motor, indicado por los leds.
int pinSensor2 = A1; //potenciometro de posicion requerida o futura
int pinLed2= 10; // pin de direccion derecha,  señal para el encendido del motor por el puente h en direccion a la derecha
int pinLed = 9; //pin de izquierda. idem anterior a la izquierda.
int valorSensor = 0;   // variable para el valor del sensor.
int posact = 0; //creo que es necesario que la variable empiece de cero.
int valorSensor2 = 0; //variable para el potenciometro 2
int sigpos = 0; // abreviatura de siguiente posición, valor que seria enviado por serial.
int difvalors =0; //diferencia entre sigpos y valor sensor
void setup() {
  // Declaramos el pin del Led como salida:
  pinMode(pinLed, OUTPUT);
  pinMode(pinLed2, OUTPUT);
  Serial.begin(9600);
}
 
void loop() {
   
 
  valorSensor2 = analogRead (pinSensor2)/2;//lee los datos del potenciometro 2 de posicion requerida
    int sigpos = valorSensor2 ;
  valorSensor = analogRead(pinSensor)/2; //valorsensor igual al valor del potenciometro de posicion actual
 
  difvalors = abs (sigpos - valorSensor);
 
 
  Serial.print ("valorSensor");
  Serial.println ( valorSensor); // para chequear en que posición esta el potenciometro del motor.
  delay(1); //le doy delay para que se pueda leer los datos impresos. de lo contrario pasan demaciado rapido
  Serial.print ("valor del sensor sig");
  Serial.println(valorSensor2); //para chequear la posicion requerida del pote2
  delay(1);
  //en este caso si el valor siguiente es menor al del potenciometro, , seria el atraso del motor.
   if (sigpos < valorSensor  && difvalors > 10 ) {
    digitalWrite (pinLed, HIGH);
    analogWrite (pinLed, 60); //pwm
    digitalWrite (pinLed2,LOW);
    delay(1);
  }
// en este caso si el valor siguiente es superior al del potenciometro, ,  seria el avance del motor.
else if (sigpos > valorSensor  && difvalors > 10)  {
  digitalWrite (pinLed2, HIGH);
  analogWrite (pinLed2, 60); //pwm
  digitalWrite (pinLed,LOW);
  delay(1);
}
//en este caso al ser iguales los valores se apagaria el motor.
else if (sigpos == valorSensor || difvalors < 10 ) {
  digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1); }

 
 
 
 
}

el video se los subo a la noche.
el esquema es simple. el arduino conectado por pin 9 y 10 a la puente h. el puente alimenta un motor, estoy utilizando la caja reductora de un servo mediano. mediante el reductor muevo un potenciometro para la posicion del motor.
otro potenciometro es el que indica el valorfuturo  o posicion deseada. que muevo manualmente obvio.
basicamente el motor se mueve a la direccion necesaria hasta llegar a su posicion y parar.
tengo que seguir depurando el codigo seguramente por los siguientes comportamientos:
1) el motor en algunas ocaciones al llegar al valor indicado, ocacionalmente avanza unos grados mas y vuelve a retroceder, nuevamente avanza unos grados pero menos que el anterior y retrocede o queda quieto. aparentemente buscaria la posicion.
2) ocurre tambien que el motor avanza hasta el valor indicado pero no se detiene exactamente sino que retrocede y avanza constantemente en unos pequeños grados...<<>> siempre en la "zona" del grado indicado.

estos comportamientos ocurrian constantemente, es decir nunca se detenia el motor en algun grado exacto sino que se acercaba y quedaba avanzando y retrocediendo.. hasta que modifique el codigo agregando lo que seguro vieron de la variable difvalors y tambien el tema de <o>10. con esto buscaba que el motor solo se moviera si la diferencia entre la posicion actual y la deseada eran mayores o menores a 10. como una especie de zona muerta para que el motor no quede en constante busqueda o avance retroceso pasandose de los valores. y tambien creo que sirve a modo de sanar el grado de error que tienen estos potenciometros economicos.

espero que les guste a los novatos. y a los expertos que me ayuden a mejorarlo.
saludos
« Last Edit: November 19, 2012, 07:13:05 pm by nicko_esx » Logged

Pages: [1] 2 3   Go Up
Jump to: