Tengo un problema que me trae de cabeza ya durante un par de dias y no se como solucionarlo.
Mi idea es hacer un dimmer mediante programación para poder controlar la iluminación de un led con un único pulsador. El funcionamiento que pretendo es el siguiente:
Pulsaciones cortas = ON/OFF led
Pulsaciones largas (>= 1 segundo) = Regulación led
#define LED 2
#define BOTON 53
#define ESPERA 0
#define SUBE 1
#define BAJA 2
#define ON 3
#define OFF 4
byte BRILLO = 0;
byte MODO = ESPERA;
unsigned long tiempo;
unsigned long tiempo2;
int retardoPulsacion = 1000;
void setup(){
pinMode(LED, OUTPUT);
pinMode(BOTON, INPUT);
}
void loop(){
if(!digitalRead(BOTON)){
MODO = ESPERA;
Serial.println("ESPERA");
tiempo=millis();
Serial.println(tiempo);
}
else if(digitalRead(BOTON)){
tiempo2=millis();
Serial.println(tiempo2);
switch(MODO){
case SUBE:
BRILLO = min (BRILLO++, 255);
break;
case BAJA:
BRILLO = max (BRILLO--, 0);
break;
case ON:
BRILLO = 255;
break;
case OFF:
BRILLO = 0;
break;
default:
if ((tiempo2-tiempo) < retardoPulsacion){
MODO = ((BRILLO == 0) ? ON : OFF);
}
else if ((tiempo2-tiempo) >= retardoPulsacion){
MODO = ((BRILLO == 0) ? SUBE : BAJA);
}
}
}
analogWrite(LED,BRILLO);
delay(10);
}
He probado todo lo que se me a ocurrido incluso la función pulseIn y no he conseguido que funcione. Con dos botones independientes, uno para encender y otro para regular si que he podido hacerlo funcionar, pero con el mismo no.
El problema creo que esta en que la pulsación la reconoce siempre antes como pulsación corta (aunque no haya llegado a soltar el botón). Entonces creo que debería hacer la comparación de los tiempos antes. Pero no se como hacerla.
Es que me pillas sin arduino y no puedo comprobar, pero creo que no ando lejos de la solución. Prueba a cambiar el valor inicial de brillo a 100 (error haber puesto cero). De paso muestra por serial su valor, a ver que resultado obtienes.
Tranquilo, al final creo que por fin he encontrado la solución. Gracias a tu sketch me has dado la idea de guardar el tiempo en el que se realiza la pulsación y el tiempo en el que se suelta para después compararlos. Y si es menor a 1 segundo ---> ON/OFF. Por otro lado también guardo el momento en el que pulso el botón y lo comparo con millis y si es mayor a 1 segundo ---> Regulación,
Dejo aquí el código por si a alguien le queréis pegar un ojo, o por si a alguien le puede servir, ya que no tengo demasiada experiencia en programación y me a costado días encontrar la solución.
#define LED 2 //Pin al que esta conectado el LED
#define BOTON 53 //Pin al que esta conectado el pulsador
#define ESPERA 0 //Modo espera (dimmer)
#define SUBE 1 //Modo regulacion ascendente (dimmer)
#define BAJA 2 //Modo regulacion descendente (dimmer)
boolean estadoActual = 0; //Estado actual pulsador
boolean estadoUltimo = 0; //Estado ultimo pulsador
boolean contadorONOFF = 0; //Contador de pulsaciones
unsigned long Tinicio; //Momento en que se pulsa el pulsador
unsigned long Tfin; //Momento en que se libera el pulsador
unsigned long Tpulsacion; //Diferencia Tfin-Tinicio
long retardoPulsacion = 1000; //Tiempo pulsacion larga
byte BRILLO = 0; //Valor del Brillo
byte MODODIMMER = ESPERA; //Modo dimmer (Espera, Sube, baja)
void setup(){
pinMode(BOTON,INPUT); //Boton como entrada
pinMode(LED,OUTPUT); //LED como salida
Serial.begin(9600);
}
void loop(){
//PARA CONTROL ON/OFF//
estadoActual = digitalRead(BOTON); //Para leer el estado del pulsador
if(estadoActual != estadoUltimo){ //Si el nuevo estado es distinto al ultimo...
if(estadoActual == HIGH){ //Si el estado es alto(cuando se aprita el boton)
contadorONOFF = contadorONOFF + 1; //Incrementa 1 al contador
Tinicio = millis();} //Guarda el momento de la pulsacion
if(estadoActual == LOW){ //Si el estado es bajo(cuando se libera el boton)
Tfin = millis();} //Guarda el momento de la liberacion
Tpulsacion = (Tfin-Tinicio); //Calculo de la duracion de la pulsacion
}
estadoUltimo = estadoActual; //Guarda el ultimo estado del boton
if((contadorONOFF % 2 != 0)&&(Tpulsacion<retardoPulsacion)){ //Pulsacion impar enciende el LED
ONLED();}
else if((contadorONOFF % 2 == 0)&&(Tpulsacion<retardoPulsacion)){ //Pulsacion par apaga el LED
OFFLED();}
//PARA CONTROL DIMMER//
if(!digitalRead(BOTON)){ //Mientras el boton este en reposo el dimmer estara en espera
MODODIMMER = ESPERA;
Tinicio = millis();} //Guarda el ultimo instante en el dimmer a estado en espera
else{DIMMER();} //Cuando se pulsa boton se activa el dimmer
//CONTROL LED//
analogWrite(LED,BRILLO); //Escritura del valor del led
}
//ENCENDDIDO ILUMINACION//
void ONLED(){
if((Tpulsacion) < retardoPulsacion){BRILLO = 255;}
}
//APAGADO ILUMINACION//
void OFFLED(){
if((Tpulsacion) < retardoPulsacion){BRILLO = 0;}
}
//DIMMER//
void DIMMER(){ //Si el tiempo de la pulsacion es mayor a un segundo
switch(MODODIMMER){ //se activara la regulacion, que sera ascendente o descente
case SUBE: BRILLO = min (BRILLO++, 255); break; //dependiendo del valor de BRILLO
case BAJA: BRILLO = max (BRILLO--, 0); break;
default:
if ((millis()-Tinicio) >= retardoPulsacion){
MODODIMMER = ((BRILLO == 0) ? SUBE : BAJA);
}
}
delay(10);
}
Se aceptan sugerencias, opiniones, criticas, etc XD
tambien puedes usar la funcion pulsein. pero tampoco que es imposible.
te quedas en u while hasta que suelte la tecla. antes de eso tomas los milis actuales, al salir del while tomas los milis y comparas el tiempo.
la libreria buttons lo hace. ahora desde el celular no leo bien todo
juanpintom:
Enhorabuena! ha costado pero ha salido!! jaja, ahora a por mas cosas!
Muchas gracias
Ahora quiero ver de mostrar en el display LCD el nivel de regulación en tanto por %.
Y a ver si llega pronto el pedido y empiezo a probar el sistema Souliss que ya tengo ganas
Edito:
Desde que me comentas que podía usar el monitor serie para encontrar errores, se me hace un poco mas sencilla la tarea
También he estructurado el código por llamadas a funciones y así tengo la menor parte del código posible en el loop, esto hace que el programa vaya mas fluido.
maxid:
tambien puedes usar la funcion pulsein. pero tampoco que es imposible.
te quedas en u while hasta que suelte la tecla. antes de eso tomas los milis actuales, al salir del while tomas los milis y comparas el tiempo.
la libreria buttons lo hace. ahora desde el celular no leo bien todo
Hola maxid,
He estado probando la librería de Button, EasyButton y pulseIn pero aun no me aclaro mucho con las librerías, por eso lo he intentado hacer sin ellas. De todas formas agradezco tu interes.
juanpintom:
Enhorabuena! ha costado pero ha salido!! jaja, ahora a por mas cosas!
Muchas gracias
Ahora quiero ver de mostrar en el display LCD el nivel de regulación en tanto por %.
Y a ver si llega pronto el pedido y empiezo a probar el sistema Souliss que ya tengo ganas
Edito:
Desde que me comentas que podía usar el monitor serie para encontrar errores, se me hace un poco mas sencilla la tarea
También he estructurado el código por llamadas a funciones y así tengo la menor parte del código posible en el loop, esto hace que el programa vaya mas fluido.
Un saludo
Para mostrarlo en el LCD simplemente mostrando BRILLO es suficiente
Lo de Souliss ya te digo yo que es mas "cumplido" que programar "a pelo" como en este post, me refiero a que usando las librerias (solo hay que leer el "manual" o referencia de cada una de ellas), en este caso usando Souliss, al tener ya todo o casi todo el codigo hecho, es mucho mas sencillo añadir un boton que haga la funcion de dimmer en pulso largo y de on/off, de hecho ya tengo un boton asi y luego meter otras muchas cosas es igual de sencillo. Me referia a que es mucho mas "cumplido" a que con poco ves muchos avances y yo al menos, me incentiva mas asi.
Lo de monitor serial es mano de santo! jaja, no se puede vivir sin el XD
Lo de organizar el Loop es mucho mejor a la hora de ser leido por "nosotros", y si, hacen mas eficiente el codigo, aunque en estos codigos "pequeños" es imperceptible.
El caso es que he hecho una regla de tres para que el valor mostrado sea en %.
Tengo unas ganas de que me lleguen ya los MAX485 y el ENC28J60 XD
Ahora, lo siguiente que voy a hacer es añadir un mando a distancia para poder controlar todas las funciones del proyecto principal. Ya he leido los valores hexadecimales de las teclas para poder asignarlas
Lo de organizar el Loop es mucho mejor a la hora de ser leído por "nosotros", y si, hacen mas eficiente el código, aunque en estos códigos "pequeños" es imperceptible.
Ya te digo si es mejor a la hora de entenderlo. XD
Pues yo si que he notado que va mas fluido, aunque tal vez es por que antes estaba un poco arreu y se volvia un poco loco al leer el código XD