Go Down

Topic: ¿Alguien sabe por que esta tontería de codigo no funciona? (Read 975 times) previous topic - next topic

josemanu

Les estoy haciendo a mis alumnos ejercicios para que las condiciones se les queden grabadas en el cerebro... y yo en mi infinita prepotencia hoy me he sacado de la manga un ejercicio en principio muy simple, a continuación el código:
Code: [Select]
#define O5 3
#define O4 5
#define O3 6
#define O2 9
#define O1 10
#define O0 11

#define I0 A0
#define I1 A1
#define I2 A2
#define I3 A3
#define I4 A4
#define I5 A5
 
  int lectura;
  void setup()
  {
  pinMode(O0,INPUT);
  pinMode(O5, OUTPUT);
  }
 
  void loop()
  {
    lectura = digitalRead(O0);
    Serial.print(lectura);
    while(lectura == HIGH)
    {
      digitalWrite(O5, HIGH);
    }
    while(lectura == LOW)
    {
      digitalWrite(O5, LOW);
    }
  }
 
 


Los #defines son por que estamos utilizando kits Tinker.

El caso es que el puñetero led no se enciende, es más, he hecho depuración por el puerto serie y parece que el loop() solo se ejecuta una vez.

Una manita por favor.
http://www.ardumania.es/

Iniciación

JRodrigo

#1
Nov 14, 2012, 05:37 pm Last Edit: Nov 14, 2012, 05:39 pm by JRodrigo Reason: 1
Los #define no tienen la culpa pobres :P

Piensa que los while son como el loop, tienes que ponerles algo dentro para poder salir de ellos sino el programa se queda atrapado dentro de uno de ellos y por eso parece que no se ejecuta pero el programa se queda atrapado dentro de uno de los dos while ejecutándolo sin parar.

Por que no utilizas un if en vez de un while para comparar?

Este seria tu código funcionando:
Quote

#define O5 3
#define O4 5
#define O3 6
#define O2 9
#define O1 10
#define O0 11

#define I0 A0
#define I1 A1
#define I2 A2
#define I3 A3
#define I4 A4
#define I5 A5
 
 int lectura;
 void setup()
 {
 pinMode(O0,INPUT);
 pinMode(O5, OUTPUT);

 Serial.begin(9600);
 }
 
 void loop()
 {
   lectura = digitalRead(O0);
   Serial.println(lectura);
   while(lectura == HIGH)
   {
     digitalWrite(O5, HIGH);

     break;
   }
   while(lectura == LOW)
   {
     digitalWrite(O5, LOW);

     break;
   }
 }


Un saludo!

josemanu

Lo de iniciar el puerto serie se me había pasado al hacer copy/paste pero lo había probado antes.

Gracias por lo de los break, no había pensado en ellos.

Como es para la actividad de robótica con los niños quería hacerlo con el while para que lo vieran y de paso machacar un poco más las condiciones, que las tienen un poco atragantadas.

Gracias por la colaboración.
http://www.ardumania.es/

Iniciación

Mitxel

El flujo de programa solo "entra" en un bucle como:

Code: [Select]
    while(lectura == HIGH)
    {
      digitalWrite(O5, HIGH);
    }


si la condición es verdadera, en este caso si "lectura" es HIGH. Una vez atrapado dentro del bucle while, el flujo de programa solo puede escapar si "la condición" deja de ser verdadera. Esto implica que algo que se ejecute dentro del bucle while tiene que cambiar en algún momento la "verdad" de la condición o el flujo quedará atrapado para siempre en un "bucle eterno". En este caso, salvo que haya por ahí algún código invisible, como el servicio de una interrupción, el código dentro del bucle while no cambia ni el valor de "lectura", ni el valor de HIGH lo que condena al bucle a ser un bucle infinito.

El compilador debería dar un warning en este caso porque se puede determinar que este es un bucle infinito en "tiempo de compilación"

Offtopic: Las etiquetas empleadas en los #define deberían ser palabras largas e improbables, como Pin_entrada_driver_05, para evitar que puedan aparecer accidentalmente en el código. Por ejemplo: si escribimos

#define er 456

y luego en el código

Serial.print(vv);

el preprocesador del compilador nos cambiará esa linea por:

S456ial.print(vv);

JRodrigo

[...]
Offtopic: Las etiquetas empleadas en los #define deberían ser palabras largas e improbables, como Pin_entrada_driver_05, para evitar que puedan aparecer accidentalmente en el código. Por ejemplo: si escribimos

#define er 456

y luego en el código

Serial.print(vv);

el preprocesador del compilador nos cambiará esa linea por:

S456ial.print(vv);


Eso no pasa, no es lo mismo er que Serial

Lo que si se puede hacer es definir Serial con otro nombre, por ejemplo:

Code: [Select]
#define COM Serial
···
COM.begin(9600);


Un saludo!

josemanu

Gracias a todos por la ayuda.

Cambiamos los while's por if's y a funcionar, si a fin de cuentas lo que me interesaba es que los chavales practicaran las condiciones... luego les hice la puñeta cambiando las condiciones en las que los leds debían encenderse o apagarse.

Sobre los #define estoy de acuerdo con el oftopic de Mitxel, pero digamos que son los #defines's oficiales para trabajar con el Tinker Shield.

Un saludo y de nuevo gracias a todos.
http://www.ardumania.es/

Iniciación

Go Up