[RESUELTO] Secuencia para encender LEDS con pulsadores avance y retroceso

Hola buenos días, mi profesor de digitales me ha dejado la tarea de crear una secuencia para encender 5 Leds con dos pulsadores configurados en modo pull-up de tal forma que con un pulsador se encienda un Led a la vez hacia la derecha y con el otro pulsador encienda hacia la izquierda. De hecho lo resolví de forma mucho mas sencilla (con la sentencia "switch" y "case") pero el profesor quiere que específicamente lo resolvamos con lo que el hasta ahora nos a enseñado y nos dio un código base:

#define PULSADOR_ASENDENTE  2
#define PULSADOR_DESENDENTE 3
#define LED_1               4
#define LED_2               5
#define LED_3               6
#define LED_4               7
#define LED_5               8
int IFO_PULSADOR_A          =0;
int IFO_PULSADOR_D          =0;
int DESENDENTE              =0;
int ASENDENTE               =0;
void setup()
{
  pinMode(LED_1,    OUTPUT);
  pinMode(LED_2,    OUTPUT);
  pinMode(LED_3,    OUTPUT);
  pinMode(LED_4,    OUTPUT);
  pinMode(LED_5,    OUTPUT);
  pinMode(PULSADOR_ASENDENTE, INPUT);
  pinMode(PULSADOR_DESENDENTE, INPUT);
}
void loop()
{
INICIO:
  IFO_PULSADOR_D=digitalRead(PULSADOR_DESENDENTE);
  if(IFO_PULSADOR_D == LOW) //esta oprimido
  {
ESPERAR_DESENDENTE:
    IFO_PULSADOR_D=digitalRead(PULSADOR_DESENDENTE);
    if(IFO_PULSADOR_D == HIGH) //esta suelto
    {
      DESENDENTE=ASENDENTE-1;
      if(ASENDENTE<=0)
      {
        ASENDENTE=5;
        goto RUTINAS;
      }
      goto RUTINAS;
    }
    goto ESPERAR_DESENDENTE;
  }
  goto INICIO;
//RUTINAS DEL PROGRAMA
RUTINAS:
  if(ASENDENTE == 1)
  {
    goto RUTINA_1;
  }
  if(ASENDENTE == 2)
  {
    goto RUTINA_2;
  }
   if(ASENDENTE == 3)
  {
    goto RUTINA_3;
  }
  if(ASENDENTE == 4)
  {
    goto RUTINA_4;
  }
  if(ASENDENTE == 5)
  {
    goto RUTINA_5;
  }
RUTINA_1:
digitalWrite(LED_1, HIGH);
digitalWrite(LED_2, LOW);
digitalWrite(LED_3, LOW);
digitalWrite(LED_4, LOW);
digitalWrite(LED_5, LOW);
delay(500);
goto INICIO;
RUTINA_2:
digitalWrite(LED_1, LOW);
digitalWrite(LED_2, HIGH);
digitalWrite(LED_3, LOW);
digitalWrite(LED_4, LOW);
digitalWrite(LED_5, LOW);
delay(500);
goto INICIO;
RUTINA_3:
digitalWrite(LED_1, LOW);
digitalWrite(LED_2, LOW);
digitalWrite(LED_3, HIGH);
digitalWrite(LED_4, LOW);
digitalWrite(LED_5, LOW);
delay(500);
goto INICIO;
RUTINA_4:
digitalWrite(LED_1, LOW);
digitalWrite(LED_2, LOW);
digitalWrite(LED_3, LOW);
digitalWrite(LED_4, HIGH);
digitalWrite(LED_5, LOW);
delay(500);
goto INICIO;
RUTINA_5:
digitalWrite(LED_1, LOW);
digitalWrite(LED_2, LOW);
digitalWrite(LED_3, LOW);
digitalWrite(LED_4, LOW);
digitalWrite(LED_5, HIGH);
delay(500);
goto INICIO;
}

El problema es que no consigo que los Leds se enciendan de izquierda a derecha o como esta en código de forma DESENDENTE.

Agradezco mucho si alguien me puede ayudar.

Comienza corrigiendo aspectos que hacen a la buena lectura de tu parte y la nuestra.
En C o C++ solo las constantes se escriben con mayúsculas. En el código no se usan mayúsculas para los procedimientos.
No quita que lo puedes hacer pero a nuestros ojos luce mal y más de uno te hará el mismo comentario que yo.

Otra cosa, C no es Basic. En C en general no se usa el goto aunque se ha implementado para hacer fácil la transición a quien(es) viene(n) de usarlo en otros lenguajes.

Yo te lo corregiré pero teniendo en cuenta lo que te acabo de decir, lucirá muy diferente

EDITO 1:
Viendo tu código con mas detenimiento, esta claro porque falla. C no funciona como lo has planteado.
Hay que modificar todo. Dame unos minutos y te presento algo si es que no me ganan.

EDITO 2:
Como siempre a veces o muchas veces leo de modo apresurado y cuando releo me sorprendo de lo que pasé por alto (otras no me doy cuenta).

