Controlando 4 LEDs con 5 pulsadores y Arduino

1

Mi código:

#define MAX 50
const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
int array[MAX];
int old_b = 0;
int val;
int counter = 0;
int i;
int temp;
int L1;
int L2;

void setup () {
  pinMode (A5, INPUT_PULLUP);
  Serial.begin(9600);
}

int readButtons (int pin) {
  int b, c;
  c = analogRead(pin);
  Serial.print("analogRead =  ");
  Serial.println(c);
  delay(100);
  if (c > 1015) b = 0;
  else if (c > 70 && c < 76) b = 1;
  else if (c > 122 && c < 128) b = 2;
  else if (c > 169 && c < 175) b = 3;
  else if (c > 209 && c < 217) b = 4;
  else if (c > 247 && c < 256) b = 5;
  else if (c > 280 && c < 291) b = 6;
  else b = 0;
  if (b == old_b) {
   return 0;
   old_b = b;
  } else {
    return b;
    old_b = b;              
    }                           
}

void loop () {
  while ((val = readButtons(5)) != 5) {
    if ((val == 1) || (val == 2) || (val == 3) || (val == 4)) {
      array[counter] = val;
      Serial.print("In  ");
      Serial.print(counter);                
      Serial.print(" saving ");            
      Serial.println(val);
      delay(200);
      counter++;
      if (counter == MAX) {
        counter = 0;
      } 
    }
  }

  temp = counter;
  counter = 0;

  for (i = 0; i < temp; i++) {
    if (array[i] % 2 == 0) {
      L1 = 2;
      L2 = array[i] / 3 + 3; 
    } else {
      L2 = 5;
      L1 = array[i] % 3 + 3;    
      }

    if (readButtons(5) != 5) {
     digitalWrite (L1, HIGH);
     if (readButtons(5) != 5) {
      digitalWrite (L2, HIGH);
      delay(1000);
      digitalWrite (L1, LOW);
      digitalWrite (L2, LOW);
      if (readButtons(5) == 5) {
        i = temp;
      }
     } else {
       digitalWrite (L1, LOW);
       i = temp; 
     }
    }

  }
}

Tengo una función que detecta si se presionó un botón. Antes de eso, he determinado en qué rango están los valores para cierto botón y todos los botones están conectados en el pin analógico 5 como this , excepto que tengo 6 y mis resistencias tienen 2200 ohmios. En el bucle while () {...} , mientras que no se presiona el quinto botón, Arduino está "mirando" si se presionó alguno de los primeros cuatro botones. Si se guardaba en una matriz y si no se seguía "buscando". Cuando se presiona el quinto botón, salimos y almacenamos el último lugar conocido en la matriz en el que se almacenó el valor y configuramos el contador de posición en cero, de modo que al comenzar de nuevo, Arduino almacena los valores en primer lugar de la matriz. Luego, basándome en lo que está almacenado, determino qué pin / LED se encenderá. Si en algún momento durante el parpadeo de los LEDs se presiona nuevamente el quinto botón, Arduino detiene el parpadeo y espera de nuevo la presión de los primeros cuatro botones. Así es como se supone que funciona en teoría. En la práctica, todavía no puedo dejar de parpadear cada vez que se presiona el botón 5to. Tengo que presionarlo varias veces, a veces son necesarias dos o incluso más veces si quiero que deje de parpadear. No creo que el uso de interrupciones ayude, ya que no sé cómo debo implementarlas en mi problema. Aquí está mi circuito (excepto que tengo Arduino Duemilanove Atmega 168). Los LED van de 1 a 4 de derecha a izquierda:

    
pregunta Nick

3 respuestas

1

Por su descripción, parece que necesita rebotar el interruptor.

Puedes hacer esto

Ya que parece que estás usando algún tipo de escalera resistiva para leer varios botones en un puerto ADC, esto será un poco más complicado.

    
respondido por el RedGrittyBrick
1

