desktop

Encender y apagar un Led con el mismo botón

Hola:

Uso Arduino UNO con el LCD. Quiero apagar y encender el Led 13. No se usa el botón o pulsador digital, sno el analógico A0 que incluye en el LCD KeyPad Shield. En el cual, no se programa de la misma forma el analógico que el digital.

Por ahora me funciona lo básico.

C:
#include <LiquidCrystal.h>

// Seleccionado los pines del LCD.
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Definir algunos valores utilizados por el LCD y los botones.
int teclaLCD = 0;
int teclaEntradaADC = 0;
#define botonDERECHO 0
#define botonARRIBA 1
#define botonABAJO 2
#define botonIZQUIERDA 3
#define botonSELECT 4
#define botonNADA 5
#define pinLed10 10 // Luz de fondo.
#define pinLed13 13   // Declaramos la variable pin del Led.
char caracter;
String comando;
int teclaAnt = 0;

// Leer todos los botones.
int leer_botones_del_LCD() {
  teclaEntradaADC = analogRead(A0); //Leer el valor desde el sensor.
  // Los botones cuando se leen están centrados en estos valores: 0, 144, 329, 504, 741.
  // Agregamos aproximadamente 50 a esos valores y verificamos si estamos cerca.

  // Hacemos de esta la primera opción por razones de velocidad,
  // ya que será el resultado más probable.
  if (teclaEntradaADC > 1000) return botonNADA;
  // Para V1.1 nosotros este umbral.
  /*
    if (teclaEntradaADC < 50)   return botonDERECHO;
    if (teclaEntradaADC < 250)  return botonARRIBA;
    if (teclaEntradaADC < 450)  return botonABAJO;
    if (teclaEntradaADC < 650)  return botonIZQUIERDA;
    if (teclaEntradaADC < 850)  return botonSELECT;
  */
  // Para V1.0, comente el otro umbral y use el siguiente:

  if (teclaEntradaADC < 50)   return botonDERECHO;
  if (teclaEntradaADC < 195)  return botonARRIBA;
  if (teclaEntradaADC < 380)  return botonABAJO;
  if (teclaEntradaADC < 555)  return botonIZQUIERDA;
  if (teclaEntradaADC < 790)  return botonSELECT;

  return botonNADA;  // Cuando todos los demás fallan, devuelve esto ...
}
void setup()
{
  pinMode(pinLed13, OUTPUT);
  pinMode(pinLed10, OUTPUT);
  digitalWrite(pinLed10, HIGH); // Dejar encendido luz de fondo.
  lcd.begin(16, 2); // LCD de 16x2.
  lcd.setCursor(0, 0);
  lcd.print(F("Arduino 2020"));
  Serial.begin(115200);
}

