Arduino Forum

International => Español => Topic started by: isaias308 on Nov 26, 2015, 07:31 am

Title: control de RPM con teclado matricial
Post by: isaias308 on Nov 26, 2015, 07:31 am
buen dia comunidad, he estado con algunas dudas en una practica que tengo que realizar, que es un control de RPM mediante un teclado matricial, donde yo le ingreso las rpm que deceo y este responde llegando a las rpm deseadas,  pero el motor que se utiliza no es de DC es de AC el cual por medio de un cruce por cero controlo el disparo del triac,pero mi duda es como controlo las rpm por teclado matricial, anteriormente lo habia realizado con un potenciometro pero ahora se requiere con teclado, anexo el codigo hasta dondel llevo si alguien tuviera una idea o me diera una orientacion se los agradeceria

Code: [Select]

#include <LiquidCrystal.h>
#include <TimerOne.h>   
#include <Keypad.h>
LiquidCrystal lcd(14,15,16,17,18,19);     
//teclado
int ans;
int cuadro=5;
int fila =0;
int b=0;
int dato;
char regt[]={0,0,0,0};
const byte Rows=4;
const byte Cols=4;
byte pinsFilas[Rows] = {22, 24,26,28};//{A8, A9 , A10, A11}; //{7, 6, 5, 4};
byte pinsColumnas[Cols] ={30, 32, 34, 36 };// {A12,A13,A14,A15}; // {3, 2, 1, 0}

char hexakeys[Rows][Cols]={
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'} 
};

Keypad tecla=Keypad(makeKeymap(hexakeys),pinsFilas,pinsColumnas,Rows,Cols);
//RPM
 int ticsPerRev = 12;       // define el numero de ranuras del encoder
  float rpm = 0.0;  // variable flotante que mide la rpm
  volatile int rpmcount =0;  //variable manipulada durante las interrupciones
  unsigned long timeold = 0; //d_t= millis()-timeold;
  int d_t;

int statusPin = 7;             // salida al conector de entrada Vcc del encoder
volatile byte status= LOW;    // inicializacion del estado
 
 
//Cruce por cero
volatile int i=0;               // Variable usada como contador
volatile boolean zero_cross=0;  // Boolean para la interrupcion del cruce por cero
int AC_pin = 3;                // salida al optoTriac
int POT_pin = A0;             // entrada del potenciometro
int dim = 128;                    // Dimming level (0-128)  0 = on, 128 = 0ff
int pass=8;
int dim2,dim3=0;
int freqStep = 65; //frecuencia de lectura a 60Hz formula =10000/120Hz
 
void setup() {                                 
  lcd.begin(16, 2); //inicializacion de la lcd
  pinMode(AC_pin, OUTPUT);                          // salida al MOC
  attachInterrupt(0, zero_cross_detect, RISING);   // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  Timer1.initialize(freqStep);                      // libreria TimerOne inicializada
  Timer1.attachInterrupt(dim_check, freqStep);     
  Serial.begin(9600);   
  lcd.clear();   
  //RPM
  attachInterrupt(2, rpm_fun, FALLING);
     
   
   pinMode(statusPin, OUTPUT);
   digitalWrite(statusPin,HIGH);
 
}
//cruce por cero
void zero_cross_detect() {   
  zero_cross = true;             
  i=0;
  digitalWrite(AC_pin, LOW);
}                                 
//TRIAC
void dim_check() {                   
  if(zero_cross == true) {             
    if(i>=dim) {                     
      digitalWrite(AC_pin, HIGH);       
      i=0;  //                         
      zero_cross=false;    // detector de zero_cross
    }
    else {
      i++;  //                     
    }                               
  }                                 
}                                   
void loop() {
  dim=analogRead(POT_pin)/8;
 //teclado
 lcd.setCursor(0,0);
 lcd.print("RPM1");
   char tiempo = tecla.getKey();
     lcd.display();
    if(tiempo != NO_KEY){
         if(b<=4)
    lcd.setCursor(cuadro,fila); 
    regt[b]=tiempo;
    dato=atol(regt);
        lcd.print(regt[b]);
      b++;     
    cuadro++;
     if(tiempo == '#' ){
      lcd.clear();
      cuadro=5;
      fila=0;
      b=0;
      dato=0;
      dim=128;
     }   
    }
    if(dato!=0){

      detachInterrupt(2);
   d_t=millis()-timeold;
   
   if (d_t >= 1000)
    {
     rpm = float(60.0*1000.0)/float((d_t))*float(rpmcount)/ticsPerRev;
 
      timeold = millis();
      d_t=0; //reset d_t
     
      //Serial Port Output
      Serial.print("Time(ms) ");
      Serial.print(timeold);
      Serial.print(" TicsPerInterval ");
      Serial.print(rpmcount);
      Serial.print(" RPM ");
      Serial.println(rpm);
      lcd.setCursor(0,1);
      lcd.print("RPM:");
      lcd.print(rpm);
          rpmcount = 0; //reset rpmcount
   
  }
  //Restart the interrupt processing
  attachInterrupt(2, rpm_fun, FALLING);
    }
   
   
}

