Pages: 1 [2] 3   Go Down
Author Topic: consulta. PID u otro modo- para posicion de motor-avances  (Read 8596 times)
0 Members and 1 Guest are viewing this topic.
Argentina-sgo
Offline Offline
Jr. Member
**
Karma: 2
Posts: 95
Novato, en electrónica desde el 2012.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

aqui les dejo el video prometido. creo que se puede observar algunos errores de posición que les comentaba anteriormente.
veremos de poder mejorar el codigo con la ayuda de esta comunidad smiley-grin
saludos smiley-grin


« Last Edit: November 19, 2012, 06:54:34 pm by nicko_esx » Logged

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

Hola Nicko,

bien por tu avance, lo que veo es q dejas el PWM constante a 60 y para q aumente la precisión debes hacer proporcional el pwm a la diferencia del valor del sensor con el pot 2.

Te cuanto que apenas fabrique mi nuevo puente H con el L298n, falta volver a configurar los valores y revisar el método PID de mi sketch. seguire pendiente de tus avances ya que apenas en q semana retomó yo.

Slds
Logged

Argentina-sgo
Offline Offline
Jr. Member
**
Karma: 2
Posts: 95
Novato, en electrónica desde el 2012.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hola selda.
lo del pwm lo dejo constante. por que fui probando y a mayor velocidad que esa, el motor se pasa del punto indicado. y queda bailando de un lado al otro sin poder encontrar el punto justo o medio. a pesar de haberle dejado ese +-10 de "zona muerta" por asi decirlo.
tambien lo probe con un motor de atornillador a bateria. y este con mucha mas potencia obvio, se pasa y jamas queda quieto.
no me habia percatado de variar la velocidad en base a la diferencia de los valores.. intentare algo al respecto.
tambien estaba pensando.. que podria conseguir potenciometros de mayor presicion.
lo que tambien me genera duda es si es mejor un potenciometro de mayor o menor K (resistencia). ahora utilizo unos de 100k lineales.

bueno. yo por mi lado estoy investigando lo del pid. pero es muy complejo para mi conocimiento en programacion por ahora.
a tu codigo mucho no lo entiendo... es la primera vez que toco lenguajes de programacion smiley-grin
nos vemos  hasta la victoria siempre smiley-grin
Logged

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


Hola Nicko,

Si no requieres tanta precisión entonces lo que has hecho esta bien, bueno y tampoco es que mi código sea la panacea, tambien estoy aprendiendo jajaja... trata con algo así (lo ley en la web)

Setpoint = analogRead(pinSensor2)

feedback= analogRead(pinSensor)

error = Setpoint - feedback

PWM =  error*K

donde K es una constante que hallaras por ensayo y error, delimitas a PWM para que si es > 255 entonces sea 255 y si es < 0 entonces sea 0, algo así es lo que hago, has visto un par de videos que saque de youtube? miralo y ve la precisión que alcanzan..mi reto es llegar a ese grado.

slds
Logged

Argentina-sgo
Offline Offline
Jr. Member
**
Karma: 2
Posts: 95
Novato, en electrónica desde el 2012.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

selda ahora entiendo! muchas gracias por la aclaracion. hoy mismo pruebo eso.
tambien estaba pensando que el motor se me pasaba del punto por ser el del un taladro o atornillador a bateria el cual tiene reductores pero es normal que gire unos grados mas cuando se le corta la alimentacion....
entonces estoy pensando buscar un motor de eleva cristales de automovil. un amigo mecanico me prometio uno.
esos funcionan con un sin fin en el eje del motor lo cual al quitar alimentacion traban el mecanismo. tal vez lograria que se detenga justo a tiempo.eso mas tu consejo seguro lograre algo mejor. espero tenerlo pronto smiley-grin
Logged

