Codigo para semaforo

hola tengo q hacer andar unas led tipo semaforo, verde amarillo y rojo, pero con numeros, si presiono 1, 2 o 3 enciende led Rojo y queda encendido dejando apagado los otros leds. Si presiono 4,5, o 6 enciende led Amarillo y queda encendido dejando apagado los otros leds. Si presiona 7, 8 o 9 enciende led Verde y queda encendido dejando apagado los otros leds., soy nuevo en esto, mas o menos logre q se prendan con los numeros, pero no se como hacer para q se apage cuando aprieto otro numero de otro led

const int SalidaLedVerde = 2;
const int SalidaLedAmarillo = 4;
const int SalidaLedRojo = 5;
char caracter = ' ';
bool estadoencendido = false;
String palabra = "";
int numero = 0;

void setup()
{
    Serial.begin(9600);

    pinMode(SalidaLedVerde, OUTPUT);
    pinMode(SalidaLedAmarillo, OUTPUT);
    pinMode(SalidaLedRojo, OUTPUT);
}



void loop()
{
    if (Serial.available() > 0)
    {
        char letra = Serial.read();
        String palabra = String(letra);
        int numero = palabra.toInt();//atol(palabra);	
        if (numero < 4)
        {
            int i;
            for (i = 0; i < numero; i++) //i menor que numero se ejecuta n veces
            {
                digitalWrite(SalidaLedRojo, HIGH);
                delay(500);
            }
         }
    
      
     else if (numero >= 4 && numero <= 6)
        {
         int i;
         for (i = 0; i < numero; i++)
           {
            digitalWrite(SalidaLedAmarillo, HIGH);
          	delay(500);
            
        }
       }
	else if (numero >= 7 && numero <= 9)
       {
         int i;
         for (i = 0; i < numero; i++)
       {
          digitalWrite(SalidaLedVerde, HIGH);
          delay(500);
         
   		 }
        }
	   }
  }

Pues al mismo tiempo que enciendes un led apagas los otros dos, ejemplo:

digitalWrite(SalidaLedRojo, HIGH);
digitalWrite(SalidaLedAmarillo, LOW);
digitalWrite(SalidaLedVerde, LOW);

Saludos.

muchas gracias, me sirvio, t hago otra consulta, como hago para q en numero pares del 1 al 9 se encienda un determinado led o si es impar se prenda otro, no puedo sacarlo

Por ejemplo:

    switch (numero) {
      case 1 : digitalWrite(SalidaLedRojo, HIGH); digitalWrite(SalidaLedVerde, LOW); digitalWrite(SalidaLedAmarillo, LOW); break;
      case 2 : digitalWrite(SalidaLedRojo, LOW); digitalWrite(SalidaLedVerde, HIGH); digitalWrite(SalidaLedAmarillo, LOW); break;
      case 3 : digitalWrite(SalidaLedRojo, HIGH); digitalWrite(SalidaLedVerde, LOW); digitalWrite(SalidaLedAmarillo, LOW); break;
      case 4 : digitalWrite(SalidaLedRojo, LOW); digitalWrite(SalidaLedVerde, HIGH); digitalWrite(SalidaLedAmarillo, LOW); break;
      case 5 : digitalWrite(SalidaLedRojo, HIGH); digitalWrite(SalidaLedVerde, LOW); digitalWrite(SalidaLedAmarillo, LOW); break;
      case 6 : digitalWrite(SalidaLedRojo, LOW); digitalWrite(SalidaLedVerde, HIGH); digitalWrite(SalidaLedAmarillo, LOW); break;
      case 7 : digitalWrite(SalidaLedRojo, HIGH); digitalWrite(SalidaLedVerde, LOW); digitalWrite(SalidaLedAmarillo, LOW); break;
      case 8 : digitalWrite(SalidaLedRojo, LOW); digitalWrite(SalidaLedVerde, HIGH); digitalWrite(SalidaLedAmarillo, LOW); break;
      case 9 : digitalWrite(SalidaLedRojo, HIGH); digitalWrite(SalidaLedVerde, LOW); digitalWrite(SalidaLedAmarillo, LOW); break;
    }

Saludos.

1 Like

O algo mas elegante;

