2 botones y 1 led

Hola :slight_smile:
Quisiera pedir su ayuda.
Intento escribir el programa, que funcione de esta manera:
Si presiono el botón 1, el programa espera, hasta que será presionado el botón 2. Si es así, se enciende LED y se queda encendido.
Para apagarlo, hay que presionar el botón 2, el programa espera, hasta que será presionado el botón 1. Si es así, se apaga LED.

const int  buttonPin1 = 2; 
const int  ledPin = 13; 
const int  buttonPin2 = 4; 
int i = 0; 

void setup() 
{
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

}


void loop() 
{

  int pin1State = digitalRead(buttonPin1);
  int pin2State = digitalRead(buttonPin2);
  
  if (pin1State == LOW) 
  {
    i = i + 1;
  }

  if (pin2State == LOW) 
  {
    i = i + 1;
  }

  if (i == 2) 
  {
    digitalWrite(ledPin, HIGH);
  }

  delay(500);
  
  i = 0;  
}

Es la primera parte del programa, pero no funciona.
¿Podréis indicarme dónde hice error, por favor?
Saludos :wave:

Your code doesn't wait as you describe - the only way the LED will come on is if you press both buttons simultaneously.

publicación movida a la sección en español. Utilice inglés en el foro general.

Estás intentando usar estados y eso es genial. ¿Para qué es este proyecto, si puedo preguntar?

El mayor problema es que enciende si pulsas 1 y 2, 2 y 1, 1 y 1, 2 y 2.

Una posible solución:

const int  buttonPin1 = 2; 
const int  ledPin = 13; 
const int  buttonPin2 = 4; 
int i = 0; 

void setup() 
{
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

}


void loop() 
{

  int pin1State = digitalRead(buttonPin1);
  int pin2State = digitalRead(buttonPin2);
  
  if (i == 0) {
    if (pin1State == LOW) 
    {
      i = 1;
    }
  }

  if (i == 1) {
    if (pin2State == LOW) 
    {
      i = 2;
    }
  }
  if (i == 2) 
  {
    digitalWrite(ledPin, HIGH);
    i = 0;
  }

  delay(500);
 
}

Te toca hacer la segunda parte (apagado)

Saludos

podrías usar una máquina de estado
El diagrama de estado podría verse así

Fijate que hacia ese lado lo llevé pero sin decirle que era una máquina de estado para que no se asuste. :grimacing:

:wink: !!!!

Muchísimas GRACIAS gatul :smiley:

¿Y qué te parece así?:

const int  buttonPin1 = 2; 
const int  ledPin = 13; 
const int  buttonPin2 = 4; 
int i = 0; 