Argentina-sgo
Offline Offline
Jr. Member
**
Karma: 2
Posts: 95
Novato, en electrónica desde el 2012.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hola selda y gente en general
tengo algunos avances con modificaciones o agregados al codigo.
el video lo subire mas adelante. la diferencia con el video anterior es la velocidad a la que se mueve el motor. antes era una constante en 50 o 60 ya que mas veloz que eso el motor se pasaba del punto y en un intento de encontrar el punto indicado el motor quedaba adelantando y atrasando su direccion constantemente, es decir de << >> <<>> bailando smiley-grin
ahora si bien el motor se mueve mas rapido. dependiendo la distancia entre el valor actual y el deseado, al llegar a la zona el mismo disminuye su velocidad y al estar entre valores menores a 10 hasta 5 de distancia del punto indicado, se hara toque al sentido contrario como un intento de freno.
por ahora funciona bastante bien, en algunos momentos solamente se pasa un poco pero enseguida vuelve. seguramente es por la zona muerta o error y la mala calidad de los potenciometros que varian constantemente en un mismo punto uno o dos valores. entonces si el motor se frena al limite del error y el valor cambia por culpa del pote, intentara volver al punto indicado o zona aceptada.. espero ser claro con la explicaciones smiley-grin
bueno les dejo el codigo. como siempre a la espera de la opinion de los que deseen. y los expertos que puedan aportar algo smiley-grin
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
int pwm = 10 ;//variable constante de pwm
int pwm2 = 50; // para el freno. utilizando la direccion contraria con un delay
int delay1 = 200;// delay para el freno
int error = 20 ;// error para zona muerta
void setup() {
  // Declaramos el pin del Led como salida:
  pinMode(pinLed, OUTPUT);
  pinMode(pinLed2, OUTPUT);
  Serial.begin(9600);
pwm = constrain (pwm, 50 , 250);//valores min y max de pwm.

}
 
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); //valor absoluto de la diferencia
 
 
  Serial.print ("act");
  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 ("        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 > error ) {
    //digitalWrite (pinLed, HIGH);
    analogWrite (pinLed, pwm * difvalors); //pwm dependiendo la distancia para la velocidad.
    digitalWrite (pinLed2,LOW);
    delay(1);
switch (difvalors) {
      case 9: // en casos que los valores sean menores a 10 intentare frenar el motor direccioandolo al lado contrario
      analogWrite (pinLed2, pwm2); //pwm2 minima velocidad para frenar
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;
      case 8:
      analogWrite (pinLed2, pwm2); //pwm
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;
  case 7:
      analogWrite (pinLed2, pwm2); //pwm
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;

case 6:
      analogWrite (pinLed2, pwm2); //pwm
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;

case 5:
      analogWrite (pinLed2, pwm2); //pwm
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
    break;

}
}
// en este caso si el valor siguiente es superior al del potenciometro, ,  seria el avance del motor.
else if (sigpos > valorSensor  && difvalors > error)  {
  //digitalWrite (pinLed2, HIGH);
  analogWrite (pinLed2, pwm * difvalors); //pwm
  digitalWrite (pinLed,LOW);
  delay(1);

switch (difvalors) {
 
case 9:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;

case 8:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
break;
case 7:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
break;
case 6:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;
 case 5:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
break;
}
 }
//en este caso al ser iguales los valores se apagaria el motor.
else if (sigpos == valorSensor || difvalors < error ) {
  digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1); }

 
 
 
 
}
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,

Igual te puede servir este link acerca de control PID:
http://real2electronics.blogspot.com/2011/07/maqueta-de-control-pid-con-arduino.html

Saludos,


Igor R.
« Last Edit: December 02, 2012, 09:57:01 pm by Igor R » Logged


Argentina-sgo
Offline Offline
Jr. Member
**
Karma: 2
Posts: 95
Novato, en electrónica desde el 2012.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

gracias Igor. lo voy a leer. saludos
Logged

