Muy buenas! Soy jaime y soy de Manresa. Bien, cómo bien habéis leído en el título quiero montar un semáforo de carreras, más bien ya lo tengo montado. Hace un tiempo hice un display grande de leds, el funcionamiento es mecánico, es decir, a base de temporizadores y relés a 12v va haciendo la cuenta atrás: 5, 4, 3, 2, 1, 0 con sus respectivos zombadores de aviso. Por el momento siempre me ha funcionado bien a pesar que es muy aparatoso y pesado, lo que con un compañero comentemos de reducir el tamaño y dejarlo todo detrás del display y me comentó que pusiera una placa de arduino. Indagando e informandome me he hecho con una placa arduino nano, todo bien hasta el momento, programa bien instalado, detecta la placa, e incluso hago las 4 cosas básicas como hacer un blink pero a la hora que quiero ponerme en serio no me aclaro. He visto un montón de tutoriales e incluso he instalado ardublock pero aún así no me aclaro, me gustaría mucho aprender pero no hay manera. Después de este tostón ahí va mi cuestión: me gustaria activar la cuenta atrás con un pulsador y que vaya haciendo la cuenta atrás cada segundo activando cada salida para activar los reles para el display numerico y al llegar al 0 esté un par de segundos y luego esté en reposo y no haga el bucle. Sólo si lo activo través del pulsador. No quiero que me mandéis la programación, me gustaría poder hacerlo yo y aprender que estoy haciendo. Perdón por el tostón y sed benévolos que soy un novato.
Saludos
Echa un ojo al ejemplo que viene con el IDE Archivo->Ejemplos->Digital->BlinkWithoutDelay en el que podras ver como se trabaja con la funcion millis() que devuelve el tiempo que lleva funcionando el sketch , a partir de aqui ,se trataria de consultar el tiempo transcurrido desde que se pulsa el boton que inicia la secuencia .Por ejemplo si el tiempo esta entre 0 y 1 segundos ,acciona ultimo led,entre 1 y 2 segundos apaga ultimo led y enciende penultimo ......etc
Gracias por tu aportación José. Y sí, he estado trasteando los tiempos con el blink y mas o menos se como se activan las salidas y los tiempos. De momento con la ayuda de ardublock he conseguido hacer un código y me gustaría que le echarais un ojo a ver que tal, al verificar no me ha dado ningún error.
void setup()
{
pinMode( 3 , INPUT);
pinMode( 5 , OUTPUT);
pinMode( 6 , OUTPUT);
pinMode( 7 , OUTPUT);
pinMode( 8 , OUTPUT);
pinMode( 9 , OUTPUT);
pinMode( 10 , OUTPUT);
}
void loop()
{
if (digitalRead(3))
{
delay( 3000 );
}
else
{
digitalWrite( 5 , HIGH );
delay( 1000 );
digitalWrite( 5 , LOW );
delay( 100 );
digitalWrite( 6 , HIGH );
delay( 1000 );
digitalWrite( 6 , LOW );
delay( 100 );
digitalWrite( 7 , HIGH );
delay( 1000 );
digitalWrite( 7 , LOW );
delay( 100 );
digitalWrite( 8 , HIGH );
delay( 1000 );
digitalWrite( 8 , LOW );
delay( 100 );
digitalWrite( 9 , HIGH );
delay( 1000 );
digitalWrite( 9 , LOW );
delay( 100 );
digitalWrite( 10 , HIGH );
delay( 3000 );
digitalWrite( 10 , LOW );
}
}
P.D. Por lo que indagado, al conectar un pulsador a una entrada, hay que poner una resistencia. Es cierto?
Echa un ojo a las normas del foro y edita tu post para adecuarlo .Te recomende el uso de millis() porque delay() "detiene" el sketch el tiempo que le pongas y durante ese tiempo ,la placa no responde a nada salvo las interrupciones,pero si solo quieres que haga eso o no vas a hacer nada durante la cuenta atras ,el uso de delay puede ser una solucion sencilla.En cuanto a la resistencia puedes usar pullup o pulldown: http://ovtoaster.com/resistencias-pulldown-y-pullup/ .Si usas pulldown ,recibiras un HIGH en la entrada cuando el boton este pulsado(pasas un positivo del pin 5v por el pulsador al pin de entrada) .Si usas pullup recibiras un LOW en el pin de entrada cuando pulses el boton (conectas el boton al pin gnd y a la entrada).
buenas, yo también soy aficionado a las carreras... el principal problema que veo en tu código es que usas un delay para el LOW, osea que en realidad habrá 1,1 segundos (por ejemplo) entre el pin 5 y el 6, puedes eliminar ese pequeño delay y también te funcionaria de maravilla. necesitas que incorpore un cronometro también? si es así yo me sumo al proyecto y tratamos de armar algo útil, si no lo necesitas creo que ese código cumple con lo que necesitas.
Saludos
Si quieres armar un cronómetro no podrán usar delay(), tendrán que pasar a millis().
Hay mucha documentación en Search : pongan millis() cronómetro (con o sin acento) y a estudiar/probar cada caso.
jose:
Echa un ojo a las normas del foro y edita tu post para adecuarlo .Te recomende el uso de millis() porque delay() "detiene" el sketch el tiempo que le pongas y durante ese tiempo ,la placa no responde a nada salvo las interrupciones,pero si solo quieres que haga eso o no vas a hacer nada durante la cuenta atras ,el uso de delay puede ser una solucion sencilla.En cuanto a la resistencia puedes usar pullup o pulldown: http://ovtoaster.com/resistencias-pulldown-y-pullup/ .Si usas pulldown ,recibiras un HIGH en la entrada cuando el boton este pulsado(pasas un positivo del pin 5v por el pulsador al pin de entrada) .Si usas pullup recibiras un LOW en el pin de entrada cuando pulses el boton (conectas el boton al pin gnd y a la entrada).
Ya está editado. Gracias por la aportación José,si si quiero que la secuencia se active mediante la pulsación y cuando acabe este en reposo. También me ha quedado clarísimo como funciona el pull up y el pull down que tenia mis dudas y al final he hecho un pull down.
He conectado los seis pins con un led con sus respectivas resistencia a cada pin y el pulsador para probar y si que funcionaba la secuencia pero lo hacia en bucle y se activaba sola. Al final buscando por internet he podido cambiar el código y funciona bien:
iasvoid setup()
{
pinMode( 3 , INPUT);
pinMode( 5 , OUTPUT);
pinMode( 6 , OUTPUT);
pinMode( 7 , OUTPUT);
pinMode( 8 , OUTPUT);
pinMode( 9 , OUTPUT);
pinMode( 10 , OUTPUT);
}
void loop()
{
if (( ( digitalRead(3) ) == ( LOW ) ))
{
delay( 3000 );
}
else
{
digitalWrite( 5 , HIGH );
delay( 900 );
digitalWrite( 5 , LOW );
delay( 100 );
digitalWrite( 6 , HIGH );
delay( 900 );
digitalWrite( 6 , LOW );
delay( 100 );
digitalWrite( 7 , HIGH );
delay( 900 );
digitalWrite( 7 , LOW );
delay( 100 );
digitalWrite( 8 , HIGH );
delay( 900 );
digitalWrite( 8 , LOW );
delay( 100 );
digitalWrite( 9 , HIGH );
delay( 900 );
digitalWrite( 9 , LOW );
delay( 100 );
digitalWrite( 10 , HIGH );
delay( 2000 );
digitalWrite( 10 , LOW );
}
}
Lo que aún tengo un par de dudas:
-
Mi intención es que cuando pulse espere 3 segundos y active la secuencia, lo que pasa ahora, es que tengo que pulsar el pulsador durante 3 segundos. Hago algo mal y no lo veo.
-
Para realizar la prueba lo alimento mediante usb, al desconectar el usb y volverlo a conectar para saber si se ha guardado bien en la placa y probar ( manías mías ) he pulsado el pulsador y no ha funcionado, se quedaba el led rojo de la placa parpadeando y no hacia nada mas.
De nuevo muchas gracias.
Si usas pulldown tu entrada estara en LOW con el pulsador en reposo y HIGH cuando estes pulsando el boton ,si lo has conectado bien,luego la condicion que debes evaluar con if es: si la entrada esta en HIGH -> Activa la secuencia .
void setup() {
pinMode( 3 , INPUT);
pinMode( 5 , OUTPUT);
pinMode( 6 , OUTPUT);
pinMode( 7 , OUTPUT);
pinMode( 8 , OUTPUT);
pinMode( 9 , OUTPUT);
pinMode( 10 , OUTPUT);
}
void loop() {
if ( digitalRead(3) == HIGH) {
delay( 3000 );
digitalWrite( 5 , HIGH );
delay( 900 );
digitalWrite( 5 , LOW );
delay( 100 );
digitalWrite( 6 , HIGH );
delay( 900 );
digitalWrite( 6 , LOW );
delay( 100 );
digitalWrite( 7 , HIGH );
delay( 900 );
digitalWrite( 7 , LOW );
delay( 100 );
digitalWrite( 8 , HIGH );
delay( 900 );
digitalWrite( 8 , LOW );
delay( 100 );
digitalWrite( 9 , HIGH );
delay( 900 );
digitalWrite( 9 , LOW );
delay( 100 );
digitalWrite( 10 , HIGH );
delay( 2000 );
digitalWrite( 10 , LOW );
}
}
maddC:
buenas, yo también soy aficionado a las carreras... el principal problema que veo en tu código es que usas un delay para el LOW, osea que en realidad habrá 1,1 segundos (por ejemplo) entre el pin 5 y el 6, puedes eliminar ese pequeño delay y también te funcionaria de maravilla. necesitas que incorpore un cronometro también? si es así yo me sumo al proyecto y tratamos de armar algo útil, si no lo necesitas creo que ese código cumple con lo que necesitas.Saludos
Buenas maddC ya esta rectificado y ahora sí es un segundo mientras enciende y apaga. A lo del cronómetro no seria mala idea lo que pasa que yo uso un dígito que usare para la cuenta atrás, lo que sí tengo es un pequeño display de cuatro dígitos y si se pudiera se podrá hacer un cronómetro ( si ya tengo dolores de cabeza con lo del semáforo de salida imagínate poner un cronómetro también, jejeje ). Pero ya que estamos, porque no?¿
El display en concreto es este:
Tienes toda la razón. He vuelto a leer el enlace y el valor ha de ser HIGH. Acabo de provar y funciona perfectamente.