Go Down

Topic: Ayuda a Principiante !!! (Read 2499 times) previous topic - next topic

Gatoloco65

Saludo !!!
en resumidas cuentas lo que pretendo es unir los ejemplos Blink y Button. para lo cual escribí el siguiente código:
Code: [Select]

/* Con este ejercicio quiero unir los ejemplos Blink y Button.
   Lo que pretendo es que tres Led's prendan y apaguen
   secuencialmente; e independiente de la secuencia de los tres
   led's, cuando se oprima el pulsador el Led # 4 se encienda y
   se apague a  X tiempo.
*/

int Led1 = 6;     
int Led2 = 7;     
int Led3 = 8;
int Led4 = 9;
int Pulsador = 2;

void setup()                     
{
  pinMode(Led1, OUTPUT);       
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  pinMode(Led4, OUTPUT);
  pinMode(Pulsador, INPUT); 
}

void loop()  {                     

  digitalWrite(Led1, HIGH);     
  delay(200);
  digitalWrite(Led1, LOW);
  delay(200);
  digitalWrite(Led2, HIGH);   
  delay(200);
  digitalWrite(Led2, LOW);   
  delay(200);
  digitalWrite(Led3, HIGH);   
  delay(200);
  digitalWrite(Led3, LOW);
  delay(200);
  digitalWrite(Led1, HIGH);     
  digitalWrite(Led2, HIGH);
  digitalWrite(Led3, HIGH);   
  delay(200);
  digitalWrite(Led1, LOW);     
  digitalWrite(Led2, LOW);
  digitalWrite(Led3, LOW);
  delay(200);
  digitalWrite(Led1, HIGH);     
  digitalWrite(Led2, HIGH);
  digitalWrite(Led3, HIGH);
  delay(500); 
  digitalWrite(Led1, LOW);     
  digitalWrite(Led2, LOW);
  digitalWrite(Led3, LOW); 
 
if (digitalRead(Pulsador)==HIGH) //Pulsador oprimido
 
   
   { digitalWrite(Led4,HIGH); //Enciende el LED
    delay (3000);  //Tiempo Prendido
    digitalWrite(Led4,LOW); //Apaga el LED
   }
}


Lo que No he podido hacer es que el Led # 4 se encienda cuando oprimo el pulsador, solo se activa cuando lo dejo oprimido unos segundos y cuando este prende la secuencia de los otros tres Led's se
interrumpe hasta que se apaga el led # 4.

Mi pregunta es como se independizan cada una de las funciones propuestas ?

Gracias !!!






curro92

Hola,

todo lo que está en loop() se ejecuta secuencialmente una y otra vez, y la comprobación del pulsador tiene que esperar a pasar todos los delay() en cada ciclo. Una forma de esperar menos, sería hacer la comprobación después de cada delay, la podrías formular como una pequeña función
Code: [Select]

comprobar_pulsador()
{
    if (digitalRead(Pulsador)==HIGH) //Pulsador oprimido
    {
         digitalWrite(Led4,HIGH); //Enciende el LED
         delay (3000);  //Tiempo Prendido
         digitalWrite(Led4,LOW); //Apaga el LED
    }
}


Si necesitas una respuesta más rápida para el pulsador, puedes usar las interrupciones, tendrás dos por lo menos en los digital 2 y 3, attachInterrupt() llama a una función cuando ocurre algo. Tienes un ejemplo en http://arduino.cc/en/Reference/AttachInterrupt




Gatoloco65

Gracias curro92.
Me pondré ahora mismo a modificar el código y a estudiar lo de las interrupciones a ver cual me va mejor.

Suerte !!!

Gatoloco65

Saludo !!!

Modifique el código utilizando las interrupciones externas "attachInterrupt()",  pero sigo sin obtener los resultados que pretendo. he logrado, hacer que el led # 4 se encienda
cuando oprimo el pulsador, pero cuando le agrego que se apague a X tiempo no lo hace, el led # 4 parpadea y se apaga nuevamente sin esperar el tiempo asignado.
He leído que estas interrupciones son muy sensibles a las variables que tienen que ver con el tiempo "delay" no se si lo que estoy diciendo sea lo correcto, pero es lo que entiendo;
añado el nuevo código por si es que hay algo malo en el, le agradecería a curro92 si me puede dar nuevamente una manito o alguien que tenga la amabilidad de orientarme.
Gracias.
Code: [Select]
/* Con este ejercicio quiero unir los ejemplos Blink y Button.
   Lo que pretendo es que tres Led's prendan y apaguen
   secuencialmente; independiente de la secuencia de los tres
   led's, cuando se oprima el pulsador el Led # 4 se encienda y
   se apague a  X tiempo.
*/

int Led1 = 6;     
int Led2 = 7;     
int Led3 = 8;
int Led4 = 9;
int Pulsador = 2;
volatile int estado = HIGH;
void setup()                     
{
  pinMode(Led1, OUTPUT);       
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  pinMode(Led4, OUTPUT);
  pinMode(Pulsador, INPUT);
  attachInterrupt(0,Inicia,CHANGE); 
}