Argentina-sgo
Offline Offline
Jr. Member
**
Karma: 2
Posts: 95
Novato, en electrónica desde el 2012.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hola gente aquí nuevamente.
con algunos pequeños avances. pero mas que nada otro video con otro mecanismo. mas casero
consta de un motor de vibra de joystick con engranajes y potenciometros de 2.5 k
el puente h es el mismo mencionado anteriormente de pyro.
el codigo es el mismo con algunos ajustes en variables
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
int pwm = 3 ;//variable constante de pwm
int pwm2 = 60; // para el freno. utilizando la direccion contraria con un delay
int delay1 = 200;// delay para el freno
int error = 10 ;// error para zona muerta
void setup() {
  // Declaramos el pin del Led como salida:
  pinMode(pinLed, OUTPUT);
  pinMode(pinLed2, OUTPUT);
  Serial.begin(9600);
pwm = constrain (pwm, 50 , 250);//valores min y max de pwm.

}
 
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); //valor absoluto de la diferencia
  
  
  Serial.print ("act");
  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 ("        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 > error ) {
    //digitalWrite (pinLed, HIGH);
    analogWrite (pinLed, pwm * difvalors); //pwm dependiendo la distancia para la velocidad.
    digitalWrite (pinLed2,LOW);
    delay(1);
switch (difvalors) {
      case 9: // en casos que los valores sean menores a 10 intentare frenar el motor direccioandolo al lado contrario
      analogWrite (pinLed2, pwm2); //pwm2 minima velocidad para frenar
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;
      case 8:
      analogWrite (pinLed2, pwm2); //pwm
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;
  case 7:
      analogWrite (pinLed2, pwm2); //pwm
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;

case 6:
      analogWrite (pinLed2, pwm2); //pwm
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;

case 5:
      analogWrite (pinLed2, pwm2); //pwm
      digitalWrite (pinLed,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
    break;

}
}
// en este caso si el valor siguiente es superior al del potenciometro, ,  seria el avance del motor.
else if (sigpos > valorSensor  && difvalors > error)  {
  //digitalWrite (pinLed2, HIGH);
  analogWrite (pinLed2, pwm * difvalors); //pwm
  digitalWrite (pinLed,LOW);
  delay(1);

switch (difvalors) {
  
case 9:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;

case 8:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
break;
case 7:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
break;
case 6:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
 break;
 case 5:
      analogWrite (pinLed, pwm2); //pwm
      digitalWrite (pinLed2,LOW);
      delay(delay1);
      digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1);
break;
}
 }
//en este caso al ser iguales los valores se apagaria el motor.
else if (sigpos == valorSensor || difvalors < error ) {
  digitalWrite (pinLed2, LOW);
  digitalWrite (pinLed, LOW);
 delay(1); }
  
 
}

el video: notaran por momentos alguna lentitud. es el motor que le falta fuerza. es pequeño. pero los movimientos los probé bastante y es preciso. siempre analizando el serial y comparando las ubicaciones de ambos potenciometros. tanto el de posicion de motor como el de posicion deseada.
bueno espero les guste es un ejemplo de un trabajo de un novato smiley-grin


-------modificado 15/12/12
gente aqui les dejo otro video pero con un motor de stereo de 12v. mas potente que el anterior smiley-grin
en el video se puede ver el puente h que uso.
el codigo es el mismo pero con algunas modificaciones en valores. intentando encontrar el punto justo.
basicamente: cambios de valores en las variables:
 
Quote
pwm = 3
pwm2 = 60
delay1 = difvalors

tambien quite el mapeo siguiente
Quote
pwm = constrain (pwm, 50 , 100);//valores min y max de pwm.

espero les guste. este mecanismo se mueve mucho mas rapido y es bastante presiso. siempre teniendo en cuenta que el grado de error es 10.




« Last Edit: December 15, 2012, 05:38:40 pm by nicko_esx » Logged

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

