Autor Tema: Robots cooperativos  (Leído 9104 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado pocher

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2569
RE: Robots cooperativos
« Respuesta #15 en: 13 de Abril de 2005, 05:38:00 »
Antes de responder a lo que preguntas, me parece que no se consigue que vaya:

- Atrás-Izquierda y
- Atrás-Derecha               ¡¡¡ Intenta solucionarlo !!!

Respecto a parar el motor de d.c. un tiempo, pero que se sigan mandando pulsos al Servo durante ese tiempo, tendrás que hacer la temporización por interrupción de algún TMR. Primero detectas si ha habido un cambio en esos dos bits, si lo ha habido cargas el TMR para un determinado tiempo. Para conseguir que este tiempo, sea más grande tendrás que aumentar el valor de una variable cada vez que se entre en la interrupción. Cuando esa variable llegue a un valor determinado (dependiendo de cuanta temporización desees) activarás al set_pwm1_duty(dutycalculado);

Previamente cuando hayas detectado un cambio en esos dos bits el set_pwm1_duty(dutycalculado); tendrá que estar desactivado con lo cual el motor de d.c. cuando se realice la temporización estará parado.

Los 4, set_pwm1_duty(dutycalculado); que utilizas en el programa los puedes borrar y usar un único set_pwm1_duty(dutycalculado); que lo pondrás antes del swich(input(pin_a4)). Este set_pwm1_duty(dutycalculado); estará condicionado por la temporización.

Si no quieres complicarte tanto, porqué no pones un pin más de PARO. Lo paras cambias lo que te dé la gana: velocidad o orientación y de nuevo lo pones en marcha.

Un saludo.

PD. Lo de la velocidad veo que ya lo has solucionado, conforme lo has pensado todos los números que pasen del 10 paran al motor d.c.

Desconectado aupadeportivo

  • PIC10
  • *
  • Mensajes: 18
RE: Robots cooperativos
« Respuesta #16 en: 13 de Abril de 2005, 08:26:00 »
Gracias maestro!
Respecto a que vaya atras izquierda y atras derecha, no quiero que vaya asi de momento. Atras- recto por ahora. Ya mirare esto de la interrupcion o alguna otra forma de mandar pulsos al servo previo paro del motor durante unos 2 0 3 segundos (para que de algun modo el servo se posicione correctamente con el motor desconectado). Bueno ya comento algo.

De nuevo mil gracias

Un saludo desde Valencia.

Desconectado aupadeportivo

  • PIC10
  • *
  • Mensajes: 18
RE: Robots cooperativos
« Respuesta #17 en: 21 de Abril de 2005, 08:55:00 »
Ey que tal? Bueno aqui el codigo el cual ha sido probado fisicamente con osciloscopio y funciona "a medias". Digo a medias xq el pic me hace todo correctamente. Al final configure tmr1 para que salte a interrupcion cada 20ms (por eso de los pulsos del servo) y en la rutina de interrupcion le digo ya el tiempo que debe estar a on el pulso (duty). Funciona to muy bien la única pega es que para los pulsos del servo necesito meter en el delay un numero en microsegundos y no me lo coge, en el osciloscopio sale nada un pulso de apenas microseg cuando si realmente le estoy diciendo que me meta un delay de 1200 us  no me lo hace.

Lo gracioso es que en el delay cuando en vez de poner us lo pongo en ms y pongo varios anchos de pulso (1 2 3....)ms me lo hace perfecto.

He probado mil cosas, meterle un float y meterselo en milisegundos y nada el rollo parece darselo en milis pero no veo la forma de que funcione y no se muy bien xq no funciona la verdad.

Te agradeceria si le podias echar un vistazo y si hay alguna restriccion en la funcion delay u otra forma de poder darle ese retardo (1200us, 600us etc). Si lo pongo en ms como float no me funciona, y debo ponerlo como float xq quiero pulsos de 1.2 0.6 etc. Si lo pongo en microsegundos como 1200... no me funciona.

¿Alguien sabe porque?????



#include <16F876.H>
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, WRT
#use Delay(Clock=4000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 5   // Identificador asociado al registro de dirección 5
#byte port_b = 6   // Identificador asociado al registro de dirección 6
#byte port_c = 7   // Identificador asociado al registro de dirección 7

//int y,x, retardo;//

void main() {
int pe, dutycalculado, xx;
set_tris_a(0x00);  // Puerto A como salida
set_tris_b(0xFF);    // Puerto B entrada
set_tris_c(0x00);  
output_a(0x00);    // Todos los pines de PORTA en 0
output_b(0x00);    // Idem con PORTB
output_c(0x00);

setup_timer_2(T2_DIV_BY_16,249,1) ; // Div=16 ; PR2=249 ; Postscale=1
setup_CCP1 (CCP_PWM);               //Configuracion PWM
enable_interrupts(GLOBAL);     // Activamos interrupciones globales
enable_interrupts(INT_TIMER1); // ... y la interrupcion por TMR1
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1);  //Configuracion TMR1 y preescaler

set_timer1(45536);   // Cada 20 ms salto a interrupcion  65536-(temporizacion*Fosc/4*preescaler)            

   while(1) {

set_pwm1_duty(0);
delay_ms(3000);

pe=0b11110000 & port_b;


while ((pe)==((0b11110000)&(port_b)))  //mientras no cambio en posicion del servo...
{



xx= 0b00001111 & port_b; //velocidad (1=10%, 2=20%......10=100%)


if(xx>10) //
{
xx=0;
set_pwm1_duty(0); //Si es mayor a 10 duty=0
}
else
{
dutycalculado= 25 * xx ; // Valor a cargar en duty
set_pwm1_duty(dutycalculado);
}

switch(input(pin_c6))
{
case 0: //motor alante

output_high(pin_c7);

break;

case 1: // motor atras

output_low(pin_c7);

break;
}
}                      
   
   }
             

}

