Go Down

Topic: Cuenta más o menos pulsos depende de la velocidad de giro (Read 1 time) previous topic - next topic

davidrummer

No hace falta declarar una entrada como entrada para que luego trabaje como interrupción.

Entradas son entradas e interrupciones son las que dispone el Arduino en uso tal como dice @PeterKanTropus.

INT0 es pin 2
INT1 es pin 3.

Esta línea puede mejorarse aunque sea correcta, debes simplificar operaciones, porque toda matemática es lenta. 
Code: [Select]
centimetros = contador / 20 * 6.5;

6.5/20 = 0.325 entonces

Code: [Select]
centimetros = contador * 0.325;

hará lo mismo de modo mas rápido.



Bueno, ahora que revisé todo tu código en su contexto me pregunto para que usas interrupciones? No creo que una rueda gire tan rápido como para no leer cambios.
Pero... debes probarlo, asi que te voy a sugerir un código que no usa interrupciones pero si mira los cambios en un pin y lo presenta en el LCD.

Prueba a ver, es el mismo pin okay?

Code: [Select]
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);

const byte ruedaPin = 3;
long contador = 0;
int centimetros = 0;
bool status, statusAnt = false;

void setup() {
  // pinMode(ledPin, OUTPUT);
  pinMode(ruedaPin, INPUT_PULLUP);
  lcd.begin();
  Serial.begin(9600);
}

void loop() {
 
  status = digitalRead(ruedaPin):
 
  if (status && !statusAnt) {
      contador++; 
      centimetros = contador 0.325;
      // lcd.clear();
      lcd.setCursor(5, 0);
      lcd.print (centimetros);
  }
  statusAnt = status;
}


Hola surbyte.
Pues uso las interrupciones  porque las vi en algún proyecto que usaba ruedas dentadas para medir distancias, y di por hecho que tenia que ser así. pero probando tu código, va mil veces mejor!!  sin ningún desfase. Voy a intentar entenderlo y si no te importa lo implementare a mi programa.

He calculado que mas o menos  el sensor de óptico de la rueda le de a arduino unos 400 pulsos por segundo.

También simplificare las operaciones matemáticas todo lo que pueda a partir de ahora.

Muchas gracias por tu ayuda!!!



tauro0221

Hi,
Pregunta que voltaje tiene el sensor cuando hay luz y cuando no hay. Si no hay luz esta +5 voltios y cuando tiene luz lee zero voltios. Para mi creo que las aberturas son muy grandes y esto te crea  problemas en los pulsos. Deberia tratar de ponerlas que te de un pulso pequeno.

davidrummer


hola tauro.

o ya no se que pensar! creia que a muescas mas separadas peor definición tenia, pero mas fiabilidad. voy a intentar hacer una con maor numero de dientes.

muchas gracias otra vez!!
 

tauro0221

Hi,
Creo que el problema es de las aberturas son muy grandes y esto hace que puede causar  recibir luz externa a la senal  infraroja del sensor. Por eso es de hacerlas lo mas pequena posible para prevenir interferencia externa. Yo tuve problemas cuando trate de leer las revolucines de un plato de tocar discos. Tuve que pintar la parte de abajo con pintura sin brillo y pude resolver el problema. Si sigues con el problema podrias tratar el hall effect sensor con un megneto y asi eliminas cualquier interferrencia externa. Cada que que el magneto pasa por el sensor este te da un pulso que puedes usarlo para que trigue el interupt. Sigue tratando hasta que puedas resolver el problema con el sensor que tienes.

surbyte

A ver tauro mi código funcionó sin problemas con las aberturas como estan. Entonces no hay problema con la abertura sino con el código que usa interrupciones, no te parece?

Habrá que enfocarse en el código anterior y modificarlo para que trabaje correctamente.
No hay rebotes, mi código no implementa rebotes, solo cuento flancos.

davidrummer

hola @surbyte.

Tu programa por si solo va genial como te dije , pero implementándolo al que tenia yo ( lo hice por partes de otros ejemplo y proyectos de gente, estoy intentando aprender) pues no va, incluso va peor( cuenta un centímetro por cada 10 o 15 si giro la rueda rápido y uno por cada 3 o 4 si lo giro lento, por ejemplo) intentare volver a hacerlo otra vez de 0.

pongo Mi desastre de programa entero. acepto ayuda y collejas también!

Code: [Select]
const byte interruptPin = 3;
long contador = 0;
//long T0 = 0; // variable anti rebote
bool status, statusAnt = false;
//boolean contador1 = 0;
const byte ruedaPin = 3;
int centimetros = 0;