Esta sección de tu código me parece extraña:

    if (readButtons(5) != 5) {
       digitalWrite (L1, HIGH);
       if (readButtons(5) != 5) {
         digitalWrite (L2, HIGH);

Su función readButtons (5) devolverá 0 a menos que se haya producido un cambio en el estado del botón.

Por lo tanto, para que se ejecute el código digitalWrite (L2, HIGH); , deberá detectar dos pulsaciones de botones en una sucesión muy rápida.

Creo que esto debe ser un error, ya que no puedo pensar en ninguna razón plausible para que el código sea así.

¿Quizás pretende tener prensas separadas por un segundo (por ejemplo)?

Entonces seguramente el código debería ser:

        if (readButtons(5) != 5) {
          digitalWrite (L1, HIGH);
          delay(1000);
          if (readButtons(5) != 5) {
            digitalWrite (L2, HIGH);
    
respondido por el akellyirl
0

Creo que el problema es la forma en que se aplican grandes retrasos que impiden el escaneo rápido de los botones.

En el siguiente código (no probado), estoy usando pequeños retrasos de 1 ms que se ejecutan varias veces mientras se siguen escaneando los botones

#define MAX 50
const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
int array[MAX];
int old_b = 0;
int val;
int counter = 0;
int i;
int temp;
int L1;
int L2;

void setup()
{
    pinMode(A5, INPUT_PULLUP);
    Serial.begin(9600);
}

int readButtons(int pin)
{
    int b, c;
    c = analogRead(pin);
    Serial.print("analogRead =  ");
    Serial.println(c);
    //delay(100);

    if(c > 1015)
    {
        b = 0;
    }
    else
        if(c > 70 && c < 76)
        {
            b = 1;
        }
        else
            if(c > 122 && c < 128)
            {
                b = 2;
            }
            else
                if(c > 169 && c < 175)
                {
                    b = 3;
                }
                else
                    if(c > 209 && c < 217)
                    {
                        b = 4;
                    }
                    else
                        if(c > 247 && c < 256)
                        {
                            b = 5;
                        }
                        else
                            if(c > 280 && c < 291)
                            {
                                b = 6;
                            }
                            else
                            {
                                b = 0;
                            }

    if(b == old_b)
    {
        return 0;
        old_b = b;
    }
    else
    {
        return b;
        old_b = b;
    }
}

void loop()
{
    unsigned char counter_var = 0;
    val = readButtons(5);  // read the buttons

    while(val != 5)
    {
        val = readButtons(5);  // read the buttons

        if(counter_var == 0)
        {
            if((val == 1) || (val == 2) || (val == 3) || (val == 4))
            {
                counter_var == 200;  // to apply ~200ms delay
                array[counter] = val;
                Serial.print("In  ");
                Serial.print(counter);
                Serial.print(" saving ");
                Serial.println(val);
                //delay(200);
                counter++;

                if(counter == MAX)
                {
                    counter = 0;
                }
            }
        }
        else
        {
            counter_var--;  // if delay>0 then this decrements and counts delay ms
            delay(1);
        }
    }

    counter_var = 0;
    temp = counter;
    counter = 0;

    for(i = 0; i < temp; i++)
    {
        if(array[i] % 2 == 0)
        {
            L1 = 2;
            L2 = array[i] / 3 + 3;
        }
        else
        {
            L2 = 5;
            L1 = array[i] % 3 + 3;
        }

        if(readButtons(5) != 5)
        {
            digitalWrite(L1, HIGH);

            if(readButtons(5) != 5)
            {
                digitalWrite(L2, HIGH);
                delay(1000);
                digitalWrite(L1, LOW);
                digitalWrite(L2, LOW);

                if(readButtons(5) == 5)
                {
                    i = temp;
                }
            }
            else
            {
                digitalWrite(L1, LOW);
                i = temp;
            }
        }
    }
}

El cambio principal que he aplicado se encuentra en la siguiente parte (inicio de bucle ())

  unsigned char counter_var = 0;
    val = readButtons(5);  // read the buttons

    while(val != 5)
    {
        val = readButtons(5);  // read the buttons

        if(counter_var == 0)
        {
            if((val == 1) || (val == 2) || (val == 3) || (val == 4))
            {
                counter_var == 200;  // to apply ~200ms delay
                array[counter] = val;
                Serial.print("In  ");
                Serial.print(counter);
                Serial.print(" saving ");
                Serial.println(val);
                //delay(200);
                counter++;

                if(counter == MAX)
                {
                    counter = 0;
                }
            }
        }
        else
        {
            counter_var--;  // if delay>0 then this decrements and counts delay ms
            delay(1);
        }
    }

y he eliminado el delay(100) de readButtons()

    
respondido por el alexan_e

Lea otras preguntas en las etiquetas