Mi objetivo es hacer que un LED esté parpadeando durante X tiempo (un tiempo largo, me refiero a horas) y que después de ese X tiempo el programa dejase de seguir funcionando.
¿Es posible realizar esto en Arduino? Y si es así, ¿cuáles serían las funciones que debería usar?
Creo que no me expliqué bien, a lo que me refería era que mi intención es que un Led parpadee cada segundo (por ejemplo) y que después de un minuto de estar el led parpadeando ya la placa quede sin energía (ya que estará haciendo otras funciones y no quiero que las haga después de ese minuto).
Gracias a krnlpanic que me dijo lo de los millis he hecho este pequeño código que os dejo a continuación, pero al compilarlo me sale el error : ´Error compilando para la tarjeta Arduino/Genuino Uno.`
Para que el programa "finalizase" mi idea fue meter el código en un bucle while cuando se cumpliese ese minuto para que así el resto del programa no se siguiera ejecutando (no se si es una buena idea...)
Muchas gracias por vuestra ayuda
const int Led=9;
unsigned long TiempoAntes= 0;
const long intervalo = 60000;
void setup() {
pinMode(Led, OUTPUT);
}
void loop() {
TiempoAntes= millis();
while(millis() >= TiempoAntes+ intervalo);{Led=LOW;}
digitalWrite(Led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(Led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
[code]
// Aquí defines Led como una constante. Al ser así no puedes modificarla en
// ningún lugar del programa.
const int Led=9;
unsigned long TiempoAntes= 0;
const long intervalo = 60000;
void setup() {
pinMode(Led, OUTPUT);
}
void loop() {
TiempoAntes= millis();
// Led=LOW es una asignación no valida, Led es una consante que vale 9 y
// se puede modificar, el código de error de compilación es:
// "assignment of read-only variable "Led"
// Led es una constate de solo lectura.
while(millis() >= TiempoAntes+ intervalo);{Led=LOW;}
digitalWrite(Led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(Led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Además veo que no entiendes como funciona millis. Mi recomendación es que mires la documentación y leas el ejemplo blinkWithoutDelay que viene con el IDE.
No debería hacer lo que voy a hacer, pero aquí tienes:
/*
* Este código se ejecuta el tiempo que le digamos en la variable
* tiempo_en_marcha, durante el cual el led de la placa arduino
* parpadeará durante 1 segundo.
* Transcurrido el tiempo_en_marcha, se apaga el led y no vuelve
* a parpadear.
*/
unsigned long tiempo_en_marcha = 20000;
unsigned long tinicio;
unsigned long tactual;
unsigned long tprev;
void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13,HIGH);
// Guardo cuando se inicia el loop.
tinicio = millis();
}
void loop()
{
// Leo el valor de millis actual.
tactual = millis();
// Si el valor actual menos el inicio es menor que el
// el tiempo que debe estar en marcha.
if ( tactual - tinicio < tiempo_en_marcha ) {
// Tenemos que hacer el blink. Comprobamos que el
// tiempo actual menos el anterior del blink sea
// mayor de 1 segundo.
if ( tactual - tprev >= 1000 ) {
// Hacemos la inversión del pin.
digitalWrite(13, !digitalRead(13));
// Guardamos el valor actual de millis, en tprev,
// para luego ver si ha transcurrido un segundo
// de nuevo.
tprev = tactual;
}
}
else {
// Ya se ha terminado el tiempo que debe estar en
// marcha. Si se quedo encendido el led lo apagamos.
digitalWrite(13, LOW);
}
}
Espero que entiendas el código. Estrujálo, empapatelo, y sobretodo ENTIENDELO!!
Dime donde en alguno de los ejemplos la placa queda SIN ENERGIA, tu código o los siguientes o incluso el mío? No hay manera de que quede sin energia a menos que pongas un rele de autoenclave que le quite la energia al cumplir con la tarea que sugieres.
y que después de un minuto de estar el led parpadeando ya la placa quede sin energía .
Que se quede sin energía es incompatible con este otro comentario
(ya que estará haciendo otras funciones y no quiero que las haga después de ese minuto)
si esta haciendo otras funciones entonces esta con energia.
Si por un lado quieres que el led parpadee y luego de un minuto haga otras cosas, entonces no te refieres a quedase sin energia si no a que el LED se apague.
Vaya complicación para explicar una idea u objetivo.
Pero al comienzo afirmas
Mi objetivo es hacer que un LED esté parpadeando durante X tiempo (un tiempo largo, me refiero a horas) y que después de ese X tiempo el programa dejase de seguir funcionando.
Esto se logra como dije de muchos modos, porque por ejemplo si lo pones en el setup, el programa ya no funciona.
Y espero que todo esto no te moleste porque no le busco la 5ta paga al gato ni hacerte enfadar.
Solo te consulto porque no se comprende lo que quieres hacer?
Si en lugar de expicarte parcialmente, explicas toda la idea, entonces se entenderá todo mejor.
Cual es la idea completa?
@victorjam
Muchas gracias por tu ayuda, la verdad que me ha servido de mucho. El programa que escribiste no conseguía que el LED parpadease y estaba encendido durante todo el tiempo (no sé por qué) pero gracias a ese y a las anotaciones que hiciste en el código que envié he conseguido que haga lo que me proponía. Dejo el código por si alguien lo necesitara en algún momento.
/*
* Este código se ejecuta el tiempo que le digamos en la variable
* tiempo_en_marcha, durante el cual el led de la placa arduino
* parpadeará durante 1 segundo.
* Transcurrido el tiempo_en_marcha, se apaga el led y no vuelve
* a parpadear.
*/
unsigned long tiempo_en_marcha = 60000;
unsigned long tinicio =0;
unsigned long tactual;
unsigned long tprev;
void setup()
{
pinMode(9, OUTPUT);
digitalWrite(9,HIGH);
// Guardo cuando se inicia el loop.
tinicio = millis();
}
void loop()
{
// Leo el valor de millis actual.
tactual = millis();
// Si el valor actual menos el inicio es menor que el
// el tiempo que debe estar en marcha.
if ( tactual + tinicio < tiempo_en_marcha ) {
digitalWrite(9, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(9, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
else {
// Ya se ha terminado el tiempo que debe estar en
// marcha. Si se quedo encendido el led lo apagamos.
digitalWrite(9, LOW);
}
}
Y en cuanto a lo de entenderlo, es una necesidad (tampoco me ha gustado eso de hacer las cosas a lo loco sin entender nada), ya que esto es solo parte lo que estoy haciendo y tengo que entender todo bien. Muchas gracias otra vez por tu ayuda.
@surbyte
No me molesta en absoluto, ya que yo no entiendo mucho de electrónica y estoy aprendiendo, así que veo normal que haga preguntas que a personas que saben de estos temas les puedan parecer preguntas sin sentido.
Yo no sé si se puede quedar sin energía la placa de algún modo o no, por eso lo he preguntado.
Aún creo que no entendiste del todo mi objetivo, igualmente gracias por intentar ayudarme.
Mi objetivo real es controlar la temperatura de un pequeño reactor térmico en el que se van a realizar hidrogenaciones para biocombustibles, y en función de la temperatura medida en el reactor encender o apagar la corriente para que la resistencia que actúa como fuente de calor siga calentando o no (comenté que era un led para que fuese más fácil y rápido de explicar),pero este proceso requiere de un tiempo, que puede llegar a varias horas, por tanto es necesario que cuando acabe,automaticamente el reactor deje de calentar (de ahí que el programa deje de funcionar)
Doy fé de que mi código funciona. Mi Uno lo hace correctamente. La diferencia está en que por no poner un led en el pin 9, usé el pin 13 que en la placa está unido a un led. Si haces un copy paste del código y lo subes al arduino, es el led el de la placa el que parpadea.
Sólo hay un detalle que no tuve en cuenta. En 49 dias millis() se desbordará con lo que el tiempo actual y el de inicio serán de nuevo menor que el tiempo en marcha y se volverá a repetir el proceso, es decir, el proceso se repite cada 49 dias.
Para solucionarlo habría que poner una variable "hecho" para que no vuelva a ocurrir.
/*
* Este código se ejecuta el tiempo que le digamos en la variable
* tiempo_en_marcha, durante el cual el led de la placa arduino
* parpadeará durante 1 segundo.
* Transcurrido el tiempo_en_marcha, se apaga el led y no vuelve
* a parpadear.
*/
unsigned long tiempo_en_marcha = 40000;
unsigned long tinicio;
unsigned long tactual;
unsigned long tprev;
bool hecho;
void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13,HIGH);
// Guardo cuando se inicia el loop.
tinicio = millis();
// La variable indicando el ciclo la pongo a falsa.
hecho=false;
}
void loop()
{
// Leo el valor de millis actual.
tactual = millis();
// Si el valor actual menos el inicio es menor que el
// el tiempo que debe estar en marcha y no está hecho.
if ( tactual - tinicio < tiempo_en_marcha && hecho==false) {
// Tenemos que hacer el blink. Comprobamos que el
// tiempo actual menos el anterior del blink sea
// mayor de 1 segundo.
if ( tactual - tprev >= 1000 ) {
// Hacemos la inversión del pin.
digitalWrite(13, !digitalRead(13));
// Guardamos el valor actual de millis, en tprev,
// para luego ver si ha transcurrido un segundo
// de nuevo.
tprev = tactual;
}
}
else {
// Ya hemos "hecho" el proceso con lo que la variable ha
// de ponerse a true para que no vuelva a ejecutarse nunca
// mas (excepción a reinicio de arduino.
hecho=true;
// Ya se ha terminado el tiempo que debe estar en
// marcha. Si se quedo encendido el led lo apagamos.
digitalWrite(13, LOW);
}
}
Tu código final, aunque funciona, presenta el problema del uso del delay con lo que durante dos segundos (mientras hace el parpadeo) no hace otra cosa. Por ejemplo, vas a pulsar un botón durante el parpadeo... ¿te lo va a leer?
Y ahora que has posteado tu "idea" mas general. ¿Qué ocurre cuando hay una situación de emergencia que debas parar todo y estas en esos dos segundos? Muerte, destrucción...
Bueno, yo quedé "enganchando" con una parte de la explicación que espero corrijas para no repetirla en el futuro.
El arduino como cualquier microcontrolador una vez energizado no lo detienes, puedes ponerlo en bajo consumo como a tu televisor cuando sigue a la espera que lo enciendes (valga la comparación) pero nada mas.
Desconectarlo es terreno para todo un proyecto y obviamente no era tu idea.
Entonces, lo que tu querías expicar es que realizaría un proceso y luego de terminado se queda a la espera del siguiente proceso o lo apagas.
Eso es lo que casi siempre se hace.. o realiza tareas repetitivas como automata que es o se queda a la espera de eventos (pulsadores o lectura de señales digitales que le dicen haz esto o lo otro).
Si la respuesta de @victorjam ya te satisfizo y el tema esta resuelto me dices y cierro el hilo, pero si este tema debe progresar al siguiente nivel, sería bueno que lo sigas aquí mismo, aunque demores en su seguimiento (no mas de 4 meses).
No dudo de que a tí te funcione, pero a mi no me parpadeaba (aunque esto fue cuando cambié la entrada del led que actuaba), independientemente de esto me sirvió para acabar esa parte del proyecto.
En cuanto a lo de desborda después de 49 días yo había pensado que con presionar el botón de reset valdría.
Y bueno, espero que la situación no llegue nunca a muerte y destrucción pero iba a ponerle que cuando enviase una letra cualquiera a la placa la resistencia la resistencia se apagase.
En principio los detalles que me faltan por incluir en el proyecto son pequeños y ya tengo una idea bastante clara de lo que tengo que hacer. Así que si quieres puedes cerrar el hilo.