Aplicaciones con pulsadores y potenciometros

PULSADOR CON “n” INSTRUCCIONES

METODO DE MULTIPLES VARIABLES;

Si queremos conseguir “n” instrucciónes diferentes con cada pulsación tendremos que declarar n variables booleanas o enteras y programar como en este ejemplo de cinco variables. Tomaremos el pin digital d6 que esta conectado al pulsador sin necesidad de conectarle una resistencia en pull_up ya que lo haremos por software en el void setup().

#define pOne 6
#define one_switch (!digitalRead(pOne))
int a=0,b=0,c=0,d=0;

void setup(){
pinMode(pOne,INPUT_PULLUP);

}


void loop(){
//cuando pulsemos,el pin 6 pasara de nivel H(digitalRead(6)) a nivel L (!digitalRead(6))



if (one_switch&&a==0){
b=1; //se prepara para el proximo pulso
//instrucción 1 que se ejecutara una sola vez
delay(250); //es importante meter un retraso para que la pulsación no sea brusca
a=1; //se deshace este primer pulso
}



if (one_switch&&b==1){
c=1;
//instrucción 2
delay(250);
b=0;
}



if (one_switch&&c==1){
d=1;
//instrucción 3
delay(250);
c=0;
}



if (one_switch&&d==1){
e=1;
//instrucción 4
delay(250);
d=0;
}




if (one_switch&&e==1){
a=0;//fin del bucle poniendo la variable a=0 para que vuelva a empezar de nuevo la siguiente pulsación
//con la instrucción 1
//instrucción 5
delay(250);
e=0;
}


EJEMPLO PULSADOR CON TRES INSTRUCCIONES UTILIZANDO DOS PULSOS CORTOS Y EL TERCERO LARGO;

Ahora vamos a definir variables booleanas a y b, y el estado inicial se anunciará en void setup(). Fijarse que solo he puesto un delay en la instrucción 1 y ninguno en las restantes. En la primera pulsación la variable “a” cambiará de estado y prepara a la siguiente pulsación poniendo b=0, pero si en vez de un pulso corto dejamos presionado el botón,puenteara la segunda instrucción ejecutando la tercera.

bool a;
bool b;

void setup(){
a=1;
b=1;


pinMode(6,INPUT_PULLUP);


}



void loop(){

 if (!digitalRead(6)&&a==1){
      //instrucción 1
  delay(250); 
a=0;
                               
  }

    if (a==0&&!digitalRead(6)){
      b=0;    

//instrucción 2

     } 


  if (b==0&&!digitalRead(6)){

     b=1;
     a=1;

//instrucción 3
}
}


Potenciometro actuando como conmutador rotatorio:

Este metodo sencillo nos va dar muchas satisfacciones;

Una vez conectado el potenciometro a una entrada analógica, solo hay que hacer un mapeo de una variable “w” dada de forma que:

#define InputX (analogRead(A0))

w=map(InputX,0,1023,1,5)

if (w==1){z

intrucción 1 }

………………………………

Lo que hacemos es dividir el recorrido del potenciometro en cinco partes iguales y “w” ira tomando valores ascendentes o descendentes entre 1 a 5 mientras giramos el pot.

Metodo sencillo: dos pulsadores ,la acción de uno es deshecha por el otro.

Disponemos de dos pulsadores,pOne y pTwo conectados al pin 32 y pin 15 .

Al pulsar pOne o pTwo, pondremos a nivel L el pin,lo que equivale a ” !digitalRead(pOne)”, entonces definimos one_switch y two_switch.

Con “Serial.println(w);” vamos a ir viendo como progresa la numeración del 1 al 3 o viceversa. Con las restricciones ” if (w<0){w=1;} if (w>3){w=3;}”, mantendremos el bucle de pulsaciones


#define pOne 32
#define pTwo 15
#define one_switch (!digitalRead(pOne))
#define two_switch (!digitalRead(pTwo))
int w;
............................. 
 if (w<0){w=1;}
if (w>3){w=3;}
if one_switch){delay(250);w--;
switch (w){
case 1:

Serial.println(w);
 break;

case 2:
Serial.println(w);

break;

case 3:
Serial.println(w);
 
break;

 }}
  if (two_switch){delay(250);w++;
  switch (w){
case 1:

Serial.println(w);
break;

case 2:

Serial.println(w);
break;

case 3:

Serial.println(w);
break;

 }}
  
}

EFECTUAR UNA TAREA EN UN TIEMPO DETERMINADO:

Suponemos un pulsador en pullup por software de forma que en reposo esta a nivel alto y al pulsar pasa a nivel bajo. declaramos la variable boton=digitalRead(pin); y para que no empiece a ejecutarse la tarea nada mas dar alimentación a la placa, declaramos una variable de inicio ini=0 de forma que con la condicion establecida en el void loop()



if (ini==0){
 t1=millis();
   } 

nos aseguramos que t1 sea igual a millis(), y la diff sera cero.

Cuando pulsemos el botón,lo primero es hacer ini=1, deshaciendo la condición inicial y estableciendo la del botón de forma que en su cambio de H-L-H, t1 dejara de ser igual a millis() y comenzará el contador ejecuntandose en el tiempo establecido la tarea requerida. AL finalizar la restricción,finalizara la tarea.



 if (diff>=1&&diff<=20){
//tarea requerida
}

long t1;
long diff;
#define pin 10
int boton=digitalRead(pin);
int ini=0;

void setup(){
pinMode(pin,INPUT_PULLUP);
}
void loop(){
  diff=(millis()-t1)/1000;
if (ini==0){
 t1=millis();
   } 
if (!boton){
  ini=1;
}
     if (diff>=1&&diff<=20){
//tarea requerida
}

}

ENTRADA ANALOGICA DIVIDIDA

En este sketch,seguimos utilizando la tira de 14 leds para aprender a dividir una entrada analógica en dos partes iguales de forma que en su punto medio este apagada y girando a la izquierda se enciendan los leds desde el 7 al 0 y moviendo a la derecha se encienda del 7 al 14.

Declaramos la variable entera “val” como entrada analogica A0 y en función del dispositivo que utilicemos tendra una resolución de 1023 para un arduíno nano ,que es el que estoy utilizando, o 4095 para una entrada analógica en el Esp32.

Declararemos dos nuevas variables “valI” y “valD” yla mapearemos de esta forma:



int val=analogRead(0);
  int valI=map(val,512,0,0,450);
  int valD=map(val,512,1023,550,1023);

sketch completo


  #include <Adafruit_NeoPixel.h>

#define PIN        13 
#define numleds 14 
#define  pin_advance 6
#define   pin_back 8

Adafruit_NeoPixel pixels(numleds, PIN, NEO_GRB + NEO_KHZ800);

int i;
int t=1000;

void setup() {
 
pixels.begin();
 pixels.clear();
 pixels.show(); 
}

void loop() {
  int val=analogRead(0);
  int valI=map(val,512,0,0,450);
  int valD=map(val,512,1023,550,1023);


  
  
  if (valI>=25&&v1==0){
    i=6;
     pixels.clear();
     pixels.show();
     while (i<=6&&i>=0){
      
      
      pixels.setPixelColor(i, pixels.Color(25, 0,0));
    pixels.show(); 
    delay(t/7);
    i--;
   
     }
   
  
  }


  if (valD>=575){
     i=6;
     pixels.clear();
  while (i>=6&&i<=13){
   
    
      pixels.setPixelColor(i, pixels.Color(25, 0,0));
    pixels.show(); 
    delay(t/7);
      i++;
     }
  }
if (val>=450&&val<=550){
   pixels.clear();
   pixels.show(); 
   v1=0;
   
}

}
  

  
  
  if (valI>=25&&v1==0){
    i=6;
     pixels.clear();
     pixels.show();
     while (i<=6&&i>=0){
      
      
      pixels.setPixelColor(i, pixels.Color(25, 0,0));
    pixels.show(); 
    delay(t/7);
    i--;
   
     }
   
  
  }


  if (valD>=575){
     i=6;
     pixels.clear();
  while (i>=6&&i<=13){
   
    
      pixels.setPixelColor(i, pixels.Color(25, 0,0));
    pixels.show(); 
    delay(t/7);
      i++;
     }
  }
if (val>=450&&val<=550){
   pixels.clear();
   pixels.show(); 
   v1=0;
   
}

}
  

He expresado un delay “t/7” con t=1000 para que el tiempo de encendido desde 7 a 1 y desde 7 a 14 sea de 1 segundo.

Con una entrada analógica entre 450 y 550 se apagarán los leds y coincidirá con el centro del recorrido del potenciometro ya que esta conectado alpin de 5V del arduíno.

Tengo que comentar que este ejemplo no es el mas adecuado para que la aplicación sea práctica, por eso habría que trasladarla al empleo de un motor que giraria en un sentido u otro teniendo el centro del potenciometro como reposo:

void Motor(){
  int freq1;
  int freq2;
  int freq=analogRead(36);
  freq1=map(freq,2200,4095,0,2300);
  
 freq2=map(freq,1800,0,0,2300);
 
 if (freq>2100&&(freq1/53)>1) {
    digitalWrite(pin_dir,LOW);
     digitalWrite(pin_ena, LOW);
        ledcSetup(stepChannel,freq1, resolution);
    ledcWrite(stepChannel, dutyCycle);
         delay(250);  
    
 }
 if (freq<1900&&(freq2/53)>1) {
   digitalWrite(pin_dir,HIGH);
     digitalWrite(pin_ena, LOW);
        ledcSetup(stepChannel,freq2, resolution);
    ledcWrite(stepChannel, dutyCycle);
    delay(250);
   
  
 } 
 if (freq>1800&&freq<2200){
    d=1;
   

  digitalWrite(pin_ena, HIGH);
 }
  
}

Variables y Potenciometros: Finalizar una instrucción

Sabemos que el uso del potenciometro al contrario que los pulsadores acarrean un pequeño problema; que es que permanentemente envían la información de su posición a la entrada analógica conectada. Podemos utilizar variables booleanas para indicarle con su cambio cuando queremos que finalice la instrucción encomendada. En este ejemplo con nuestra “Strip led” vamos a iluminar los elementos desde el centro hacia arriba y hacia abajo finalizando la instrucción una vez se ilumine el led 0 o el ultimo. Esta vez he utilizado una tira de 144 leds.

#include <Adafruit_NeoPixel.h>

#define PIN        13 
#define numleds 144 


Adafruit_NeoPixel pixels(numleds, PIN, NEO_GRB + NEO_KHZ800);
bool v1=0;
bool v2=0;
int i;



void setup() {
   Serial.begin(9600);
 
pixels.begin();
 pixels.clear();
 pixels.show(); 
}

void loop() {
 
  int val=analogRead(0);
 Serial.println(val); 

//No he necesitado mapear la entrada analógica, puesto que uso un arduíno nano y los valores iran de 0-1023
if (val<450&&v1==0){//uso de la variable booleana v1
     i=70;
     pixels.clear();
  while (i<=70&&i>=0){
   
    
      pixels.setPixelColor(i, pixels.Color(25, 0,0));
    pixels.show(); 
    delay(25);
      i--;
     }
     v2=0;//preparo la instrucción siguiente
     v1=1;//paro esta instrucción
  }
  
  


  if (val>550&&v2==0){
     i=70;
     pixels.clear();
  while (i>=70&&i<=143){
   
    
      pixels.setPixelColor(i, pixels.Color(25, 0,0));
    pixels.show(); 
    delay(25);
      i++;
     }
     v2=1;
     v1=0;
  }
if (val>=450&&val<=550){
   pixels.clear();
   pixels.show(); 
   v1=0;
v2=0;
   
}

}
  

En el siguiente ejemplo y siguiendo jugando con las variables vamos a hacer que el recorrido de iluminación se pare ante un cierto valor de “i”. Mucho cuidado,como tenemos un bucle “while” dentro de una condicional, la variable hay que incluirla en el bucle interno:

#include <Adafruit_NeoPixel.h>

#define PIN        13 
#define numleds 144 


Adafruit_NeoPixel pixels(numleds, PIN, NEO_GRB + NEO_KHZ800);
bool v1=0;
bool v2=0;
int i;



void setup() {
   Serial.begin(9600);
 
pixels.begin();
 pixels.clear();
 pixels.show(); 
}

void loop() {
 
  int val=analogRead(0);
 Serial.println(val); 
if (val<450&&v1==0){
     i=70;
     pixels.clear();
  while (i<=70&&i>=0&&v1==0){
   
    
      pixels.setPixelColor(i, pixels.Color(25, 0,0));
    pixels.show(); 
    delay(25);
      i--;
      if (i==40){
        v1=1;
       
             }
     }
     v2=0;
     v1=1;
  }
  
  


  if (val>550&&v2==0){
     i=70;
     pixels.clear();
     
  while (i>=70&&i<=143&&v2==0){
   
    
      pixels.setPixelColor(i, pixels.Color(25, 0,0));
    pixels.show(); 
    delay(25);
      i++;
      if (i==100){
        v2=1;
       
             }
     }
//v2=1;
     v1=0;
  }
if (val>=450&&val<=550){
   pixels.clear();
   pixels.show(); 
   v1=0;
v2=0;
   
}

}
 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Translate »