Así que esto es el código base que te dió el profesor!!!!!

Olvida mis comentarios anteriores porque no van dirigidos para ti sino para el.

Estoy sorprendido y no salgo de mi asombro!!.

Ahora no tengo claro como corregirlo si el pretende que se corrija el código de este modo.

Aclárame esto por favor.

Debes analizar bien el codigo primero y entender lo que estas haciendo.

void loop(){
INICIO:
   IFO_PULSADOR_D = digitalRead(PULSADOR_DESENDENTE);
   if (IFO_PULSADOR_D == LOW){ //esta oprimido
      ESPERAR_DESENDENTE:
      IFO_PULSADOR_D = digitalRead(PULSADOR_DESENDENTE);
      if (IFO_PULSADOR_D == HIGH){ //esta suelto
         //DESENDENTE = ASENDENTE - 1;          //Error esta aqui
         ASENDENTE = ASENDENTE - 1;              //Esta es la linea correcta
         if (ASENDENTE <= 0){
            ASENDENTE = 5;
            //goto RUTINAS;                                //Esta demás borralo
         }
         goto RUTINAS;
      }
      goto ESPERAR_DESENDENTE;
   }
goto INICIO;

PD: Hay un truco que te ahorra poner las resistencias pullup de los pulsadores de manera fisicas y es usar el pull-up por software

pinMode(PULSADOR_ASENDENTE, INPUT_PULLUP);
pinMode(PULSADOR_DESENDENTE, INPUT_PULLUP);

Acabo de percatarme que lo que enviaste es el código del profesor alterado, donde tu en ciertos lugares cambiaste DESCENDENTE x ASCENDENTE.

Te falto cambiar de pulsador y lo mas importante:

ASCENDENTE = ASCENDENTE +1;
if (ASENDENTE > 5){
    ASENDENTE = 1;
}

Esta en mi versión.

#define PULSADOR_ASCENDENTE   2
#define PULSADOR_DESCENDENTE  3
#define LED_1                 4
#define LED_2                 5
#define LED_3                 6
#define LED_4                 7
#define LED_5                 8

bool ifo_pulsador_A;
int ifo_pulsador_D, ifo_pulsador_D_Ant = true;
int descendente              =0;
int ascendente               =0;

void setup()
{
  pinMode(LED_1,    OUTPUT);
  pinMode(LED_2,    OUTPUT);
  pinMode(LED_3,    OUTPUT);
  pinMode(LED_4,    OUTPUT);
  pinMode(LED_5,    OUTPUT);
  pinMode(PULSADOR_ASCENDENTE, INPUT);
  pinMode(PULSADOR_DESCENDENTE, INPUT);
}

void loop()
{
  ifo_pulsador_D = digitalRead(PULSADOR_DESCENDENTE);
  if (ifo_pulsador_D == LOW && ifo_pulsador_D_Ant == HIGH) { //hubo cambio de flanco de 1 a 0?
      ascendente++;
      if (ascendente > 5) 
          ascendente = 1;
  }
  ifo_pulsador_D_Ant = ifo_pulsador_D;
  
  if (ascendente == 1)  {
      rutina_1();
  }
  
  if (ascendente == 2)  {
      rutina_2();
  }
  
  if (ascendente == 3)  {
      rutina_3();
  }
  
  if (ascendente == 4)  {
      rutina_4();
  }
  
  if (ascendente == 5)  {
      rutina_5();
  }

void  rutina_1() {
  delay(500);
}
  
void  rutina_2() {
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, HIGH);
  digitalWrite(LED_3, LOW);
  digitalWrite(LED_4, LOW);
  digitalWrite(LED_5, LOW);
  delay(500);
}  

void  rutina_3() {
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
  digitalWrite(LED_3, HIGH);
  digitalWrite(LED_4, LOW);
  digitalWrite(LED_5, LOW);
  delay(500);
}  

void  rutina_4() {
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
  digitalWrite(LED_3, LOW);
  digitalWrite(LED_4, HIGH);
  digitalWrite(LED_5, LOW);
  delay(500);
}  

void  rutina_5() {
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
  digitalWrite(LED_3, LOW);
  digitalWrite(LED_4, LOW);
  digitalWrite(LED_5, HIGH);
  delay(500);
}

@alexmel, sólo te diré dos cosas. Uno: si tu profesor te ha enseñado a usar el goto en C, más te valdría cambiar de profesor. Dos: si el uso del goto es cosa tuya, más te vale no volver a escribir esa palabra en tu vida.

Hola a todos, efectivamente mi profesor nos a enseñado de esta forma y usando la etiqueta goto que tanto los aterra jajajajaaja. Ya inmediatamente voy a hacer las correcciones que ustedes me han recomendado y voy a utilizar el sketch del señor surbyte y del señor Kike_GL y les comentare como me va con cada uno.

Muchísimas gracias a todos.

Pdta: voy a tomar en cuenta todas las normas etiqueta y presentación para futuros post :slight_smile:

Gracias por entenderlo y mi tirón de orejas a tu profesor por enseñarte C usando GOTO. Dile que eso es de BASIC no de C.

Buenos caballeros, ya aplique las correcciones sugeridas y el programa anda perfecto! Cabe aclarar que sabiendo que hay formas mas sencillas de realizar el código, me apego a dejarlo lo mas original posible por aquello de que mi profesor no le gusta que nos adelantemos a lo que nos enseña (así como con goto por ejemplo jajajajaja). Aquí les comparto como quedo y atendiendo las recomendaciones del señor surbyte puse los procedimientos en minúsculas:

#define pulsador_ascendente 2
#define pulsador_descendente 3
#define led_1               4
#define led_2               5
#define led_3               6
#define led_4               7
#define led_5               8
int ifo_pulsador_ascen     =0;
int ifo_pulsador_descen    =0;
int descendente            =0;
int ascendente             =0;
void setup()
{
  pinMode(led_1,    OUTPUT);
  pinMode(led_2,    OUTPUT);
  pinMode(led_3,    OUTPUT);
  pinMode(led_4,    OUTPUT);
  pinMode(led_5,    OUTPUT);
  pinMode(pulsador_ascendente, INPUT);
  pinMode(pulsador_descendente, INPUT);
}
void loop()
{
inicio:
  ifo_pulsador_descen=digitalRead(pulsador_ascendente);
  if(ifo_pulsador_descen == LOW) //esta oprimido
  {
esperar_ascendente:
    ifo_pulsador_ascen=digitalRead(pulsador_ascendente);
    if(ifo_pulsador_ascen == HIGH) //esta oprimido
    {
      ascendente=ascendente+1;
      if(ascendente>5)
      {
        ascendente=1;
      }
      goto rutinas;
    }
    goto esperar_ascendente;
  }
  ifo_pulsador_descen=digitalRead(pulsador_descendente);
  if(ifo_pulsador_descen == LOW) //esta oprimido
  {
esperar_descendente:
    ifo_pulsador_descen=digitalRead(pulsador_descendente);
    if(ifo_pulsador_descen == HIGH) //esta suelto
    {
      ascendente=ascendente-1;
      if(ascendente<=0)
      {
       ascendente=5;
      }
      goto rutinas;
    }
    goto esperar_descendente;
  }
  goto inicio;
//rutinas del programa
rutinas:
  if(ascendente == 1)
  {
    goto rutina_1;
  }
  if(ascendente == 2)
  {
    goto rutina_2;
  }
   if(ascendente == 3)
  {
    goto rutina_3;
  }
  if(ascendente == 4)
  {
    goto rutina_4;
  }
  if(ascendente == 5)
  {
    goto rutina_5;
  }
rutina_1:
digitalWrite(led_1, HIGH);
digitalWrite(led_2, LOW);
digitalWrite(led_3, LOW);
digitalWrite(led_4, LOW);
digitalWrite(led_5, LOW);
delay(500);
goto inicio;
rutina_2:
digitalWrite(led_1, LOW);
digitalWrite(led_2, HIGH);
digitalWrite(led_3, LOW);
digitalWrite(led_4, LOW);
digitalWrite(led_5, LOW);
delay(500);
goto inicio;
rutina_3:
digitalWrite(led_1, LOW);
digitalWrite(led_2, LOW);
digitalWrite(led_3, HIGH);
digitalWrite(led_4, LOW);
digitalWrite(led_5, LOW);
delay(500);
goto inicio;
rutina_4:
digitalWrite(led_1, LOW);
digitalWrite(led_2, LOW);
digitalWrite(led_3, LOW);
digitalWrite(led_4, HIGH);
digitalWrite(led_5, LOW);
delay(500);
goto inicio;
rutina_5:
digitalWrite(led_1, LOW);
digitalWrite(led_2, LOW);
digitalWrite(led_3, LOW);
digitalWrite(led_4, LOW);
digitalWrite(led_5, HIGH);
delay(500);
goto inicio;
}

Muchas gracias a todos por su ayuda y comprensión y donde quieran que estén cuidensen por favor, manténganse en casa. Saludos desde Colombia.

Pdta: surbyte compile tu código pero me sale este error por si lo quieres revisar

'rutina_1' was not declared in this scope

 if (ascendente == 1)  {
      rutina_1();//Justo aquí
  }

Te agradezco por tu cortesía al llamarme Sr. pero no hace falta. Con decir @surbyte esta mas que bien.

Por otro lado, ese error, deberías poder salvarlo por tu cuenta.

rutina_1(); esta declarado mas abajo como

Asi que el error es que olvidé poner una llave antes de ese void rutina_1() {

Observa esto

if (ascendente == 5)  {
      rutina_5();
  }
} // <== FALTA esta llave que cierra el loop x eso da error en la siguiente.

void  rutina_1() {
  delay(500);
}

Eso ocurre porque no probé el código. Muchos contestamos sin probar la compilación.