Felicitaciones Nicko, genial, y hasta ahora retomo mi proyecto, ya adelante la parte del control de los motores con RF link; y ahora voy a hacer lo del control del servo. tu post me será de grand utilidad.

Cuenta del resto de tu proyecto.

Estamos en contacto.
Logged

Argentina-sgo
Offline Offline
Jr. Member
**
Karma: 2
Posts: 95
Novato, en electrónica desde el 2012.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hola amigo selda. un gusto saber que te agrado el avance.
el resto del proyecto lo deje un poquito de lado. puesto que comence otro que me tenia volando jeje
es la mini cnc. en el segmento de Proyectos de este foro esta el post smiley-grin espero tu visita ahi smiley-grin
siempre visito tu blog viendo en que avanzas.
saludos amigo
Logged

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

Hola a todos:
Quisiera preguntarles si es posible, solo teniendo un motor DC y un potenciometro colocado al final del eje de giro, obtener el modelo matematico del motor DC. El potenciometro gira de 0 a 300 grados y cuando probe el motor a penas le puse 3 voltios no se cuantas vueltas dio. eso es mas de 300 grados podrian ayudarme con este problema.
Cordiales saludos.
Logged

Argentina-sgo
Offline Offline
Jr. Member
**
Karma: 2
Posts: 95
Novato, en electrónica desde el 2012.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hola zaciatok
mira no se si entiendo bien lo que consultas.
quieres utilizar solo un potenciometro al motor. para darle la posicion y giro como mi ejemplo?
esto seria imposible con solo esos dos componentes. a lo sumo con un potenciometro obtendrias regular la velocidad del motor. y el giro depende de como conectes las polaridades. pero posiblemente se te queme el potenciometro. todo depende del consumo del motor. el funcionamiento es como basicamente la llave de un ventilador de tu hogar smiley-grin
osea. no hay forma de que sin un componente electronico puedas determinar posicion y sentido de giro. a lo sumo utilizando reles y llaves de corte. simulando una especie de puntos limites y puente h de reles. mucho lioooooo
esa es mi humilde opinion.
Logged

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

Me encanta tu proyecto!!  smiley-cool
me gustaría hacerte una consulta, si sería posible poder hacer un control del pwm de las salidas led con un potenciometro, yo estoy empezando en esto y estoy muy verde, jejeje un saludo!

pwm = constrain (pwm, 50 , 250);//valores min y max de pwm.
Logged

Argentina-sgo
Offline Offline
Jr. Member
**
Karma: 2
Posts: 95
Novato, en electrónica desde el 2012.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hola jesus
a ver. tu pregunta es si podemos variar el pwm con un potenciometro?
si es esa la pregunta. la respuesta es si.
te comento, que yo puse la variable pwm de esa manera para basicamente dejarla fija. por que a velocidades altas del motor. tiende a pasarse del punto o posicion que queriamos dejarlo.
para controlar la velocidad del motor por pwm primero tienes que tener en cuenta que tu puente H tenga esta opcion. en el caso del que utilizo yo funciona perfectamente con pwm
ahora el codigo:
primero obviamente declaramos la variables que utilizaremos como ejemplo podria ser : int pwmxx

necesitariamos tambien un tercer potenciometro que hay que declarar
luego basicamente en el cuerpo del codigo lo que cambia es

valorSensor3 = analogRead (pinSensor3);//lee los datos del potenciometro 3 de pwm
    int pwmxx = valorSensor3

tambien es necesario dar el mapeo antes, ya que el potenciometro tiene valores mucho mas altos que el pwm. el pwm va de 0 a 255
 pwmxx = map(valorSensor3, 0, 1024, 0 ,255 ); (no recuerdo si el potenciometro llega a 1024)

espero que te sirva. pero recuerda que en mi caso opte por mantener variables mas fijas de pwm para no errar en la velocidad del motor. ya que si el motor esta cerca del punto de posicion indicada y se mueve a toda velocidad, seguro se pasara.
saludos
Logged

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