void loop()  {                     

  digitalWrite(Led1, HIGH);     // Secuencia de Los Led
  delay(200);
  digitalWrite(Led1, LOW);
  delay(200);
  digitalWrite(Led2, HIGH);   
  delay(200);
  digitalWrite(Led2, LOW);   
  delay(200);
  digitalWrite(Led3, HIGH);   
  delay(200);
  digitalWrite(Led3, LOW);
  delay(200);
  digitalWrite(Led1, HIGH);     
  digitalWrite(Led2, HIGH);
  digitalWrite(Led3, HIGH);   
  delay(200);
  digitalWrite(Led1, LOW);     
  digitalWrite(Led2, LOW);
  digitalWrite(Led3, LOW);
  delay(200);
  digitalWrite(Led1, HIGH);     
  digitalWrite(Led2, HIGH);
  digitalWrite(Led3, HIGH);
  delay(500); 
  digitalWrite(Led1, LOW);     
  digitalWrite(Led2, LOW);
  digitalWrite(Led3, LOW);
 
 
}

void Inicia()
 
{
if (digitalRead(estado==HIGH)); //Pulsador oprimido
 
   
   digitalWrite(Led4,HIGH); //Enciende el LED
   delay(5000);
   digitalWrite(Led4,LOW); //apaga el Led para esperar a que sea
                           //oprimido nueva/.el pulsador
 
}





curro92

Hola Gatoloco65,
todo lo que se ejecuta cuando haces la comprobación if() tienes que ponerlo entre llaves,
if(digitalRead(Pulsador) == HIGH)
{
   ...
}
en caso contrario se te ejecutará siempre, independientemente de la comprobación. También he cambiado la forma de hacer la comprobación, a digitalRead  le paso el pin donde tiene que leer, y la función devuelve HIGH ó LOW
Code: [Select]

void Inicia()
{
    if (digitalRead(Pulsador) == HIGH)   //Pulsador oprimido
     {
        digitalWrite(Led4,HIGH); //Enciende el LED
        delay(5000);
        digitalWrite(Led4,LOW); //apaga el Led para esperar a que sea oprimido nueva/.el pulsador
     }
}


Cuando llamas a attachInterrupt() utilizas el 'mode' CHANGE, que actúa tanto cuando pasa de LOW a HIGH, como cuando lo hace de HIGH a LOW
Puedes probar el modo RISING, que actúa solo cuando pasa de LOW a HIGH


Gatoloco65

Saludo !!! curro92

Hice lo que me sugeriste colocando las llaves { } , en la parte del codigo :
Code: [Select]
{

if (digitalRead(estado==HIGH)); //Pulsador oprimido
[b]{[/b]
   digitalWrite(Led4,HIGH); //Enciende el LED
   delay(5000);
   digitalWrite(Led4,LOW); //apaga el Led para esperar a que sea
                           //oprimido nueva/.el pulsador
[b]} [/b]                       
 
}



Pero sigue sin funcionar, cuando oprimo el pulsador, el Led #4 se enciende momentaneamente, sin cumplir el tiempo que se le asigno en el "delay".

Seguiré buscando hasta dar con el problema. debe haber algo en el código que no este haciendo bien.

Curro92 de nuevo mil gracias por tu colaboración.




curro92

Dos cosas:
- tienes un punto y coma al final del if(), que estropea la sentencia
- la comprobación yo la haría así: if (digitalRead(Pulsador) == HIGH), porque a digitalRead() le tienes que pasar el pin que debe leer

Gatoloco65

Saludo !!!

Curro92 he cambiado la sentencia tal como lo propones y no cambia en nada el comportamiento del Led #4.

He estado revisando los ejemplos sobre E/S Digitales y creo que para este caso se debe utilizar: "Blink Without Delay: parpadeo sin delay, enciende y apaga
el LED sin usar la función delay()." utilizando la función "millis()". Voy a empezar a buscar la forma de acoplar este ejemplo en mi código.   

Por ahora deduzco que me falta mas estudio, pero bueno de eso se trata... de aprender poco a poco.

Suerte curro y tan pronto tenga algún resultado te lo comunico.


Gatoloco65

Saludo !!!

Buscando en el foro me encontré con el siguiente post. Led parpadeante sin delay y diferente On y Off de Lee Majors. http://arduino.cc/forum/index.php/topic,31235.0.html. adapte el codigo al mio y nuevamente No resulto. =(
Cuando oprimo el pulsador el Led #4 se enciende durante el tiempo establecido, pero los Led 1 y 2 dejan de parpadear hasta que el Led #4 termina su ciclo. Busco nuevamente la ayuda de ustedes para ver si me pueden orientar; les dejo el nuevo codigo.
Code: [Select]
int led1 = 6;
int led2 = 7;
int pulsador = 2;       
int led4 = 8;
boolean flag = true;
long previousMillis = 0;
long On = 500;             // tiempo que dura encendido, en milisegundos
long Off = 500;          // tiempo que dura apagado, en milisegundos

