Autor Tema: control velocidad motor dc con poteciometro y sensor hall como implementarlo?  (Leído 5777 veces)

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

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:control velocidad motor dc con poteciometro y sensor hall como implementarlo?
« Respuesta #15 en: 05 de Abril de 2020, 19:02:54 »
remi04
Excelente explicación,, gracias mil.
mi objetivo no es copiar y pegar un código, me interesa conocer a profundidad el por que de las cosas. En realidad he aprovechado  este ejercicio para tratar de comprender  mejor los timmer ya que siempre me han dado dolores de cabeza.

No he seguido adelante tratando de comprender a plenitud el código que me proporcionaste por lo que me atrevo a preguntar de nuevo..
Ademas generalmente trabajo en CCS y noto algunas cosas que no he realizado antes..

he colocado comentarios al programa, me podrian decir por favor si son acertados, gracias
Código: C
  1. volatile boolean first;
  2. volatile boolean triggered;
  3. volatile unsigned long overflowCount;
  4. volatile unsigned long startTime;
  5. volatile unsigned long finishTime;
  6.  
  7.  //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  8. // here on rising edge
  9. void isr ()
  10. {
  11.   unsigned int counter = TCNT1;  // quickly save it // guarde en counter lo que lleva hasta el momento timer1
  12.  
  13.   // wait until we noticed last one
  14.   if (triggered) // si es true sale de la funcion - si es false sigue
  15.     return;
  16.  
  17.   if (first)// si es true toma la lectura actual y lo pone a falso para que no vuelva a entrar y sale de la funcion  / si es false sigue
  18.     {
  19.     startTime = (overflowCount << 16) + counter; //guarda el primer valor
  20.     first = false;
  21.     return;  
  22.     }
  23.    
  24.   finishTime = (overflowCount << 16) + counter; // guarda el ultimo valor
  25.   triggered = true; // lo pone a true para garantizar que (triguered)no vuelva a entrar a la interrupcion y que entre al loop
  26.   detachInterrupt(0);   //detiene las interrupciones
  27. }  // end of isr
  28.  //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  29.  
  30.  
  31.  //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  32. // timer overflows (every 65536 counts)
  33. ISR (TIMER1_OVF_vect)
  34. {
  35.   overflowCount++;           //cada que TIMER1 llegue a 65535 overflowCount++ aumenta 1
  36. }  // end of TIMER1_OVF_vect
  37.  
  38.  
  39. void prepareForInterrupts ()
  40.   {
  41.   // get ready for next time  //  prepárate para la próxima vez
  42.   EIFR = _BV (INTF0);  // clear flag for interrupt 0
  43.   first = true;                                     // habilita la primera lectura
  44.   triggered = false;  // re-arm for next time       //permite que entre a la interrupcion
  45.   attachInterrupt(0, isr, RISING);                  // habilita la interrupcion - de 0 a 1
  46.   }  // end of prepareForInterrupts
  47.  //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  
  48.  
  49. void setup () {
  50.   Serial.begin(115200);      
  51.   Serial.println("Frequency Counter");
  52.  
  53.   // reset Timer 1
  54.   TCCR1A = 0;
  55.   TCCR1B = 0;  // timer1 sin preescaler 0 - 65536
  56.   // Timer 1 - interrupt on overflow
  57.   TIMSK1 = _BV (TOIE1);   // enable Timer1 Interrupt // habilita interrupcion
  58.   // zero it
  59.   TCNT1 = 0;    
  60.   // start Timer 1
  61.   TCCR1B =  _BV (CS10);  //  coloca a 1 CS10
  62.  
  63.   // set up for interrupts
  64.   prepareForInterrupts ();  
  65.  
  66. } // end of setup
  67.  
  68. void loop ()
  69.   {
  70.  
  71.   if (!triggered) // no pasa hasta que no sea true, y sigue preguntando hasta que haga la segunda lectura
  72.     return;
  73.  
  74.   unsigned long elapsedTime = finishTime - startTime;
  75.   float freq = 1.0 / ((float (elapsedTime) * 62.5e-9));  // each tick is 62.5 nS
  76.  
  77.   Serial.print ("Took: ");     //tics
  78.   Serial.print (elapsedTime);  // tiempor transcurrido: finishTime - startTime;
  79.   Serial.print (" counts. ");
  80.  
  81.   Serial.print ("Frequency: ");
  82.   Serial.print (freq);
  83.   Serial.println (" Hz. ");
  84.  
  85.   // so we can read it  //para que podamos leerlo
  86.   delay (100);
  87.  
  88.   prepareForInterrupts ();   //prepararse para las interrupciones
  89. }   // end of loop