void rpm_fun()
 {
   detachInterrupt(2);
   
   rpmcount++; //update rpmcount
     
 
   attachInterrupt(2, rpm_fun, FALLING);
 }






Title: Re: control de RPM con teclado matricial
Post by: surbyte on Nov 26, 2015, 02:30 pm
Con el teclado ingresas tu setpoint o sea a que RPM quieres que el control del motor mantenga.
Debes leer las RPM con algún método. 
Alternativas hay muchas, te sugiero dos: 
1. Rueda dentada y usas un sensor de efecto hall para contar dientes y obtienes RPM.
2. Encoder. Rueda con ranuras y optoacoplador. Hay muchas variantes de esta opción

Esto indica que estas usando un MEGA como mínimo y en su INT2 tienes un sensor de RPM.
Code: [Select]
void rpm_fun() {
   detachInterrupt(2);
   rpmcount++; //update rpmcount
   attachInterrupt(2, rpm_fun, FALLING);
 }


Es asi?
Title: Re: control de RPM con teclado matricial
Post by: isaias308 on Nov 26, 2015, 09:07 pm
si de hecho por medio de un encoder ya estoy leyendo las RPM,pero el objetivo es que, ingrese las RPM deseadas por medio del teclado, por ejemplo que si yo quiero 1200RPM la ingrese por el telclado y este mande el PWM al MOC3011 de tal manera que el motor AC llegue  las 1200RPM ingresa, y hasta ahora solo he podido controlar las RPM por medio de un potenciometro alguna idea?
Title: Re: control de RPM con teclado matricial
Post by: surbyte on Nov 27, 2015, 04:43 am
Tienes que armar un lazo de control sea PI o PID. 
Aca tienes un ejemplo (http://real2electronics.blogspot.com.ar/2011/07/maqueta-de-control-pid-con-arduino.html) que tiene algunos puntos de contacto como para introducirte en el tema.

Tu MOC3011 es una interfaz que hara girar mas o menos el motor AC según el PWM.
Haz una tabla con numeros puntos variado el duty cycle, desde 0 a 255. Digamos que lo haces de a 5.
Por cada lectura tendras una RPM.
Luego esa curva de RPM podras o no verla en un Excel y tal vez observarás que es lineal o no.
Este es un método que te ayuda a entrar con RPM (tu setupoint) y salir con el DT Duty Cycle que asegura esas RPM.

Luego esta un método mucho mas elaborado como el PID. Pero requiere mas trabajo.


Title: Re: control de RPM con teclado matricial
Post by: noter on Nov 27, 2015, 04:34 pm
Tal vez me equivoque, Ricardo, pero me parece que ahora mismo su problema pudiera ser el diseño del "menú" de entrada de datos. ¿Es eso, isaias308?
Title: Re: control de RPM con teclado matricial
Post by: surbyte on Nov 27, 2015, 07:26 pm
Ademas de tener un menú para manejarme mejor el dice

Quote
pero mi duda es como controlo las rpm por teclado matricial, anteriormente lo habia realizado con un potenciometro pero ahora se requiere con teclado, anexo el codigo hasta dondel llevo si alguien tuviera una idea o me diera una orientacion se los agradeceria
Asi que creo que quiere controlar las RPM con un dato ingresado por teclado.
Title: Re: control de RPM con teclado matricial
Post by: isaias308 on Nov 28, 2015, 06:28 pm
asi es como dice surbyte solo quiero controlar las RPM mediante el teclado matricial,ya tengo la etapa de potencia, el cruce por cero funciona correctamente, pero solo me falta eso, y hablando del control de PID lo tengo considerado en este proyecto

si alguien ya lo ha realizado o ha controlado el pwm mediante teclado, estaria bien que diera una idea para orientarme

Title: Re: control de RPM con teclado matricial
Post by: surbyte on Nov 29, 2015, 04:40 am
Mi respuesta en el post#3 tiene un ejemplo pid