Que tal amigos del foro Arduino, soy nuevo aquí y también nuevo en arduino, tengo apenas unas semanas aprendiendo y unos días leyendo este foro, me pareció muy interesante y decidí preguntar aquí mi duda, tengo un Arduino MEGA 2560, aquí mismo en el foro he leído varias ideas sobre contadores o cronómetros inversos pero no se me ocurre como hacer lo que necesito, lo explico:
Se trata de agregar al arduino un botón al pin 4 y un led al pin 5
Si el botón es presionado el led enciende 900 segundos.
Pero por ejemplo si al led le faltan 500 segundos para apagarse y presiono el botón necesito que se agreguen 900 segundos más (ya faltarían 1400 en el ejemplo).... y si presiono otra vez al tiempo que quede 900 más y así.
Entiendo que se maneja en milisegundos no en segundos.
Lo malo es que soy tan novato que ni si quiera se me ocurre como agregar el tiempo a
lo que falta. :o
Es por eso que recurro a la sabiduría de ustedes, que ya he leído varias buenas ideas pero ninguna que me quite esta duda, gracias de antemano.
surbyte:
Como sea, la solución esta en usar millis() asi que ve a Documentación => Indice de temas tutoriales => millis()
Lo que veo en los tutoriales de los millis() es que delay no me sirve porque causa problemas cuando se necesita trabajar con más de un proceso en este caso me imagino que el hecho de tener una cuenta regresiva y la posibilidad de agregar tiempo esa cuenta puede contar como 2 procesos con lo que alcanzo a entender de los tutoriales sigo con la duda como agrego tiempo a lo que ya está contando, saltar de la idea de DELAY a millis me confunde por ser novato, creo que esta sería la forma con millis pero sigue faltando agregar tiempo al que va contando ¿alguna idea?
// ASIGNACION DE PINES
unsigned long tiempoinicio = millis ();
const int ledPinluz = 5; // numero del pin para el led
int ledStateluz = LOW; // configurar LED
long previousMillisluz = 0; // guarda la última vez que se actualizó el LED
unsigned long intervalluz = 900000; // intervalo de tiempo
const int pinon = 4; // numero del pin para el botón
// VARIABLE DE ESTADO DEL BOTON
int estaon = LOW;
void setup() {
pinMode(ledPinluz, OUTPUT); // led configurado como salida
pinMode(pinon, INPUT); // botón configurado como entrada
}
void loop() {
// LEER EL ESTADO DE PINES DE BOTON A VARIABLES
estaon = digitalRead(pinon);
// SI SE OPRIME EL BOTÓN
if (estaon == HIGH) {
if (millis () – tiempoinicio >= intervalo)
{
digitalWrite(5, HIGH);
}
}
jose:
y que es lo que llevas hecho hasta el momento?
viendo que lo que tenía con delay no funciona, leyendo sobre millis () ¿crees que esto sea un comienzo?, no sé si me hice nudos con las partes
// ASIGNACION DE PINES
unsigned long tiempoinicio = millis ();
const int ledPinluz = 5; // numero del pin para el led
int ledStateluz = LOW; // configurar LED
long previousMillisluz = 0; // guarda la última vez que se actualizó el LED
long intervalluz = 900000; // intervalo de tiempo
const int pinon = 4; // numero del pin para el botón
// VARIABLE DE ESTADO DEL BOTON
int estaon = LOW;
void setup() {
pinMode(ledPinluz, OUTPUT); // led configurado como salida
pinMode(pinon, INPUT); // botón configurado como entrada
}
void loop() {
// LEER EL ESTADO DE PINES DE BOTON A VARIABLES
estaon = digitalRead(pinon);
// SI SE OPRIME EL BOTÓN
if (estaon == HIGH) {
if (millis () – tiempoinicio >= interval)
{
digitalWrite(5, HIGH);
}
}
Añade una variable booleana a modo de flag ,inicialmente es false .Cuando aprietas el pulsador ,si esta variable es false ,es que es la primera vez ,pones el contador a 900 segundos y la variable a true,pero si al pulsar el boton la variable es true,es que ya esta realizando una temporizacion ,por lo tanto sumas tiempo .Cuando acabes la temporizacion ,la variable se pone nuevamente
a false.Controla los rebotes del pulsador ,puedes sumar mas segundos de los que quieres.
Que experimentaste con milis(), hiciste el ejemplo? Miraste BlinkWithoutDelay()?
Te diste cuenta que fácil es tomar el estado actual de millis(), y sumarle tiempo?
Entonces cada vez que persionas el boton y éste cambia de un estado digamos de 0 a 1 haces los cambios.
Presionaste una vez y tomas el estado de millis() en una variable digamos que se llame start
algo asi
start = millis();
Eso le dice a start que carge el valor de millisl() desde que se arrancó el arduino. Es lo mismo que si tu tomas el comienzo de una carrera de 10kms con todos los corredores y el cronometro esta en marcha y yo te digo..
Quiero que me digas cuanto le toma hacer la vuelta a ese corredor.. entonces cuando pase tu tomaras el tiempo parcial y a la siguiente vuelta de nuevo tomaras el parcial. Los restas y que te da? El tiempo de vuelta.
Es lo mismo que hacemos con millis().
En tu caso, que harás.. pasa el corredor y tomas el tiempo con start = millis()
comparas con 900 msg cómo? De este modo
if (millis(() - start > 900UL) { // UL es porque el compilador debe ver unsigned long
}
Si alguien vuelve a presionar el pulsador pues no solo le asignas millis() al valor de start sino que conservas el valor de start anterior
entonces quedaría asi
start += millis();
Sabes como usar un pulsador para que se accione con el flanco?
Esta por todos lados respondido, solo miras su estado y lo comparas con el estado anterior que obviamente será el opuesto.
Al final actualizas el valor anterior con el actual.
Sobre el pulsador quiero que sea pulldown, como soy muy nuevo en esto tal vez no comprendí bien lo de "accionar con el flanco" pero sí para pulldown ya tengo la información, gracias.
Escribí un código según lo que pude comprender, pero en el último if no sé si es válido lo que hice traté de reescribir el tiempo encendido y en los millis para saber el tiempo puse millis actuales menos previos ¿me equivoco?
const int ledPin = 5;
const int swchpin = 4;
int ledState = LOW;
int swchpin = LOW;
unsigned long previousMillis = 0; // guardar la ultima vez que se actualizó el led
unsigned long onTime = 9000; // millisegundos encendido
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(swchpin, INPUT);
}
void loop()
{
unsigned long currentMillis = millis();
if ((ledState == LOW) && ((swchpin == HIGH))
{
ledState = HIGH; // encender
previousMillis = currentMillis; // recordar el tiempo
digitalWrite(ledPin, ledState); // actualizar el led
}
else if((ledState == HIGH) && (currentMillis - previousMillis >= onTime))
{
ledState = LOW; // apagar
previousMillis = currentMillis; // recordar el tiempo
digitalWrite(ledPin, ledState); // actualizar el led
}
else if((swchpin == HIGH) && (currentMillis - previousMillis <= onTime))
{
onTime -= (currentMillis - previousMillis) + 9000; // agregar 9 segundos al tiempo que falta.
}
}
Lo de los flancos lo explico en toda respuesta que lo amedita. Asi que con mirar otros hilos encontrarás la respuesta. El proceso te ayudará a aprender otras cosas.
jose:
Para saber si una entrada esta en HIGH (se ha pulsado e boton ) tienes que hacer un digitalRead() de dicha entrada. digitalRead() - Arduino Reference
Gracias José lo leo ya, y corrijo lo antes posible.
jose:
Para saber si una entrada esta en HIGH (se ha pulsado e boton ) tienes que hacer un digitalRead() de dicha entrada. digitalRead() - Arduino Reference
Ya veo, son muchas cosas las que se me pasan por ser nuevo, gracias por el aviso, usé digitalRead tanto para el led como para el switch porque los if que puse toman en cuenta los estados de las 2, también renombré el estado del switch ahora que lo comprendo mejor el anterior nombre no tenía congruencia ¿que te parece ahora?
const int ledPin = 5;
const int swchpin = 4;
int ledState = LOW;
int swchState = LOW;
unsigned long previousMillis = 0; // guardar la ultima vez que se actualizó el led
unsigned long onTime = 9000; // millisegundos encendido
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(swchpin, INPUT);
}
void loop()
{
ledState = digitalRead(ledpin);
swchState = digitalRead(swchpin);
unsigned long currentMillis = millis();
if ((ledState == LOW) && ((swchpin == HIGH))
{
ledState = HIGH; // encender
previousMillis = currentMillis; // recordar el tiempo
digitalWrite(ledPin, ledState); // actualizar el led
}
else if((ledState == HIGH) && (currentMillis - previousMillis >= onTime))
{
ledState = LOW; // apagar
previousMillis = currentMillis; // recordar el tiempo
digitalWrite(ledPin, ledState); // actualizar el led
}
else if((swchpin == HIGH) && (currentMillis - previousMillis <= onTime))
{
onTime -= (currentMillis - previousMillis) + 9000; // agregar 9 segundos al tiempo que falta.
}
}
Yo iba por otro lado,con una variable booleana que indica si se esta temporizando o no :
const int ledPin = 13; //para probar con led de la placa
const int swchpin = 4;
boolean temporizando = false;
unsigned long previousMillis; // guarda comienzo temporizacion
unsigned long onTime;
#define INCREMENTO 9000
void setup() {
Serial.begin(9600); // Para probar por serial monitor
pinMode(ledPin, OUTPUT);
pinMode(swchpin, INPUT_PULLUP); // Sin pulsar el estado es HIGH ,LOW pulsado (boton conectado a GND)
}
void loop() {
if(digitalRead(swchpin) == LOW){
if(temporizando){ // Si ya esta temporizando añade tiempo
onTime += INCREMENTO;
} else { // Si no ,activa salida y comienza a temporizar con cantidad inicial que es la misma que los incrementos,9000
previousMillis = millis();
onTime = INCREMENTO;
digitalWrite(ledPin,HIGH);
temporizando = true;
}
delay(150); // rebotedel boton
}
if(temporizando){ // Si esta temporizando comprueba tiempo transcurrido,si supera el valor de onTime pone la salida en LOW
if((millis() - previousMillis) > onTime){
digitalWrite(ledPin,LOW);
onTime = 0;
temporizando = false;
}
Serial.print(onTime);
Serial.print(" ");
Serial.println(millis() - previousMillis);
}
}
Sobre la variable booleana me hizo falta leer sobre ella, recuerdo mis clases de sistemas digitales, y como sabes los números binarios Hexadecimales y álgebra de boole, mapas de Karnaugh pero desgraciadamente no me tocó ver arduino, estoy aprendiendo a puros tropiezos, y trato de entender sobre la marcha las prácticas que voy escribiendo, en este caso no había visto lo de serial print
y en otras páginas no lo pego porque no sé si rompo alguna regla.
entiendo que Serial.print imprime algo, puede ser en cualquier base potencia de 2 pero ¿como sabe lo que imprime cuando lo que está entre comillas queda vacío?
Serial.print(" ") -----es la parte que no comprendo ¿sería para limpiar pantalla?
y cuando están las lineas seguidas como sabe el programa cuando ponerlas?
Es para que puedas usar el monitor serie que viene con el IDE y ver el comportamiento del sketch.Va muy bien para depurar o comunicarse con la placa. Monitor Serie | Aprendiendo Arduino
jose:
Es para que puedas usar el monitor serie que viene con el IDE y ver el comportamiento del sketch.Va muy bien para depurar o comunicarse con la placa. Monitor Serie | Aprendiendo Arduino
interesante, haré algunas prácticas con esa función, no tenía idea, muchas gracias., estoy buscando mi protoboard para ponerme a experimentar un poco.