if ( numero % 2 == 0) { // se cumple cuando es par
  digitalWrite(SalidaLedRojo, LOW); 
  digitalWrite(SalidaLedVerde, HIGH); 
  digitalWrite(SalidaLedAmarillo, LOW); 
}
else {
  digitalWrite(SalidaLedRojo, HIGH); 
  digitalWrite(SalidaLedVerde, LOW); 
  digitalWrite(SalidaLedAmarillo, LOW); 
}
Saludos.
2 Likes

No se vale @gonpezzi estaba planteando lo mismo pero desarrollando la idea!

Bueno, lo subo igual.


Teoría: un número par es divisible por 2 (o sea, al dividirlo por 2 da resto 0, hablando de enteros). ¿De acuerdo?

La función módulo ( % ) da el resto de una división entre enteros

Entonces, X % 2 da como resultado 0 (cero) si el número X es par, ó 1 (uno) si es impar.

Llevado a código

if(X % 2 == 0) {  // entonces es par
// enciendo el/los LED que quiero
}
else { // si el resto es 1 es impar
// enciendo otros, apago los encendidos o lo que sea
}

Si quisiera discriminar por impar

if(X % 2 == 1) {  // entonces es impar
// enciendo el/los LED que quiero
}
else { // si el resto es 0 es par
// enciendo otros, apago los encendidos o lo que sea
}

Saludos

1 Like

muchas gracias, mas o menos me salió, ahora tengo dos dudas, cuando pongo un numero par el verde se prende 1 seg. y se apaga (si pongo impar se prende amarrillo y queda prendido perfecto), como hago para que se mantenga prendido hasta que apriete otro numero, y la otra duda, es como limito todo para usar números del 1 al 9

const int SalidaLedVerde = 2;
const int SalidaLedAmarillo = 3;

int numero = 0;

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

void loop()
  {
  if (Serial.available()>0)
   {
   		numero = Serial.read();

if (numero % 2 == 0)  // se cumple cuando es par
  	{
    digitalWrite(SalidaLedVerde,HIGH); 
    digitalWrite(SalidaLedAmarillo, LOW); 
  	}
  
else 
	{
  
  digitalWrite(SalidaLedVerde, LOW); 
  digitalWrite(SalidaLedAmarillo, LOW); 
	}
  
  }
 

{
if (numero % 2 == 1)  // se cumple cuando es impar
  	{
    digitalWrite(SalidaLedVerde,LOW); 
    digitalWrite(SalidaLedAmarillo, HIGH); 
  	}
  
else 
	{
  digitalWrite(SalidaLedVerde, LOW); 
  digitalWrite(SalidaLedAmarillo, LOW); 
	}
  }
  
}

Quita lo que pusiste por impar, yo solo lo puse como ejemplo si quisieras discriminar por impar en lugar de par.

El else del primer código se encarga de los impares (fijate que lo aclaré en el comentario).

Veamos


Si (if) el numero es par
hago tal cosa
sino (else) // si no es par entonces es impar
hago tal otra


Entonces luego hacer lo contrario no tiene sentido. ¿Me explico?

1 Like

Y para acotar entre el uno y el 9 te basta con un if :

if (numero > 0 && numero < 10) {// Acotamos entre el 1 y el 9
//comprobamos la paridad
}

Otra forma mas para comprobar la paridad :

      // Comprobamos, (en binario), el ultimo bit de "numero",se cumple el if cuando es inpar.
      // El ultimo bit de un numero impar siempre es un 1 el de un par siempre 0
      if (bitRead(numero, 0)) {
        digitalWrite(SalidaLedVerde, LOW);
        digitalWrite(SalidaLedAmarillo, HIGH);
      }
      else {
        digitalWrite(SalidaLedVerde, HIGH);
        digitalWrite(SalidaLedAmarillo, LOW);
      }

Saludos.

1 Like

Si, también puede hacer un AND con 1

if((X & 1) == 0) {
bla, bla, bla...
}
else...

pero ¿para qué complicarle la vida?

Es más, me gusta más así que con % :grinning_face_with_smiling_eyes:

Saludos

adonde pongo el if (numero <10) probe en todos lados y no me anda

