Cuenta más o menos pulsos depende de la velocidad de giro

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!

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();
 //   }
 // }
//}/*

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

@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!

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.

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.

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

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.

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.

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!

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++

Hola a todos.

bueno, creo que ya esta solucionado.

PeterKantTropus tenias razón , no se puede usar millis en la interrupción , por lo visto micros si contabiliza.

encontre esta pagina que esta muy bien explicado Andromina robot V.2.0: Encoder y Arduino. Tutorial sobre el módulo sensor de velocidad IR con el comparador LM393 (Encoder FC-03)

Pongo mi sketch por si a alguien le pueda servir ( aunque seguro que es muuuuuuuy mejorable, sigo aprendiendo)

*alimentar arduino por VIN desde entrada 12v de L298n

*/

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
static volatile unsigned long debounce = 0; // Tiempo del rebote.


volatile  long contador = 0;

int centimetros = 0;

int IN3 = 12; //pin motor dc 12
int IN4 = 13; //pin motor dc 13
int ENB = 14; //pin para velocidad (pin 14 (A0)
const byte interruptPin = 3;



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


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  entradas arduino
  {'7', '8', '9', '-'},         //  1       2           3         4     11    10        9     8  salidas del teclado
  {'*', '0', '=', '+'}
};


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() {
  Serial.begin(9600);


  // pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);
  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);    //control de velocidad motor (pin 14 (A0)

  lcd.begin();
  lcd.setCursor(0, 0);
  lcd.print("BOBINADOR V.07"); //Prendido de pantalla
  delay (1000);
  lcd.clear();
}
void motorderecha()
{ 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() {

  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 == '/')) {    //giramos motor derecha
    motorderecha();
  }
  if ( key == 'x') {    //giramos motor izquierda
    motorizquierda();
  }


  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.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) 
  {

    final = true;
    lcd.clear();
  }


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

  {
    teclaigual++;
    //delay (50);


  }


  if (final == true )  
  {
    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:
        centimetros = contador * 0.64;
        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);
        //Serial.print(centimetros);


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


        }
        if ( ans <= centimetros)
        {

          motorparo();
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print ("Bobina hecha  ");
          lcd.setCursor(0, 1);
          lcd.print (ans);
          lcd.setCursor(10, 1);
          lcd.print ("Cm");
          delay(1000);

         /* 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() {
  if (  digitalRead (interruptPin) && (micros() - debounce > 500) && digitalRead (interruptPin) ) {
    // Vuelve a comprobar que el encoder envia una señal buena y luego comprueba que el tiempo es superior a 1000 microsegundos y vuelve a comprobar que la señal es correcta.
    debounce = micros(); // Almacena el tiempo para comprobar que no contamos el rebote que hay en la señal.
    contador++;
  }  // Suma el pulso bueno que entra.
  else ;
}

Muchísimas gracias @Tauro0221, @surbyte, PeterKantTropus por la ayuda!!

un saludo

Que es una interrupción? Una rutina de rapida acción.
En una rutina de rápida acción algo que llegue al nivel del watchog hace que tu Arduino se resetee.
Por eso millis() no tiene sentido y por eso no puedes usar Serial.print ni cosas asi.
Pero por ejemplo si podrias usar millis() en una interrupción para contar eventos que tienen esa duración. Se comprende.
Tu en cambio pretendías generar una demora y eso si no tiene sentido.