void loop()
{
  /* Voy leyendo carácter a carácter lo que se recibe por el canal
    serie (mientras llegue algún dato allí), y los voy concatenando
    uno tras otro en una cadena. En la práctica, si usamos el
    "Serial monitor" el bucle while acabará cuando pulsemos Enter.
    El delay es conveniente para no saturar el canal serie y que la
    concatenación se haga de forma ordenada.
  */
  while (Serial.available() > 0)
  {
    caracter = Serial.read();
    comando.concat(caracter);
    delay(10);
  }
  /* Unavez ya tengo la cadena "acabada", compruebo su valor y hago
     que la placa Arduino reaccione según sea este. Aquí podríamos
     hacer lo que quiesiéramos: si el comando es "tal", enciende
     un Led, si es cual, mueve un motor... y así.
  */
  if (comando.equals(F("Led_13_ON")) == true)  // Led_ON.
  {
    digitalWrite(pinLed13, HIGH); // Enciende el Led.
    lcd.setCursor(0, 1);
    lcd.print(F("Led 13: ON "));
    Serial.println(F("Led 13 encendido."));
  }

  if (comando.equals(F("Led_13_OFF")) == true) // Led_OFF.
  {
    digitalWrite(pinLed13, LOW); // Apaga el Led.
    lcd.setCursor(0, 1);
    lcd.print(F("Led 13: OFF"));
    Serial.println(F("Led 13 apagado."));
  }

  if (comando.equals(F("Led_10_ON")) == true)  // Led_ON.
  {
    digitalWrite(pinLed10, HIGH); // Enciende el Led.
    lcd.setCursor(14, 1);
    lcd.print(F("F1"));
    Serial.println(F("Led 10 encendido."));
  }

  if (comando.equals(F("Led_10_OFF")) == true) // Led_OFF.
  {
    digitalWrite(pinLed10, LOW); // Apaga el Led.
    lcd.setCursor(14, 1);
    lcd.print(F("F0"));
    Serial.println(F("Led 10 apagado."));
  }
  // Limpiamos la cadena para volver a recibir el siguiente comando.
  comando = "";
 
  // Indicar posición.
  lcd.setCursor(0, 1);
  // Esperando lectura botones.
  teclaLCD = leer_botones_del_LCD();
  if (teclaLCD != teclaAnt) {
      // Dependiendo de qué botón se presionó, realizamos una acción.
      switch (teclaLCD) {
        case botonDERECHO:
          {
            lcd.print(F("Derecha  "));
            Serial.println(F("Derecha."));
            break;
          }
        case botonIZQUIERDA:
          {
            lcd.print(F("Izquierda"));
            Serial.println(F("Izquierda."));
            break;
          }
        case botonARRIBA:
          {
            lcd.print(F("Arriba   "));
            Serial.println(F("Arriba."));
            break;
          }
        case botonABAJO:
          {
            lcd.print(F("Abajo    "));
            Serial.println(F("Abajo."));
            break;
          }
        case botonSELECT:
          {
            lcd.print(F("SELECT   "));
            Serial.println(F("SELECT"));
            break;
          }
        case botonNADA:
          {
            //lcd.print(F("Nada     "));
            //Serial.println(F("Nada"));
            break;
          }
      }
  }
  teclaAnt = teclaLCD;
}

¿Alguna idea?

Saludos.
 
No entiendo bien la pregunta, pero...
Si quieres hacer un cambio de estado, simplemente con digitalWrite(pinLed13, !digitalRead(pinLed13)); haces el "toggle".

Otra cosa, como sugerencia, busca el uso de enum para los diferentes estados. Asi evitas definir cada estado aparte.
Un ejemplo

C:
typedef
  enum{
    Boton1,
    Boton2,
    Boton3
  }
Botones;

// Luego
Botones botonEstado = Boton1;
Asi, por ejemplo, "botonEstado" se inicia como "0", ya que es el primero que aparece en la enumeracion
 
En resumen:

Uso los botones del esta Shield del LCD.
Arduino_Shield8.png


Me funciona con el truco qu epusiste.
digitalWrite(pinLed13, !digitalRead(pinLed13));

Me he dado cuenta una cosa.
A veces el botón pulsa como unas dos veces si pulso ARRIBA. A veces también como que se pulsa SELECT y no lo he pulsado, solo arriba. Una locura.

Me he dado cuenta que con el pinLed10 no hace lo mismo que con el 13.
digitalWrite(pinLed10, !digitalRead(pinLed10));


Saludos.
 
Es raro que no te funcione con el pin 10, yo estoy haciendo una alarma para auto, y uso ese truco y no tengo problema con ningun pin.

Por lo que te sale como si pulsaras otro boton, es porque usa el ADC, y si el boton no hace buen contacto, se crea una resistencia que "confunde" al ADC. Ésto pasa comunmente en los equipos de musica que usan entradas analogica para los pulsadores.

Que se repida la pulsacion, puede ser por lo mismo de lo anterior, falla el pulsador. Quizas haciendo algun "antirebote" por software, pero es mas complejo en analogico que en digital.
 
Al final, mejor usar botones digitales para que se le quite la tontería a todo esto. Por ahora sigo con los analógicos porque es lo que incluye en la placa.
 
La unica ventaja que le veo es ahorrar pines, pero a cambio de la inexactitud cuando apenas empiezan a fallar los botones.

Siempre que se pueda, usa botones individuales o algun integrado que expanda los puertos.
 
Atrás
Arriba