Alternar dos leds usando una sola salida del microcontrolador

A quien no le ha pasado quedarse sin salidas del microcontrolador y necesitar alternar el encendido de dos led dependiendo del estado, es decir, cuando esté a HIGH la salida del microcontrolador se encienda, por ejemplo, un LED verde y cuando esté a LOW uno rojo.

Soluciones a este problema hay muchas y muy variadas, desde comunicar con otro microcontrolador (un desperdicio para tan poca cosa), usar transistores, o la que os propongo hoy:

Alternar dos leds usando una sola salida del microcontrolador con diodos 1N4007.

ledsalternos

Mediante este sencillo circuito podemos controlar 2 leds dependiendo del estado de salida de la patilla deseada del microcontrolador.

Os dejo código de prueba para Arduino:

int led = 3;

void setup() {

pinMode(led, OUTPUT);
}

void loop() {
digitalWrite(led, HIGH);
delay(500);
digitalWrite(led, LOW);
delay(500);
}
Anuncios

Programación PIC y uso (y no abuso) de delay(milisegundos)

Casi todos, cuando empezamos a programar PIC, tenemos la costumbre de usar la función delay(milisegundos) casi para todo. Hemos de tener en cuenta que esta función detiene la ejecución del programa el tiempo que le digamos.

Tomemos, por ejemplo, un programa que nos muestra la hora, no queremos que en cada iteración del programa nos la muestre, sería terriblemente pesado ver salir muchísimas veces el mismo segundo …. Así que lo que queremos es que nos muestre la hora cada vez que pase un segundo.

Casi todos hemos pensado lo mismo, muestro la hora, espero un segundo y la vuelvo a mostar; y para eso usamos delay():

void loop(){
  Serial.println(dimeFecha());
  delay(1000);
}

Si bien es una solución, no es la mejor. Al llegar a la función delay() el programa se detiene 1 segundo (una eternidad en tiempo de proceso del PIC). Supongamos que tenemos otra parte del programa donde necesitamos la hora para hacer alguna cosa, como el programa se ha detenido 1 segundo nada más poner la hora, el dato de la hora llegará con 1 segundo de retraso a resto del programa. Y eso nos puede dar mucho dolor de cabeza.

Para resolver este problema, voy a proponer dos soluciones: una basada en el uso de la función millis() y otra haciendo uso de la hora devuelta por el propio reloj (que para eso esta ¿no? 😉 ).

Usando millis() tendremos el siguiente código:

long tiempo=0;
void setup(){
}
void loop(){
  if(millis()-tiempo>1000){
    tiempo=millis();
    Serial.println(dimeFecha());
  }
}

¿Qué hace este programa?

  • Establece la variable global tiempo a 0.
  • En el bucle loop() comprueba si los milisegundos transcurridos (millis()) menos el tiempo guardado es mayor a 1000 milisegundos (1 s).
  • En caso que se cumpla la condición, se guarda el valor actual de millis() en la variable tiempo y se muestra la hora.
  • El programa continúa sin detenerse para nada.

Podemos comprobar que es una solución bastante elegante y simple; pero hay algo que debemos tener en cuenta: la función millis() cuenta el tiempo desde que empezó a ejecutarse el programa en ciclos de procesador, es decir, no va sincronizada con el reloj, por lo que al mostrarse la hora llevará un desfase con el tiempo real.

Para solucionar este último inconveniente propongo la solución de usar el propio reloj para mostrar la hora cada segundo, aquí está el código:

int segundos=0;
void setup(){
}
void loop(){
  DateTime ahora;
  ahora=RTC.now();
  if(ahora.second() != segundos){
    segundos=ahora.second();
    Serial.println(dimeFecha());
  }
}

Podemos comprobar que el funcionamiento de este programa es análogo al anterior, pero con la particularidad de que se usa el reloj para controlar cuando se va a imprimir la hora.

Como nota final, comentaros que es muy importante tener en cuenta el uso (o abuso) de la función delay() ya que en la mayoría de los casos un pic nos da la impresión de ir lento y no caemos en la cuenta de que somos nosotros los que estamos haciendo que se pare.

Por otro lado, la función dimeFecha() es esta:

/*
FUNCION PARA OBTENER LA FECHA EN MODO TEXTO
Devuelve: DD-MM-AAAA HH:MM:SS
*/
String dimeFecha(){
  
    char fecha[19];
    DateTime now = RTC.now(); //Obtener fecha y hora actual.

    int dia = now.day();
    int mes = now.month();
    int anio = now.year();
    int hora = now.hour();
    int minuto = now.minute();
    int segundo = now.second();

    sprintf( fecha, "%.2d/%.2d/%.4d %.2d:%.2d:%.2d", dia, mes, anio, hora, minuto, segundo);
    return String( fecha );
}

Hasta el próximo. Espero vuestros comentarios.

Regresando al mundo de la electrónica

La electrónica fue siempre una de mis pasiones, cuando niño y durante la adolescencia me pasaba la horas entre resistencias, condensadores, diodos, transistores …. Entretanto aparecieron los ordenadores personales y la puerta al mundo de la programación, que me fascinó y me absorbió hasta convertirse en mi profesión y mi afición. La electrónica quedó relegada a un segundo plano, pero siempre estuvo ahí. La aparición de los microPics me llevaron al mundo de poder unir las dos pasiones, pero nunca pasé de hace cosas sencillas.

Había oído hablar de Raspberry Pi y de Arduino, y al final me hice con ellos para ver que era eso y qué se podía hacer. Simplemente me cautivaron y me devolvieron aquella pasión que tanto sentía por la electrónica.

A día de hoy estoy a las puertas de conseguir entrar en una empresa para desarrollar un proyecto con microPics. Un proyecto donde se va a diseñar todo el sistema desde cero, desarrollo de una controladora basada en microPic, software de configuración y software de usuario.

Estoy luchando con todas mis fuerzas por conseguirlo, será como un sueño hecho realidad.