void setup() 
{
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() 
{
  int pin1State = digitalRead(buttonPin1);
  int pin2State = digitalRead(buttonPin2);

  if (i == 0) {
    if (pin1State == LOW) 
    {
      i = 1;
    }
  }


  if (i == 1) {
    if (pin2State == LOW) 
    {
      i = 2;
    }
  }

 
  if (i == 2) 
  {
    digitalWrite(ledPin, HIGH);
    i = 0;
  }


  if (i == 0) {
    if (pin2State == LOW) 
    {
      i = 1;
    }
  }


  if (i == 1) {
    if (pin1State == LOW) 
    {
      i = 2;
    }
  }


  if (i == 2) 
  {
    delay(500);
    digitalWrite(ledPin, LOW);
    i = 0;
  }

}

Me parece mejor

const int  buttonPin1 = 2; 
const int  ledPin = 13; 
const int  buttonPin2 = 4; 
int i = 0; 

void setup() 
{
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() 
{
  int pin1State = digitalRead(buttonPin1);
  int pin2State = digitalRead(buttonPin2);

  if (i == 0) {
    if (pin1State == LOW) 
    {
      i = 1;
    }
  }


  if (i == 1) {
    if (pin2State == LOW) 
    {
      i = 2;
    }
  }

 
  if (i == 2) 
  {
    digitalWrite(ledPin, HIGH);
    i = 3;
  }


  if (i == 3) {
    if (pin2State == LOW) 
    {
      i = 4;
    }
  }


  if (i == 4) {
    if (pin1State == LOW) 
    {
      i = 5;
    }
  }


  if (i == 5) 
  {
    delay(500);
    digitalWrite(ledPin, LOW);
    i = 0;
  }

}

Porque sino cuando i es 0 no se sabe si hay que apagar o encender.

De cualquier modo prueba tu código porque puedo estar equivocado y estar bien como lo has hecho. :thinking:

Saludos

Con un poco de cosmética lo que esta haciendo es un máquina de estado, pero le falta mas forma.
Es claro que se trata de un programa propuesto como tarea escolar, así que las opciones para resolverlas deberían ser bien recibidas y según su entusiasmo y motivación aprender lo que mejor le sirva.
Usar máquina de estados es la mejor opción siempre, pero preparar tu cerebro para de aquí en mas hacerlo siempre de ese modo lleva tiempo.

Sabes gatul, lo hice como Tú lo hiciste, pero mientras tanto me surgió necesario, que necesito "algo", que funcione desde la mitad del programa, y aumenté un botón más.
Hice la prueba y todo funciona muy bien :+1:
Ahí viene el programa:

const int  buttonPin1 = 2;
const int  ledPin = 13;
const int  buttonPin2 = 4;
const int  buttonPin3 = 7;
int i = 0;
int delayTime = 3000; 

void setup() 
{
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() 
{
  int pin1State = digitalRead(buttonPin1);
  int pin2State = digitalRead(buttonPin2);
  int pin3State = digitalRead(buttonPin3);

  if (i == 0) {
    if (pin1State == LOW) 
    {
      i = 1;
    }
  }


  if (i == 1) {
    if (pin2State == LOW) 
    {
      i = 2;
    }
  }

 
  if (i == 2) 
  {
    digitalWrite(ledPin, HIGH);
    i = 3;
  }


  if (i == 3) {
    if (pin2State == LOW) 
    {
      i = 4;
    }
  }


  if (i == 4) {
    if (pin1State == LOW) 
    {
      i = 5;
    }
  }

  if (i == 5) 
  {
    delay(delayTime);
    digitalWrite(ledPin, LOW);
    i = 0;
  }



  if (i == 0) {
    if (pin3State == LOW) 
    {
      i = 6;
    }
  }

  if (i == 6) {
    if (pin2State == LOW) 
    {
      i = 7;
    }
  }

  if (i == 7) 
  {
    digitalWrite(ledPin, HIGH);
    i = 8;
  }
  
  if (i == 8) {
    if (pin1State == LOW) 
    {
      i = 9;
    }
  }

  if (i == 9) 
  {
    delay(delayTime);
    digitalWrite(ledPin, LOW);
    i = 0;
  }

}

Quisiera agradecer también a todos que hicieron cualquier comentario.
¡Sois los mejores!
Saludos :wave:

J-M-L, has hecho un gran trabajo con el diagrama :clap: :clap: :clap:
Hasta ahora no lo conocía, tal vez es un nuevo camino para descubrirlo :+1:
Saludos :wave:

Muy bien!

Si me permites, te aconsejo que trates de evitar delays tan largos, piensa que durante 3 segundos pierdes el control (porque el programa literalmente se frena) y si pulsas un botón durante el delay el programa ni se entera. Lee el tema "Entender millis..." en la sección Documentación que te va a venir muy bien para evitar del abuso de los delays.

Saludos

:wink:

¿puedes usar una biblioteca de botones?
Eso haría su vida más fácil (y el código más fácil de leer)

la máquina de estado


podría implementarse de esta manera

#include <OneButton.h>  //https://github.com/mathertel/OneButton (doc @ http://www.mathertel.de/Arduino/OneButtonLibrary.aspx)

const int  botonPin1 =  2;
const int  botonPin2 =  3;
const int  ledPin    = 13;

OneButton boton1(botonPin1);  // activo LOW con PULLUP integrado
OneButton boton2(botonPin2);  // activo LOW con PULLUP integrado

enum : byte {LED_OFF, ESTADO_B1, ESTADO_B2, LED_ON} estado;

void apagaLed() {
  digitalWrite(ledPin, LOW);
  estado = LED_OFF;
}

void enciendeLed() {
  digitalWrite(ledPin, HIGH);
  estado = LED_ON;
}

void click1() {
  switch (estado) {
    case LED_OFF: estado = ESTADO_B1; break;
    case ESTADO_B2: apagaLed();  break;
    default: break;
  }
}

void click2() {
  switch (estado) {
    case ESTADO_B1: enciendeLed(); break;
    case LED_ON: estado = ESTADO_B2; break;
    default: break;
  }
}

void setup() {
  pinMode(ledPin, OUTPUT);
  boton1.attachClick(click1);
  boton2.attachClick(click2);
  apagaLed();
}

void loop() {
  boton1.tick();
  boton2.tick();
}

corto y bueno + fácil de leer, ¿no?

J-M-L, lo que hiciste, es un obra de arte, o mejor dicho: alto nivel :scream:
Tal vez algún día llegaré a éste nivel :+1:
Te agradezco muchísimo por tu aporte :pray: :clap:
Saludos :wave:

gatul, el tema es muy interesante y seguramente lo estudiaré.
Muchísimas gracias por tus sugerencias :+1: :clap: :pray:
Saludos :wave:

J-M-L, gracias a tu sugerencia, he cambiado un poco tu diagrama de estado:


Como lo puedes ver, he aumentado el "botón 3", que directamente pasa de LED_ON a LED_OFF.
Por favor, revisa el programa si lo hice bien:

#include <OneButton.h>  //https://github.com/mathertel/OneButton (doc @ http://www.mathertel.de/Arduino/OneButtonLibrary.aspx)

const int  botonPin1 = 2;
const int  botonPin2 = 4;
const int  botonPin3 = 7;
const int  ledPin    = 13;
const int  relayPin  = 9;

OneButton boton1(botonPin1);  // activo LOW con PULLUP integrado
OneButton boton2(botonPin2);  // activo LOW con PULLUP integrado
OneButton boton3(botonPin3);  // activo LOW con PULLUP integrado

enum : byte {LED_OFF, ESTADO_B1, ESTADO_B2, LED_ON} estado;

void apagaLed() {
  digitalWrite(ledPin, LOW);
  digitalWrite(relayPin, HIGH);
  estado = LED_OFF;
}

void enciendeLed() {
  digitalWrite(ledPin, HIGH);
  digitalWrite(relayPin, LOW);
  estado = LED_ON;
}

void click1() {
  switch (estado) {
    case LED_OFF: estado = ESTADO_B1; break;
    case ESTADO_B2: apagaLed();  break;
    default: break;
  }
}

void click2() {
  switch (estado) {
    case ESTADO_B1: enciendeLed(); break;
    case LED_ON: estado = ESTADO_B2; break;
    default: break;
  }
}

void click3() {
  switch (estado) {
    case LED_ON: apagaLed();  break;
    default: break;
  }
}

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(relayPin, OUTPUT);
  boton1.attachClick(click1);
  boton2.attachClick(click2);
  boton3.attachClick(click3);
  apagaLed();
}

void loop() {
  boton1.tick();
  boton2.tick();
  boton3.tick();
}

Esto luce bien !
entendiste todo :slight_smile:

Vaya progreso @mariosvd!!

Te llevo 15 dias alcanzar el nivel, felicitaciones por pasar de lo básico a usar máquinas de estados.