const int SalidaLedVerde = 2;
const int SalidaLedAmarillo = 3;

int numero = 0;

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

void loop()

  
{  
  
   if (Serial.available()>0)
   {
   	numero = Serial.read();
 	if (numero < 10)
	
    {
    if (numero % 2 == 0)  // se cumple cuando es par
   
           
    digitalWrite(SalidaLedVerde,HIGH); 
    digitalWrite(SalidaLedAmarillo, LOW); 
  	}
  
else 
  
	{
  digitalWrite(SalidaLedVerde, LOW); 
  digitalWrite(SalidaLedAmarillo, HIGH); 
	}
  
  }
 
  
  
}

Pues donde lo has puesto pero como te dije:

const int SalidaLedVerde = 2;
const int SalidaLedAmarillo = 3;
int numero = 0;

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

void loop() {
  if (Serial.available() > 0) {
    numero = Serial.read();
    if (numero > 0 && numero < 10) { // acota entre 1 y 9
      if (numero % 2 == 0) { // se cumple cuando es par
        digitalWrite(SalidaLedVerde, HIGH);
        digitalWrite(SalidaLedAmarillo, LOW);
      }
      else { // se cumple cuando es impar
        digitalWrite(SalidaLedVerde, LOW);
        digitalWrite(SalidaLedAmarillo, HIGH);
      }
    }
  }
}

Esa no se me habia ocurrido. Yo habia simplificado un poco mas la del bit menos significativo:

//Comprobacion paridad
      bool led = bitRead(numero, 0);     
      digitalWrite(SalidaLedVerde, ! led);
      digitalWrite(SalidaLedAmarillo, led);

̶Y̶ ̶y̶a̶ ̶p̶u̶e̶s̶t̶o̶s̶ ̶a̶ ̶j̶u̶g̶a̶r̶ ̶c̶o̶n̶ ̶b̶i̶t̶s̶ ̶:̶

 ̶/̶/̶C̶o̶m̶p̶r̶o̶b̶a̶c̶i̶o̶n̶ ̶p̶a̶r̶i̶d̶a̶d̶
̶ ̶ ̶ ̶ ̶ ̶ ̶d̶i̶g̶i̶t̶a̶l̶W̶r̶i̶t̶e̶(̶S̶a̶l̶i̶d̶a̶L̶e̶d̶V̶e̶r̶d̶e̶,̶ ̶!̶ ̶l̶o̶w̶B̶y̶t̶e̶(̶n̶u̶m̶e̶r̶o̶)̶)̶;̶
̶ ̶ ̶ ̶ ̶ ̶ ̶d̶i̶g̶i̶t̶a̶l̶W̶r̶i̶t̶e̶(̶S̶a̶l̶i̶d̶a̶L̶e̶d̶A̶m̶a̶r̶i̶l̶l̶o̶,̶ ̶l̶o̶w̶B̶y̶t̶e̶(̶n̶u̶m̶e̶r̶o̶)̶)̶;̶

Saludos.

Edicion : Tachado. eso no funciona , ver explicacion de @gatul en post #17

1 Like

@maxcin77 No te funciona porque te faltó un paso.
Serial.read() devuelve el código ASCII del caracter que pulsaste. Si pulsas el 1 no te devuelve 1, vas a obtener 49 que es el código de "1".

Para convertir a numero debes restarle 48 (el código de "0").

Modifica la linea para que quede así

numero = Serial.read() - 48;

y va a funcionar.

Saludos

1 Like

muchas gracias a los 2, quisiera darle solucion a ambos pero no se puede

¿Lo probaste?
lowByte() devuelve un byte (el byte de menor peso de un int, long, etc.), y como cualquier valor distinto de 0 se considera true (o sea, 1), entonces cualquier número distinto de 0 apaga el LED en el primer caso y lo enciende en el segundo, sea par o impar, da lo mismo porque es distinto de 0. :man_facepalming:t2:

Saludos

Efectivamente lo que dices es correcto , supongo que como probe solo con el monitor serie algo haria mal, ya lo corregi.

Aunque correcto seria irelevante si no quisiera acotar entre 1 y 9 ya que seguiria siendo par o impar y se cumpliria perfectamente la comprobacion de la paridad.
No le funciona porque "Serial.read ()" no lee el bufer completo y ejecuta el "if (Serial.available()" dos veces , prevaleciendo la seguda lectura , (algún caracter de control), que siempre es el mismo de ahi que:

Deberia usar la función " Serial.readString() " que si lee el buffer completo eliminando ese caracter de control. El código podria quedar algo simimilar a esto:

const int SalidaLedVerde = 2;
const int SalidaLedAmarillo = 4;
int numero;

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

void loop() {
  if (Serial.available() > 0) {
    numero = (Serial.readString()).toInt();//atol(palabra);
    if (numero > 0 && numero < 10) {// Acotamos entre el 1 y el 9
      //Comprobacion paridad
      // Comprobamos, (en binario), el ultimo bit de "numero",se cumple el if cuando es inpar.
      // El ultimo bit de un numero impar siempre es un 1 el de un par siempre 0
      digitalWrite(SalidaLedVerde, ! bitRead(numero, 0));
      digitalWrite(SalidaLedAmarillo, bitRead(numero, 0));
    }
  }
}

Obiamente para la comprobacion de la paridad puede usar la que mas le guste de las expuestas anteriormente.
Saludos.

1 Like

Yo entiendo todo pero, generalmente, me centro en responder sobre lo que preguntan (y seguramente es un error). Si alguien dice que ingresa dígitos entre 0 y 9, no creo necesario comprobar la validez, entonces no le digo que verifique que sea 0 o mas y 9 o menos, porque esa ya es la condición. En este caso esa comprobación encima provocaba el mal funcionamiento porque lo leído era un ASCII en rango 48 a 57. Como bien dices, igualmente y de pura casualidad, la paridad se cumple igual pero... no pasa el filtro de rango del numero, o sea, no se verifica nada.
El PO no dijo que quiere entrar más de un dígito ni aislar caracteres que no sean dígitos, o sea, si ingresa "K" o "T" no está contemplado en la pregunta porque son letras, no dígitos.
No preguntó cómo verificaba números de 2 o más dígitos ni qué pasaba si pulsa Intro/ Enter o como figure en el teclado.
O sea, mi respuesta fue puntual a una pregunta puntual: "¿Cómo comprobar si un dígito es par o impar?".
Repito, tal vez sea mi error ver las cosas de esta forma, tal vez mi formación (que nunca ejercí) en analisis de sistemas no aplique acá en el foro, pero eso es lo que me "machacaron" siempre: "Respuesta puntual a problema puntual".

Saludos

los molesto con otro drama, tengo que encender el led rojo n veces del 1 al 4 inclusive, el amarillo del 5 al 7 (n veces), y el verde del 8 al 9 (n veces), hice el rojo, pero no se como seguir.

const int SalidaLedVerde = 2;
const int SalidaLedAmarillo = 10;
const int SalidaLedRojo = 6;
char caracter = ' ';
bool estadoencendido = false;
String palabra = "";
int numero = 0;

void setup()
{
    Serial.begin(9600);

    pinMode(SalidaLedVerde, OUTPUT);
    pinMode(SalidaLedAmarillo, OUTPUT);
    pinMode(SalidaLedRojo, OUTPUT);
}



void loop()
{
    if (Serial.available() > 0)
    {
        char letra = Serial.read();
        String palabra = String(letra);
        int numero = palabra.toInt();	
        if (numero < 5)
        {
            int i;
            for (i = 0; i < numero; i++) 
            {
                digitalWrite(SalidaLedRojo, HIGH);
                delay(500);
                digitalWrite(SalidaLedRojo, LOW);
                delay(500);
            }
         }
    }  
    
}

Lo que debes aprender es a trabajar sin delay() o cosas como enviarle comandos y que responda en función de eso se comportarán tan mal como en el caso que has publicado. En tu caso, cualquier número menor a 5 hace que el LED rojo parpadee cada 500 mseg pero mientras no hace nada.
En cambio si usas millis() el sistema responderá.
Ve a documentación y mira como usar millis() y no morir en el intento o cualquiera de los demas tutoriales de millis() que alli se listan, hay 4 mas.

pasa que no puedo usar cosas que aun no me enseñaron, estoy limitado a if else, for while y lo que se ve