void setup(){
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(pulsador, INPUT);
  pinMode(led4,OUTPUT);
 
}

void loop(){ 
  if (digitalRead(pulsador)==HIGH)
   {
     digitalWrite(led4,HIGH); //Enciende el LED
     delay (5000);  //Tiempo Prendido
     digitalWrite(led4,LOW); //Apaga el LED
   }
   
  if (millis() < (previousMillis + On + Off)){
    flag = true;
  }
  else {
   flag = false;
   previousMillis = millis();
  }
  if (flag == true){
   if (millis() > (previousMillis + On)){
   digitalWrite(led1, LOW);
   digitalWrite(led2,HIGH);
   }
   else{
     digitalWrite(led1, HIGH);
     digitalWrite(led2,LOW);
   }
  }

}


Gracias !!!

curro92

Hola,
cuando usas delay(5000) le estás a diciendo al arduino que se pare y no haga nada durante 5 segundos. Yo creo que no tienes que usar delay. Tendrías que contar milisegundos al encender el led4, seguir el ciclo y comprobar a intervalos cuándo pasan los 5000, y entonces apagarlo.

Gatoloco65

Saludo !!!
ahi si me perdí ... como podría usar micros y hacer su comprobación ?

Perdóname curro92 pero no entiendo lo que me propones, he realizado miles de ensayos utilizando diferentes funciones y tratando de acoplar lo que encuentro en la red sobre interrupciones tiempos etc... pero no encuentro la solución,  pienso que cada vez me enredo mas y no logro lo que deseo.

Nuevamente gracias por tu colaboración.

Gatoloco65 

curro92

Hola, Gatoloco65
yo intentaría resolver primero sin delay lo que se refiere al pulsador, luego intentaría resolver del mismo modo el led intermitente, y finalmente juntar los dos códigos.
Para el pulsador, prueba este código ( lo que está comentado se refiere al puerto serie que he usado para depurar, porque no tengo puesto el pulsador)
Code: [Select]

int led4 = 8;
int pulsador = 2;
unsigned long  m4;
#define PAUSA4 5000L

void setup()
{
  // Serial.begin(9600);
  m4 = 0L;
}

void loop()
{
   if (digitalRead(pulsador)==HIGH  /* || ( Serial.available() && Serial.read() == 'a') */ )
   {
        digitalWrite(led4,HIGH);
        m4 = millis(); 
        // Serial.println("4");
   }
   if(m4)
   {
      if(millis() - m4 > PAUSA4)
      {
         digitalWrite(led4,LOW);
         // Serial.println("0");   
         m4 = 0L;
      }
   }
}



curro92

Hola Gatoloco65
Ahí va otro código para parpadear un LED sin delay, a ver si te sirve.
Code: [Select]

/*
Parpadeo de LED con un tiempo de encendido (TIEMPO_ON) y otro de apagado (TIEMPO_OFF).
El resto de dividir millis() entre la suma de los dos tiempos
se reparte entre el encendido y el apagado.
(NOTA: en la IDE de Arduino no puedo escribir con acentos, es normal eso?)
*/

int led2 = 9;

#define TIEMPO2_ON  3000L
#define TIEMPO2_OFF 1000L


void loop()
{
   if ( (millis() % (TIEMPO2_ON + TIEMPO2_OFF)) < TIEMPO2_ON)
   {
       digitalWrite(led2,HIGH);
   }
   if ( (millis() % (TIEMPO2_ON + TIEMPO2_OFF)) >= TIEMPO2_ON)
   {
       digitalWrite(led2,LOW);
   }
}


Gatoloco65

Saludo !!!

Gracias curro92 por tu valiosa colaboración. Uní los dos códigos que me enviaste y ahora si funciona tal como me lo habia planteado; salvo que el led intermitente no prende con la misma intensidad, no es problema del led, pues ya probé otros y en diferentes salidas. te dejo el código nuevo para que revises o le complementes algo.

Code: [Select]
int led4 = 8;
int led2 = 9;
int pulsador = 2;
unsigned long  m4;
#define PAUSA4 5000L

void setup()
{
  pinMode(led4, OUTPUT);
  pinMode(pulsador, INPUT);
  m4 = 0L;
  #define TIEMPO2_ON  500L
  #define TIEMPO2_OFF 1000L
}

void loop() {

    if ( (millis() % (TIEMPO2_ON + TIEMPO2_OFF)) < TIEMPO2_ON)
     {
       digitalWrite(led2,HIGH);
     }
       if ( (millis() % (TIEMPO2_ON + TIEMPO2_OFF)) >= TIEMPO2_ON)
     {
       digitalWrite(led2,LOW);
     }
 
  if (digitalRead(pulsador)==HIGH) 
   
   {
       digitalWrite(led4,HIGH);
       m4 = millis(); 
       
   }
   
     if(m4)
   
       if(millis() - m4 > PAUSA4)
     {
         digitalWrite(led4,LOW);
         m4 = 0L;
      }
   
}


Luego lo termino de pulir y le coloco todos los comentarios para que quede bien explicado. nuevamente mil gracias.


Go Up