Go Down

Topic: Programa para contar las pulsaciones de un encoder (Read 268 times) previous topic - next topic

e_z_2000

Jul 05, 2018, 08:12 pm Last Edit: Jul 06, 2018, 11:34 pm by surbyte Reason: Agregado de etiquetas de código y errores.
Hola! Estoy haciendo un programa para contar las pulsaciones de un encoder rotacional tanto al incrementar como al decrementar. La cosa es que a dar el giro completo al encoder en el monitor se refleja 400 (si sigo rotando ese valor va subiendo indefinidamente por lo que no puedo usar la función map). ¿Cómo puedo hacer para que al dar al giro completo, quede en un rango de 0 a 100?. De antemano muchas gracias! Dejo el código que estoy utilizando:
Code: [Select]

#include <Encoder.h>


Encoder myEnc(2, 3);


void setup() {
Serial.begin(9600);
Serial.println("Basic Encoder Test:");
}

long oldPosition  = -999;

void loop() {
long newPosition = myEnc.read();
if (newPosition != oldPosition) {
  oldPosition = newPosition;
  Serial.println(newPosition);
}
}

surbyte

Tienes que hacerlo porque existen librerías de enconders
Ademas si usas un enconder debes ver flancos ya que tienes dos señales A y B defasadas entre si y de su defasajes determinas si esta girando en sentido horario o anti horario.

Busca Arduino encoder y tendras las diferentes opciones.

PeterKantTropus

Depende del tipo de encoder estés utilizando podrás hacerlo simple o no. Los encoder suelen tener tres canales : A,B y Z este último es un pulso que indica un giro completo y con el cual deberás resetear a cero el contador
"Si no entra como tornillo, entra como clavo"

Daniel_Arg

Te dejo un código que yo uso para mis proyectos pero tienes que usar la librería RotaryEncoder.h


Para probar el código los pines CKL y DT los conectas a A0 y A1
El pin SW que es el pulsador lo conectas a A2
Por supuesto también conectas + y GND.

Observa que llamo a la función LeeEncoder con cuatro parámetros por ejemplo
LeeEncoder(0,255,5,1); donde (0) es el mínimo, (255) el máximo, (5) los saltos, o sea que cuenta de cinco en cinco y por último (1) que puede valer uno o cero. Si vale (1) la función le pone tope al giro del encoder una vez alcanzado el mínimo o el máximo, y si vale (0)  la función no le pone tope, con lo cual si estas ajustando el mes en una fecha como en el siguiente código, una vez llegado a Diciembre el próximo paso salta a Enero.


Otra cosa que no debes olvidar es que si vas a dar saltos, como por ejemplo en LeeEncoder(0,255,5,1); donde se fija la potencia de un led, debes prestar atención que antes se fija el puntero del encoder de la siguiente forma encoder.setPosition(pwmled/5);

Buena suerte!


Code: [Select]


#include <RotaryEncoder.h>

// Variables
volatile byte enc_but;
int lastPos = 0;
int newPos = 0;
int yy = 2018;
byte mm = 1;
byte dd = 1;

byte pwmled  = 0;

String NombreMeses[13] = {"","Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre","Diciembre"};
#define enc_a  A0
#define enc_b  A1
#define enc_c  A2

RotaryEncoder encoder(A1,A0);
 
void setup() {
   pinMode(enc_a,INPUT_PULLUP); pinMode(enc_b,INPUT_PULLUP); pinMode(enc_c,INPUT_PULLUP);
   Serial.begin(9600);
   
  }   

 
void loop() {
 read_but();
 if(enc_but==1) {
  enc_but=0;
  SetupTime();
 }
}


void read_but()
{
  bool pin_status;
  delay(1);
  pin_status=digitalRead(enc_c);
  if(pin_status == LOW && enc_but !=128) {enc_but = 128;}
  if(pin_status == HIGH && enc_but ==128){enc_but=1; }
}


void LeeEncoder(int RotaryMin, int RotaryMax, int RotarySteps, int RotaryTop ) {

 encoder.tick();
 newPos = encoder.getPosition() * RotarySteps;
 
if (RotaryTop == 1) {
  if (newPos < RotaryMin) {
    encoder.setPosition(RotaryMin / RotarySteps);
    newPos = RotaryMin;

  }
  if (newPos > RotaryMax) {
    encoder.setPosition(RotaryMax / RotarySteps);
    newPos = RotaryMax;
  }
}
      if (RotaryTop == 0) {
      if (newPos < RotaryMin) {
      encoder.setPosition(RotaryMax / RotarySteps);
      newPos = RotaryMax;
     }
      if (newPos > RotaryMax) {
      encoder.setPosition(RotaryMin / RotarySteps);
      newPos = RotaryMin;
     }
   }
}

void SetupTime() {

    Serial.println("Ajuste Año, Día, Mes y Potencia");
    encoder.setPosition(yy);;
    delay(50);
   
      while(enc_but!=1) {
      LeeEncoder(2017,2030,1,1);
      if (lastPos != newPos){
        lastPos = newPos ; yy = newPos ;
        Serial.print("Año: "); Serial.println(yy);
        }
      read_but();
      }
    enc_but=0;
    encoder.setPosition(mm);
    delay(50);
     
      while(enc_but!=1) {
      LeeEncoder(1,12,1,0);
      if (lastPos != newPos){
        lastPos = newPos ; mm = newPos ;
        Serial.print("Mes: "); Serial.println(NombreMeses[mm]);
        }       
      read_but();
      }
    enc_but=0;
    encoder.setPosition(dd);
    delay(50);
   
      while(enc_but!=1)  {
      LeeEncoder(1,31,1,0);
      if (lastPos != newPos){
        lastPos = newPos ; dd = newPos ;
        Serial.print("Dia: "); Serial.println(dd);
      }
      read_but();
      }
      enc_but=0;

     
    encoder.setPosition(pwmled/5);
    delay(50);
   
      while(enc_but!=1)  {
      LeeEncoder(0,255,5,1);
      if (lastPos != newPos){
        lastPos = newPos ; pwmled = newPos ;
        Serial.print("Led: "); Serial.print(pwmled); Serial.print(" - "); Serial.print(map(pwmled,0,255,0,100));
        Serial.println("%");
      }
      read_but();
      }
      enc_but=0;

 
    Serial.println("---------------");
    Serial.print("Fecha: ");  Serial.print(dd); Serial.print("/");
    Serial.print(NombreMeses[mm]);Serial.print("/");Serial.println(yy);
    Serial.print("Potencia led: "); Serial.print(pwmled);
    Serial.print(" - "); Serial.print(map(pwmled,0,255,0,100)); Serial.println("%");
    Serial.println("---------------");

 
}

Go Up