-En las siguientes lineas de código no veo remarcado con ningún color en el "IDE" (ISR (TIMER1_OVF_vect))así como cuando se llama a una función,( void isr () )void se pone azul, es normal cuando se trata de interrupción por timer?
Código: C
  1. ISR (TIMER1_OVF_vect)
  2. {
  3.   overflowCount++;           //cada que TIMER1 llegue a 65535 overflowCount++ aumenta 1
  4. }  // end of TIMER1_OVF_vect
saludos...
« Última modificación: 06 de Abril de 2020, 12:13:07 por johenrod »
Si algo parece complicado... es por que esta mal explicado.

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:control velocidad motor dc con poteciometro y sensor hall como implementarlo?
« Respuesta #16 en: 07 de Abril de 2020, 22:03:23 »
cordial saludo,,,
ya tengo trabajando el motor el problema es cuando tengo que subir la velocidad..
Código: C
  1. if (dato sensor <=18&& freq<20)
  2.  {
  3.  datosensor++;
  4.  }
Aquí obviamente no me incrementa si no en 1 por que al volver al bucle toma a lectura actual del conversor A/D (he intentado varias formas incluso con "while" pero el motor o se queda quieto o arranca como loco.

tambien intente esto..
Código: C
  1. if ((datoSensor <=18)&& (freq<18))
  2.  {
  3.   suma =suma++;
  4.  datoSensor=datoSensor +suma;
  5.   Serial.print ("++: ");     //tics
  6.     Serial.println (datoSensor);
  7.     analogWrite(MOSFET, datoSensor); //Valor analogico para la salida
  8.     delay(10);
  9.  }
  10.  
  11. if ((datoSensor <=18)&& (freq>18))
  12.  {
  13.   suma =suma--;
  14.  datoSensor=datoSensor -suma;
  15.    Serial.print ("--: ");     //tics
  16.     Serial.println (datoSensor);
  17.     analogWrite(MOSFET, datoSensor); //Valor analogico para la salida
  18.     delay(10);
  19.  }

tambien intente esto y trabaja mejor pero aun con errores..
Código: C
  1. datoSensor = analogRead(Sensor); //Leemos el dato del sensor y lo guardamos en la variable
  2.   datoSensor=map(datoSensor,0,1023,15,70);
  3.   //analogWrite(MOSFET, datoSensor); //Valor analogico para la salida
  4.   //delay(10); //Detenemos el programa 25 milisegundos
  5.   Serial.print ("actual: ");     //tics
  6.     Serial.println (datoSensor);
  7. if ((datoSensor <=20)&& (freq<16))
  8.  {
  9.   suma=datoSensor;
  10.   suma1=suma +1;
  11.  
  12.   Serial.print ("++: ");     //tics
  13.     Serial.println (suma1);
  14.     analogWrite(MOSFET, suma1); //Valor analogico para la salida
  15.     //delay(5);
  16.  }
  17.  
  18. if ((datoSensor <=20)&& (freq>16))
  19.  {
  20.   suma=datoSensor;
  21.   suma1=suma -1;
  22.  
  23.   Serial.print ("--: ");     //tics
  24.     Serial.println (suma1);
  25.     analogWrite(MOSFET, suma1); //Valor analogico para la salida
  26.     //delay(5);
  27.  }

Estoy mapeando la lectura ya que necesito el PWM entre 15 Y 70, no consigo retener la lectura para incrementar la velocidad, por ejemplo cuando la lectura del pot, esta en 15 me debe mantener 16.6 rpm, alguna sugerencia por favor..

dejo el código completo
Código: C
  1. volatile boolean first;
  2.   volatile boolean triggered;
  3.   volatile unsigned long overflowCount;
  4.   volatile unsigned long startTime;
  5.   volatile unsigned long finishTime;
  6.  
  7.   int Sensor = A0; // Declaramos la variable del potenciómetro pin 7 attiny13
  8.   int MOSFET = 11; // Declaramos la variable del led  pin6
  9.   int datoSensor = 0; // Variable para el valor del sensor
  10.   int suma=0;
  11.   float freq =1 ;
  12.    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  13.   // here on rising edge
  14.   void isr ()
  15.   {
  16.     unsigned int counter = TCNT1;  // quickly save it // guardalo rapidamente
  17.    
  18.     // wait until we noticed last one
  19.     if (triggered) // si es true sale de la funcion - si es false sigue
  20.       return;
  21.    
  22.     if (first)// si es true toma la lectura actual y lo pone a falso para que no vuelva a entrar y sale de la funcion  / si es false sigue
  23.       {
  24.       startTime = (overflowCount << 16) + counter; //guarda el primer valor
  25.       first = false;
  26.       return;  
  27.       }
  28.      
  29.     finishTime = (overflowCount << 16) + counter; // guarda el ultimo valor
  30.     triggered = true; // lo pone a true para garantizar que (triguered)no vuelva a entrar a la interrupcion y que entre al loop
  31.     detachInterrupt(0);   //detiene las interrupciones
  32.   }  // end of isr
  33.    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  34.  
  35.    
  36.    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  37.   // timer overflows (every 65536 counts)
  38.   ISR (TIMER1_OVF_vect)
  39.   {
  40.     overflowCount++;           //cada que TIMER1 llegue a 65535 overflowCount++ aumenta 1
  41.   }  // end of TIMER1_OVF_vect
  42.    
  43.    
  44.   void prepareForInterrupts ()
  45.     {
  46.     // get ready for next time  //  prepárate para la próxima vez
  47.     EIFR = _BV (INTF0);  // clear flag for interrupt 0
  48.     first = true;                                     // habilita la primera lectura
  49.     triggered = false;  // re-arm for next time       //permite que entre a la interrupcion
  50.     attachInterrupt(0, isr, FALLING);                  // habilita la interrupcion - de 0 a 1
  51.     }  // end of prepareForInterrupts
  52.    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  
  53.    
  54.   void setup () {
  55.     Serial.begin(115200);      
  56.     Serial.println("Frequency Counter");
  57.     pinMode(MOSFET, OUTPUT); // Asigna el pin del led como salida
  58.    
  59.     // reset Timer 1
  60.     TCCR1A = 0;
  61.     TCCR1B = 0;  // timer1 sin preescaler 0 - 65536
  62.     // Timer 1 - interrupt on overflow
  63.     TIMSK1 = _BV (TOIE1);   // enable Timer1 Interrupt // habilita interrupcion
  64.     // zero it
  65.     TCNT1 = 0;    
  66.     // start Timer 1
  67.     TCCR1B =  _BV (CS10);  //  coloca a 1 CS10
  68.    
  69.     // set up for interrupts
  70.     prepareForInterrupts ();  
  71.    
  72.   } // end of setup
  73.    
  74.   void loop ()
  75.     {
  76.  
  77.   //start impulsar motor
  78. if (datoSensor<=1)//
  79. {
  80. datoSensor=12;
  81. Serial.print ("datoSensor in");
  82. Serial.println (datoSensor);
  83. analogWrite(MOSFET, datoSensor);
  84. delay(500);
  85.      
  86. }
  87.    if (!triggered) // no pasa hasta que no sea true, y sigue preguntando hasta que haga la segunda lectura
  88.       return;
  89.     unsigned long elapsedTime = finishTime - startTime;
  90.     float freq = 1.0 / ((float (elapsedTime) * 62.5e-9));  // each tick is 62.5 nS
  91.  
  92.   datoSensor = analogRead(Sensor); //Leemos el dato del sensor y lo guardamos en la variable
  93.   datoSensor=map(datoSensor,0,1023,15,70);
  94.   analogWrite(MOSFET, datoSensor); //Valor analogico para la salida
  95.   delay(10); //Detenemos el programa 25 milisegundos
  96.  
  97. if (dato sensor <=18&& freq<20)
  98.  {
  99.  datosensor++;
  100.  }
  101.  
  102. analogWrite(MOSFET, datoSensor); //Valor analogico para la salida
  103.  
  104.    
  105.     Serial.print ("Took: ");     //tics
  106.     Serial.print (elapsedTime);  // tiempor transcurrido: finishTime - startTime;
  107.     Serial.print (" counts. ");
  108.    
  109.     Serial.print ("Frequency: ");
  110.     Serial.print (freq);
  111.     Serial.println (" Hz. ");
  112.    
  113.     // so we can read it  //para que podamos leerlo
  114.  
  115. // Serial.print ("datoSensor");
  116. //Serial.println (datoSensor);
  117.  
  118.     delay (100);
  119.     prepareForInterrupts ();   //prepararse para las interrupciones
  120.   }   // end of loop

Gracias de antemano...
« Última modificación: 08 de Abril de 2020, 00:18:23 por johenrod »
Si algo parece complicado... es por que esta mal explicado.