int IN3 = 12; //pin motor dc 12
int IN4 = 13; //pin motor dc 13
int ENB = 14; //pin para velocidad


// La librería para el LCD 16x2 I2C
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x3F, 16, 2);

//#include <LiquidCrystal.h> // Librería para el control del LCD
#include <Keypad.h> // Librería para el control del keypad

//LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // varible LCD y pines
const byte filas = 4; // número de filas '4'
const byte columnas = 4; // número de columans '4'

char teclado [filas][columnas] = {
  {'1', '2', '3', '/'},         // verde - amarillo - naranja - rojo- gris- blanco - negro -violeta
  {'4', '5', '6', 'x'},         //  11      10          9         8     7     6         5     4
  {'7', '8', '9', '-'},
  {'*', '0', '=', '+'}
}; //variable teclado

byte filaPines[filas] = {11, 10, 9, 8}; //configuración de filas
byte columnaPines[columnas] = {4, 5, 6, 7}; // configuración de columnas

Keypad calcu = Keypad (makeKeymap(teclado), filaPines, columnaPines, filas, columnas);

boolean inicio = false;
boolean final = false; // variables de control
boolean iniciomotor = false;

boolean introducecm = true;


String num1 ; //numero que ingresamos con el teclado
long int ans; // para convertir el numero en cifra computable

int teclaigual = 0; //contador de la tecla igual. para confirmar el arranque motor



void setup() {
  // pinMode(ledPin, OUTPUT);
 // pinMode(interruptPin, INPUT_PULLUP);
 // attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);
 
   pinMode(ruedaPin, INPUT_PULLUP);
  lcd.begin();
  //Serial.begin(9600);
  pinMode(2, INPUT);

  pinMode (IN4, OUTPUT);    // Input4 conectada al pin 10
  pinMode (IN3, OUTPUT);    // Input3 conectada al pin 11
  pinMode (ENB, OUTPUT);

  lcd.begin();
  lcd.setCursor(0, 0);
  lcd.print("BOBINADOR V.07"); //Prendido de pantalla
  delay (1000);
  lcd.clear();

}

void motorderecha() //gira motor derecha , poner () para usar
{ digitalWrite (IN4, HIGH);
  digitalWrite (IN3, LOW);
  analogWrite(ENB, 255);
}
void motorizquierda()
{ digitalWrite (IN4, LOW);
  digitalWrite (IN3, HIGH);
 analogWrite(ENB, 255);
}
void motorparo()
{ digitalWrite (IN4, LOW);
  digitalWrite (IN3, LOW);
}

