Saludos ArduMyth. Lo primero de todo es pedirte disculpas porque creo que he sido algo pedante y grosero contigo. No debería de tratar así a alguien nuevo en el foro que trata de ayudar desinteresadamente. Así que ruego sepas disculparme.
Aunque parezca sarcasmo, lo que dije:
IgnoranteAbsoluto:
… muchas gracias por poner tu código y así se pueda ver un claro ejemplo de cómo no se ha de programar.
… lo dije en serio y con toda buena intención (tal vez no con buenos modales). Creo que no se debería de poner ejemplos y explicaciones ofuscadas para aquellos que son nuevos, están aprendiendo y carecen de muchos conocimientos y experiencia en la programación. Además de ser un muy mal hábito el “programar para uno”, sin pensar en “los demás” ya que, en el caso de necesitar ayuda, tu código puede resultar “áspero” y poco legible para otros. Así que, en serio, creo que has puesto un claro ejemplo de cómo no programar.
ArduMyth:
Curiosamente yo opino que tu código es el que está mal, incompleto, largo, ofuscado, ineficiente y ni sabes hacer lo más básico con millis()... Peeeero en ningún momento te dije que así no se debe programar, no cómo tú.
Si no sabes usar millis() ¿qué potestad tienes criticando a quien sí sólo porque tus conocimientos sean escasos?
Con otro tipo de comentario te habría explicado y me habría "adecuado" más a tu forma de programar.
Creo que te has confundido, quien hace la consulta y necesita ayuda no soy yo, sino Shadoaru. Soy yo, y no él, quien ha criticado tu código. No critico la escasez de comentarios, sino el mal uso de nombres de las variables y, sobre todo, el usar un array como único contenedor de datos que son muy diferentes y heterogéneos entre sí. Ya que deberían de ser de tipos diferentes, sería preferible usar una simple estructura con la que poder especificar tipos y nombres diferentes a cada uno de los elementos que conjuntamente controlan lo que deseamos hacer. Precisamente en mi respuesta a Shadoaru le remito a un post donde explico paso a paso cómo hacerlo, así como el recorrido “lógico” que lleva al resultado final.
En cuanto a lo que dije yo, no Shadoaru, de...
IgnoranteAbsoluto:
Aunque, siguiendo tu criterio, no entiendo porqué pones comentarios. ¿No es escribir de más? El preprocesador del compilador es de lo primero que elimina del código antes de compilar.
… confieso que quería ser sarcástico. Mis disculpas.
Respecto a:
ArduMyth:
Dí que sí. Guarda el valor de millis() en una variable de tipo byte y a ver que depura el IDE...
Había dicho claramente:
IgnoranteAbsoluto:
...derrochas memoria de mala al tratar todas las variables como tipo int. Cuando, si te fijas, en más de un caso con un byte tendrías (e incluso menos, si utilizas los campos de bits).
“en más de un caso”, no para todos los casos. De hecho, para controlar los “famosos” millis(), es aconsejable utilizar variables de tipo unsigned long, en lugar del tipo unsigned int, ya que con este último apenas se puede “manejar” poco más de seis segundos. Es por eso que, en mi respuesta a Shadoaru, le aconsejo el uso de unsigned long en lugar de int.
Así que, si fuera necesario controlar tiempos de más de seis segundos y medio, ¿tú lo que harías es declarar el array de tipo unsigned long? ¿Consumiendo así el doble de memoria en lugar de cuatro bytes más? (Pasaría de un array de 6 unsigned int, un total de 12 bytes, a un array de 6 unsingned long, un total de 24 bytes por array).
Mi “propuesta rápida” de “correción de estilo” a tu código, sin saber si funciona o no, y sólo sustituyendo el array por una simple estructura, sería esta:
struct Boton {
byte pinBoton;
byte pinLed;
bool estadoBoton : 1;
bool modoInterruptor : 1;
unsigned long contadorTiempoLuz;
unsigned long contadorDebounce;
} botonA = {2, 6, 0, 0, 0, 0},
botonB = {3, 7, 0, 0, 0, 0};
void setup() {
Serial.begin(9600);
DDRD =B11110010; //Pin 2 y 3 como INPUT
}
void loop() {
luz(botonA) ; // Usamos el paso por referencia
luz(botonA) ;
}
void luz(Boton &b) { // Usamos el paso por referencia
bool val = digitalRead(b.pinBoton);
if(b.estadoBoton != val && (millis() - b.contadorDebounce >= 150)) { //debounce
b.estadoBoton = val; //valor como pulsador
if(! b.estadoBoton ) {
b.modoInterruptor = ! b.modoInterruptor ; //valor como interruptor
if( b.modoInterruptor ) {
b.contadorTiempoLuz = millis() ;
}else{
Serial. println("El led del pin "+String(b.pinLed) +" ha estado encendido " + String(millis() - b.contadorTiempoLuz) +" milisegundos");
}
}
b.contadorDebounce = millis() ; //reiniciar tiempo debounce
}
digitalWrite(b.pinLed, b.modoInterruptor) ; //apagar encender led
}
Bueno, como no te gusta “escribir de más”, en la función luz en lugar de llamar el parámetro boton lo he llamado simplemente b. Después de todo, cada campo de la estructura nos deja claro de qué se trata. Así que nos podemos tomar esa licencia.
La estructura finalmente tiene un tamaño de 11 bytes (aprovechando los campos de bits para los dos bool). Los tiempos se controlan con unsigned long, así que podrán ser mayores a seis segundos y medio.
¡Ah! Otra cosa. Como he dicho, no sé si tu propuesta funciona o no, sólo he cambiado “el estilo” y corregido una única cosa. Mira que como tú bien dices es un tema harto repetido en el foro cada semana con mil ejemplos... y aún así siempre hay a quien se le escapa el uso correcto de los millis() a la hora de verificar si ha transcurrido el tiempo deseado, como es tu caso. No has de hacerlo así:
millis() >= arr[5] + 150
La forma correcta de hacerlo es así:
millis() - arr[5] >= 150
Busca en los foros o en Google, hay muchas explicaciones del porqué y del problema que se da cuando se desborda el contador de los millis(). Pero supongo que eso tú ya lo sabías y lo tenías más que controlado (nótese el sarcasmo).
Una vez más, ruego disculpes mi pedantería y si he sido grosero contigo. Te animo a que sigas ayudando en el foro. No todo el mundo lo sabe todo, y doy por hecho de que tú sabes mucho, así que espero que lo compartas poco a poco con todos.
Leyendo consultas y respuestas de este foro he descubierto que estaba equivocado en alguna que otra cosa. A la vez que he descubierto y aprendido cosas nuevas.
Los fallos nos pueden servir para aprender, los aciertos sólo nos sirven para confirmarnos lo que creemos saber.