#INT_TIMER1                  
void interrupcion()
{
long retardo;
int y, x;
set_timer1(45536);
x=port_b;

y=0b11110000 & x;

switch(y){
case 0:          // 0000 servo recto

// retardo=1200;  //recto
 retardo=1;
break;
case 16:
//retardo=1466;
 retardo=2;   //giro derecha abierto 0001
break;

case 48:
//retardo=1800;
 retardo=3;   //giro derecha cerado  0011
break;
case 64:
//retardo=933;
 retardo=4;  // giro izquierda abierto 0100
break;

case 192:
//retardo=600;
 retardo=5;    // giro izquierda cerrado  1100
break;


}

output_high(pin_c0);
delay_ms(retardo);
output_low(pin_c0);                        

}



Muchas gracias y espero que me hayas entendido.

Gracias maestro!!
Un saludo.

Desconectado pocher

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2569
RE: Robots cooperativos
« Respuesta #18 en: 22 de Abril de 2005, 00:00:00 »
Sí, lo de porqué no te funciona está claro. La función delay_ms o delay_us si lo que hay dentro del paréntesis es una variable solo admite valores enteros entre 0 y 255, sin embargo si es una constante puedes meterle hasta 65535.

Puedes hacer al final de todo: if (retardo==5); delay_us(600) etc

Un saludo

Desconectado aupadeportivo

  • PIC10
  • *
  • Mensajes: 18
RE: Robots cooperativos
« Respuesta #19 en: 25 de Abril de 2005, 16:49:00 »
buenas de nuevo. Montando fisicamente el cacharrito se ve que a la hora de meterle los pulsos al servo es bastante inestable.

He leido por ahi una respuesta tuya pocher sobre crear una base de tiempo mas pequeña que mis 20ms necesarios y con dos contadores poder hacer qe este en alto el duty necesario y el resto de los 20ms a off. Quisiera probar eso pero estoy dandole vueltas y no se. en proteus por lo menos no me funciona.

Alguna idea o algo xq la verdad toy ya desesperao. Muchas gracias de nuevo xavalote, me estas ayudando mucho y aprendiendo bastante con tus consejos

Un saludo.

Desconectado aupadeportivo

  • PIC10
  • *
  • Mensajes: 18
RE: Robots cooperativos
« Respuesta #20 en: 28 de Abril de 2005, 11:31:00 »
Bueno aca esta el programita para controlar el movimiento de un robotito. La direccion la proporciona un servo y el movimiento un motor dc (ambos controlados mediante pwm).

#include <16F876A.H>
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD//, WRT
#use Delay(Clock=4000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 5             // Identificador asociado al registro de dirección 5
#byte port_b = 6             // Identificador asociado al registro de dirección 6
#byte port_c = 7             // Identificador asociado al registro de dirección 7

int periodo, dutty;       // Definimos variables globales