void loop() {
  /*centimetros = contador / 20 * 6.5; (((contador * 0.107 * 3.141592) * (19.01 / 2) / 10));*/

 status = digitalRead(ruedaPin);
 
  if (status && !statusAnt) {
      contador++; 
      centimetros = contador*0.325;
       lcd.clear();
      lcd.setCursor(5, 0);
      lcd.print (centimetros);
  }
  statusAnt = status;

  //centimetros = (((contador * 0.107 * 3.141592) * (19.005/ 2) / 10)); //0,107 sale de 360 grado/20 radianes por 2*pi -- todo eso por pi y por la mitad del radio de encoder COMPROBAR


 
  if (introducecm == true&&inicio==false &&final==false &&iniciomotor==false) // sale el texto introdice centimetros , solo si final, inicio e inicio motor estan en false
  {
    lcd.setCursor(0, 0);
    lcd.print ("Introduce Cm    ");
  }

  char key = calcu.getKey();

  if (key != NO_KEY && (key == '1' || key == '2' || key == '3' || key == '4' || key == '5' || key == '6' || key == '7' || key == '8' || key == '9' || key == '0'))
  {


    //lcd.clear();
    if (inicio == false)
    { num1 = num1 + key;         //ingresa numero en la pantalla y se mueve el cursor segun lo introducimos
      int numLength = num1.length();
      lcd.setCursor(13 - numLength, 1);
      lcd.print(num1 );


      lcd.setCursor(14, 1);
      lcd.print ("Cm");

    }


  }

  if (teclaigual == 1) //primera pulsacion de teclaigual
  {
    //lcd.clear();  //limpiamos lcd

    lcd.setCursor(0, 0);    //colocamos cusos
    lcd.print("Confirma Medida ");      //escribimos  aviso
    inicio = true;                    //ponemos inicio en true para no dejar introducir mas datos con el teclado

    delay(50);
   
  }

  if  (teclaigual == 2) //(teclaigual==2&&iniciomotor==false)
  {

    final = true;
    lcd.clear();
  }


  if ((inicio == false || true/*&& iniciomotor==false*/) && key != NO_KEY && ( key == '=')) //  si tecla igual primera vez te pide que confirmes

  {
    teclaigual++;
    delay (50);
   

  }


  if (final == true )  //pulsa = para que salgan los resultados
  {
    iniciomotor = true;

    ans = num1.toInt() ;

    // lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Confirmado");
    delay(3000);
    contador = 0;
    teclaigual = 0;
    final = false;
    lcd.clear();
   
  }
  if ( key != NO_KEY && key == '*')  //si se pulsa asterisco se borra todo (PROBAR a poner final = false para volver al principio
  {
   

    inicio = false;
    final = false;
    iniciomotor = false;
    num1 = "";   
    ans = 0;   
    teclaigual = 0;
    contador = 0;
    motorparo();
    lcd.clear();


  }

  if (iniciomotor == true)
   
  {

    switch (digitalRead(2)) {
      case 1:
       
        lcd.setCursor(0, 0);
        lcd.print ("cm hechos");
        lcd.setCursor(11, 0);
        lcd.print (centimetros);
        lcd.setCursor(0, 1);
        lcd.print ("cm hacer");
        lcd.setCursor(10, 1);
        lcd.print (ans);
        delay(50);

        if ( centimetros < ans)
        {
          motorizquierda();
          lcd.setCursor(8, 0);
         

        }
        if ( ans <= centimetros)
        {
         
          motorparo();
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print ("Bobina hecha    ");
          delay(4000);

          lcd.clear();
          // lcd.setCursor(15,0);
          inicio = false;
          final = false;
          iniciomotor = false;
          num1 = "";
          //num2 = "";
          ans = 0;
          //op = ' ';
          teclaigual = 0;
          contador = 0;

        }
        break;

      case 0:
        {
          //lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print ("no cinta        ");
          lcd.setCursor(0, 1);
          lcd.print ("                ");
        }
        //motorderecha();
        // delay(100);
        motorparo();
        break;
    }


  }

}

//void blink() {
//  //state = !state;
  //contador++;
 // {
 //   if ( millis() > T0  + 2)   //60 es el tiempo en millis antes 250
  //  { contador++ ;
  //    T0 = millis();
 //   }
 // }
//}/*

surbyte

Tu programa tiene muchos delay(), no puedes tener delay() ya te lo habia dicho.

davidrummer

#22
Feb 26, 2019, 12:56 am Last Edit: Feb 26, 2019, 12:58 am by davidrummer
@surbyte, yo pensaba que al no estar en la parte en la que cuenta los pulsos no importaba. Mañana sin falta vuelvo a montar el cacharro y a quitar los delay() a ver que tal va.

Muchas gracias!

davidrummer

hola @tauro0221

Pues si no consigo que funcione con lo que tengo seria una opción a mirar lo del sensor hall. Lo raro es que con el programa de surbyte si sale bien.

davidrummer

Hola surbyte .

Quite todos los delay() que tenia en el programa (la mayoría no se por que los había puesto) y sigue más o menos igual. voy a intentar hacerlo de cero con tu ejemplo, a ver si logro hacer algo mas decente ordenado, y sobre todo que funcione.

Iré poniendo los progresos por aquí, por si le puede ayudar a alguien que este en las mismas.

surbyte

Luego miro tu código con interrupciones a ver que puede tener de errado.

tauro0221

Hi,
No cambies el sensor a menos que no reduzcas la abertura de la rueda. Creo que esas aberturas son muy grandes y para generar un interrupt no necesitas tener esas aberturas.

PeterKantTropus

Estas utilizando millis( ) dentro de la función de interrupción, por eso no funciona. No funcionará nada que utilice timers u otra interrupción.
"Si no entra como tornillo, entra como clavo"

davidrummer

Muchas gracias @surbyte!


@tauro0221 puede ser, pero si el programa de surbyte funciona con esas aberturas, cuando no funciona es cuando yo incluyo algo mas en el loop().

PeterKantTropus@, te entiendo, ese lapso de tiempo es suficiente como para que si giro rápido la rueda me deje de contar algún pulso, o me imagino que sera algo parecido.



yo ya no doy mas de si, ya no se que hacer!


Muchas gracias chicos!

PeterKantTropus

La función millis que tienes dentro de la función que llama la interrupción( blink)  no funciona, no se incrementa su valor. No puedes poner millis dentro de esa función. Deja solo en la función blink la sentencia contador++
"Si no entra como tornillo, entra como clavo"

Go Up