Go Down

Topic: Pregunta simple. (Read 1 time) previous topic - next topic

Disc

Hola.

Soy novata con esto del arduino, se un poco de programación C pero aun así estoy teniendo un problema muy simple. Espero que puedan ayudarme.
Estoy realizando un código para prender y apagar un led cuando se ingrese una contraseña por el serial monitor, en este caso la contraseña es '1' pero posteriormente en el desarrollo del programa el usuario podrá cambiarla haciendo uso de un teclado matricial. El problema que tengo ahora es que en efecto el led se apaga y se prende adecuadamente, pero también se imprime la instrucción de contraseña errónea en el Serial monitor (aun después de darle la contraseña correcta), cuando la contraseña que ingreso es incorrecta la leyenda se imprime dos veces. No se a que se deba esto, agradecería un poco de ayuda, ocupo que la leyenda solo se imprima en el serial monitor cuando la contraseña es errónea y en ese caso que se imprima una sola vez.

Aquí les dejo el código que tengo:

Code: [Select]
/*Programa para prender un Led dada una contraseña en el Serial Monitor */

const int ledPin = 12; // Led al pin 12
int contra='1', band=0, val;      //variable para leer el dato
void prenderled(void);

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  prenderled();
}

void prenderled()
{
if(band==0){
  Serial.println("\n Ingrese contrasena:");
  band=1;}
 
   if (Serial.available() > 0) {
     int lectura = Serial.read();
     
     if(lectura==contra)
    {
      val=digitalRead(ledPin);
      if(val==HIGH){
        digitalWrite(ledPin, LOW); 
        Serial.println("\n Led apagado");
        band=0;
        Serial.println(lectura);
        }
      else{
        digitalWrite(ledPin, HIGH);
        Serial.println("\n Led prendido");
        Serial.println(lectura);
        }
    }
    else
    {
     Serial.println("\nContrasena erronea");
     Serial.println(lectura);
    } 
     
  }
}


Gracias.

Heke

Es por como has puesto el condicional:

Has puesto: 

   si
      hay algo en el puerto serie.....
   sino
     contraseña erronea
     lectura

Tienes que modificar el condicional y poner:
 
  hay algo en el puerto serie     
       si (hay algo en el serie)
           lo que hay es correcto
                      si -->  contraseña correcta
                      sino --> contraseña erronea
       no (no hay nada en el serie)
   sino
       nada
         
   
CUIDADO !! MIS POST NO SON APTOS PARA MENORES. SI ERES MENOR DE 14 AÑOS DEBES DE LEERLOS ACOMPAÑADO DE UN ADULTO

Disc

Antes que nada muchas gracias por responder. Sin embargo no me queda del todo claro lo que me dices, según yo he puesto el condicional como lo planteas la segunda vez. De haberlo puesto como la primera vez en todo caso siempre que no haya lectura en el puerto serie debería de imprimirme la leyenda "contraseña errónea" ¿no?
He puesto un condicional "if(lectura==contra)" el cual precisamente pregunta si lo que hay en el puerto serie es correcto de ser incorrecto me debe de mandar al "else" donde se imprime la contraseña errónea, sin embargo pareciera como si entrara al "if" y posteriormente al "else" también, o en todo caso dos veces al "else"

Una disculpa de antemano si no entredí tu respuesta. Gracias por tu tiempo.

Heke

#3
Nov 17, 2012, 12:11 pm Last Edit: Nov 17, 2012, 12:21 pm by Heke Reason: 1
Hola

Mira, segun lo veo en tu codigo, podemos:

Por un lado eliminar la funcion "Prenderled()"  que no te hace falta, esa puede ir dentro del "void loop"

Por otro lado tienes si  "band==0" que supongo sera la variable del pulsador, (aqui habria que hacer algo para evitar el tema de los rebotes de pulsadores, por las lecturas extras que te puede dar.

En el condicional, pones "if serial available() > 0"  {y aqui englobas unas instrucciones} pero tienes puesto que "else" {imrimir contraseña erronea y lectura}

Por el puerto serie lees lo que venga pero que puede ser contra (o sea 1) o cero pero y ¿los retornos de carro o los line feed que puede enviar el serial?

Aparte te imprime tanto si hay "serial available como si no"

Mi consejo: no pongas el condicional en serial available, ponlo en la comprobacion del dato simplemente comprueba si hay datos en el serial, sean los que sean, y si coincide con lo que quieres entonces si imprimes.

A ver si me explico mejor: que la instruccion sea algo asi:
Code: [Select]
if (Serial.available() > 0)
    {
    int lectura = Serial.read();  
    if(lectura==contra)
      {
      val=digitalRead(ledPin);
      if(val==HIGH)
        {
        digitalWrite(ledPin, LOW);  
        Serial.println("\n Led apagado");
        Serial.println("\nContrasena correcta");    // lo he incluido aqui pero no se si este es contraseña que quieres o no, cambialo a tu gusto
        band=0;
        Serial.println(lectura);
        }
     else
        {
        digitalWrite(ledPin, HIGH);
        Serial.println("\n Led prendido");
        Serial.println("\nContrasena erronea");    // lo he incluido aqui pero no se si este es contraseña que quieres o no, cambialo a tu gusto
        Serial.println(lectura);
       }
   }


No he comprobado tu codigo, solo he insertado para que veas donde pongo el serial print.

Lo que no se es ¿para que pones \n antes de imprimir el texto?

A ver si mas o menos he podido aclararte lo que queria decirte...

Ya diras....

Un saludo.

PD: Igual el ejemplo del IDE de arduino 1.0.1 de "serialevent"  te ayuda un poco:
Code: [Select]
/*
  Serial Event example

When new serial data arrives, this sketch adds it to a String.
When a newline is received, the loop prints the string and
clears it.

A good test for this is to try it with a GPS receiver
that sends out NMEA 0183 sentences.

Created 9 May 2011
by Tom Igoe

This example code is in the public domain.

http://www.arduino.cc/en/Tutorial/SerialEvent

*/

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {
    Serial.println(inputString);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

/*
  SerialEvent occurs whenever a new data comes in the
hardware serial RX.  This routine is run between each
time loop() runs, so using delay inside loop can delay
response.  Multiple bytes of data may be available.
*/
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

CUIDADO !! MIS POST NO SON APTOS PARA MENORES. SI ERES MENOR DE 14 AÑOS DEBES DE LEERLOS ACOMPAÑADO DE UN ADULTO

Disc

De nuevo gracias.

La funcion " prenderled()" la he incluido aparte puesto que posteriormente incluiré mas funciones, en realidad el programa va para mas largo y lo tengo que presentar, asuntos de estética realmente.
La band=0 no corresponde a ningún pulsador, solo la uso para que imprima la primera linea una sola vez, es decir que me pida la contraseña una sola vez y me la vuelva a pedir solo cuando se apague el led.

Si te fijas bien el "else" de imprimir contraseña errónea no corresponde al "if serial available() > 0" (de hecho el "if serial available() > 0" no lleva ningún "else" en el código) sino que corresponde al "if(lectura==contra)", puesto que como tu has dicho en dado caso me imprimiría la leyenda "contraseña errónea" incluso cuando no hay lectura en el Puerto serie, cosa que el programa no hace.

Sin embargo tienes razón, el problema seguramente lo debe de estar dando el retorno de carro, puesto que el programa lee en el serial un código que no corresponde al de la contraseña imprime entonces el "contraseña errónea". Seguiré modificando el código a ver que obtengo.

Gracias por el ejemplo adjunto.
Saludos.

Go Up