#INT_TIMER1                  //Rutina de atención a la interrupcion
void interrupcion()
   {
   set_timer1(65472);            //Recarga el timer a 100us (-36us) Base de tiempo

   periodo=periodo+1;            // cada vez que se entre incrementamso periodo

      if(periodo<dutty)             //Duracion de estado alto PWM segun posicion servo
      {
      output_high(pin_c0);
      }
      else
      {
      output_low(pin_c0);
      }
      if(periodo==200)              // Acaba el periodo
      {
      periodo=0;
      }
   }  

   void main()
   {
   int pe, xx, dutycalculado;
   set_tris_a(0x00);                            // Puerto A como salida
   set_tris_b(0xFF);                            // Puerto B entrada
   set_tris_c(0b01000000);                      // Pin C6 indica sentido del motor alante o atras
   output_a(0x00);                              // Todos los pines de PORTA en 0
   output_c(0b0000000);                         // Todos los pines de PORTC en 0
   enable_interrupts(GLOBAL);                   // Activamos interrupciones globales
   enable_interrupts(INT_TIMER1);               // ... y la interrupcion por TMR1
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1);  //Configuracion TMR1 y preescaler
   setup_timer_2(T2_DIV_BY_16,249,1) ;          // Div=16 ; PR2=249 ; Postscale=1
   setup_CCP1 (CCP_PWM);                        //Configuracion PWM
   set_timer1(65472);                              // Cada 100 us salto a interrupcion  65536-(temporizacion*Fosc/4*preescaler)  (-36us)
   periodo=dutty=0;                                
 

   while(1)
   {



   pe=0b11110000 & port_b;
   switch (pe)             // Comprobacion para posicionar el servo
   {

   case 192:               // servo cerrado izquierda pulso de 600us 1100...
   dutty=6;
   break;

   case 48:                // servo cerrado derecha  pulso de 1800us  0011...
   dutty=18;
   break;

   case 240:               // servo recto pulso de 1200us  1111...
   dutty=12;
   break;

   case 16:                // servo abierto derecha  pulso de 1500us  0001...
   dutty=15;
   break;

   case 128:               // servo abierto izquierda pulso de 900us  1000...
   dutty=9;
   break;
   }

   set_pwm1_duty(0);       //Apagamos motor durante 1.5 sg para posicionar correctamente el servo
   delay_ms(1500);
             
    while ((pe)==((0b11110000)&(port_b)))      //mientras no cambios en posicion del servo (4 bits de mayor peso en port b)
    {
      xx= 0b00001111 & port_b;                   //velocidad (1=10%, 2=20%......10=100%)
      if(xx>10) //
      {
      xx=0;                                      // Si es mayor a 10 la parte baja de portb qe marca la velocidad
      set_pwm1_duty(0);                          //Paramos motor
      }
      else
      {
      dutycalculado= 25 * xx ;                   // Valor a cargar en duty segun relacion
      set_pwm1_duty(dutycalculado);
      }
      switch(input(pin_c6))
      {
      case 0: //motor alante

      output_high(pin_c7);

      break;

      case 1: // motor atras

      output_low(pin_c7);

      break;
      }
   }

 }


}

Desconectado pocher

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2569
RE: Robots cooperativos
« Respuesta #21 en: 28 de Abril de 2005, 13:08:00 »
Bien, me alegra que lo hayas resuelto. Si tengo un rato lo simulo.

Un saludo

Desconectado aupadeportivo

  • PIC10
  • *
  • Mensajes: 18
RE: Robots cooperativos
« Respuesta #22 en: 11 de Mayo de 2005, 05:16:00 »
Ey que hay de nuevo amigo?

Bueno hemos estado probando la comunicacion i2c y no nos funciona. Una duda:

La rutina esta que hay por el foro de comunicacion i2c que funciona, utiliza un servicio a interrupcion para leer el dato recibido y almacenarlo vale, pero en mi programita donde ya tengo una interrupcion para el servo (servicio cada 100us), ¿habria algun problema en meter hay esa rutina de comunicacion i2c con interrupcion o se armaria un cacao el pic, ya que me tendria que atender a las dos interrupciones y se pudiera dar el caso de conflictos? Ahi no puedo dar prioridad a interrupcion ya que cada 100 us me esta entrando ala del servo y es imprescindible que me entre alli, pero si recibo un dato mientras estoy atendiendo a la otra interrupcion......Llorica

Hay alguna otra forma de comunicacion i2c que no sea de este tipo y funcione?


Gracias, un saludo.

Desconectado aupadeportivo

  • PIC10
  • *
  • Mensajes: 18
RE: Robots cooperativos
« Respuesta #23 en: 19 de Mayo de 2005, 06:38:00 »
Ey pocher ya ta resuelto esto del i2c y tal. Ya puse el programita alla en eficacia de pwm por software pa la gente si le interesaba y tal. Ahora pasaremos a programar el esclavo que recoja la informacion de los sensores y con varios modos de funcionamiento. Ya ire comentando cosillas segun vayan saliendo.  

Un saludo