Buenos días,
estoy intentado mediante un pulsador y una variable, ir acumulando valores en la variable mediante el pulsador para así ir cambiando de pantalla, pero me da error al sumar la variable y no se corregirlo.
#include <LiquidCrystalISP.h>
long randomNumber;
int Puls = 7;
int paso = 0;
LiquidCrystal lcd(13,12,5,4,3,2);
void setup() {
pinMode(Puls, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Inicio de sketch - secuencia de numeros aleatorios");
randomSeed(analogRead(A0));
lcd.begin(16, 2);
lcd.print("Pulsar el boton");
lcd.setCursor(0,1);
lcd.print("para empezar");
}
void loop() {
randomNumber = random(5, 20);
if (paso=1);{
lcd.clear();
Serial.print("El numero aleatorio es = ");
Serial.println(randomNumber);
lcd.setCursor(0, 0);
lcd.print("numero azar =");
lcd.setCursor(0, 01);
lcd.print(randomNumber);
delay(1000);
}
if (paso=2);{
lcd.clear();
lcd.print("Jugando...");
}
}
Se que tengo que implementar una función que por cada vez que pulse se sume 1, pero no se como ya que cuando lo hago cambia constantemente el valor calculado en el monitor serial
Tienes mal todas los if que haces con la variable paso. No es un signo igual (=) lo que has de usar, sino un doble signo igual (==). Además, el punto y coma (;) no va. En lugar de:
if (paso=1);{
Has de poner:
if (paso==1) {
La corrección la has de hacer en varios if que tienes mal.
Otro problema es que nada le dice a tu código que incremente paso, asi que no ejecutará ninguna condición porque siempre paso = 0.
Debes usar algun pulsador para que al presionarlo cambie de valor.
No suelo entrar mucho por el foro pero esta vez me ha llamado la atención la "no lógica" para el contador de tiempo usando millis
Si millis() retorna milisegundos no necesitas hacer MOD de 100 e ir contando decimas y segundos. Esto es cómo cuando en el cole convertías mililitros a centilitros, decilitros...
En vez de dividir sumar y consultar con if, tan sólo DIVIDE.
Aparte de los fallos que te han comentado hay otras cosillas pero de momento ve corrigiendo los fallos de sintaxis que te comenta @ignoranteAbsoluto, luego irás viendo los temas de la lógica que te comentamos el resto.
Paso 1. Explicar qué quieres hacer.
Paso 2. No hacer copiar y pegar de trozos de códigos (lo digo por los comentarios en inglés de cómo obtener el tiempo desde millis(), que por cierto está mal hecho.
Paso 3. Tabular correctamente para una lectura entendible del código (las {} son una locura)
Paso 4. Entender cuando van los final de línea -> ; (punto y coma)
Consejo. Ve por partes.
Primero haz un pulsador que funcione cómo un interruptor (Qué es diferente que modo pulsador).
Cuando el estado esté en true entonces aumentas tu variable (Entiendo que quieres hacer un menú)
indice_menu++;
Segundo, una vez esta parte te funcione haces un switch y con cada indice _menú muestras/dibujas la pantalla que quieras.
Tercero y último establece los tiempos bien dividendo millis() y no haciendo MOD (si no sabes que es mod búscalo antes de ir copiando código) Ejemplo normal:
3500 milisegundos / 1000 -> 3.5 segundos.
Quiero conseguir que mediante un pulsador se vaya pasando de unas pantallas a otras.
En El Paso 0, solo quiero que aparezca las letras de Pulsar el botón para empezar, que no se porque no aparece y directamente al pulsar pasa al paso 1, en el cual debe aparecer un número generado por el monitor serial, al volver a pulsar (pasamos al paso 2) deberá aparecer en pantalla el texto jugando… mientras se ejecuta un cronómetro el cual no aparecerá en pantalla, cuando nosotros creamos que ha pasado el número de segundos aparecido en la pantalla anterior, deberemos volver al pulsar para llegar al paso 3, el cual nos indicará el tiempo que ha pasado desde que se ha ejecutado el cronómetro hasta que lo hemos parado y la diferencia con el número generado por el monitor serial.
#include <LiquidCrystalISP.h>
long randomNumber;
const int Puls = 7;
int paso = 0;
LiquidCrystal lcd(13,12,5,4,3,2);
int horas = 0;
int minutos = 0;
int segundos = 0;
int decimas = 0;
long milisegundos = 0;
bool estado, estadoAnt;
int suma=1;
void setup() {
pinMode(Puls, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Inicio de sketch - secuencia de numeros aleatorios");
randomSeed(analogRead(A0));
lcd.begin(16, 2);
estado=digitalRead(Puls);
if (estado == HIGH && estadoAnt == LOW){
paso++;
}
estadoAnt = estado;
}
void loop() {
randomNumber = random(5, 20);
if (digitalRead(Puls) == LOW) //se ha oprimido el pulsador azul de subir variable
{
paso=paso+suma; //subir variable
while (digitalRead(Puls)==LOW) ; //esperar a que el pulsador se suelte
}
if (paso==0){
lcd.setCursor(0,0);
lcd.print("Pulsar el boton");
lcd.setCursor(0,1);
lcd.print("para empezar");
}
if (paso==1){
lcd.clear();
Serial.print("El numero aleatorio es = ");
Serial.println(randomNumber);
lcd.setCursor(0, 0);
lcd.print("numero azar =");
lcd.setCursor(0, 1);
lcd.print(randomNumber);
delay(1000);
}
if (paso==2){
lcd.clear();
lcd.print("Jugando...");
}
if(paso==3){
lcd.clear();
lcd.print(minutos);
lcd.print(":");
lcd.setCursor(3,0);
if(segundos < 10){
lcd.print("0");
}
lcd.print(segundos);
lcd.print(":");
lcd.setCursor(6,0);
lcd.print(decimas);
}
}
Quiero conseguir que mediante un pulsador se vaya pasando de unas pantallas a otras.
En El Paso 0, solo quiero que aparezca las letras de Pulsar el botón para empezar, que no se porque no aparece y directamente al pulsar pasa al paso 1, en el cual debe aparecer un número generado por el monitor serial, al volver a pulsar (pasamos al paso 2) deberá aparecer en pantalla el texto jugando… mientras se ejecuta un cronómetro el cual no aparecerá en pantalla, cuando nosotros creamos que ha pasado el número de segundos aparecido en la pantalla anterior, deberemos volver al pulsar para llegar al paso 3, el cual nos indicará el tiempo que ha pasado desde que se ha ejecutado el cronómetro hasta que lo hemos parado y la diferencia con el número generado por el monitor serial.
#include <LiquidCrystalISP.h>
long randomNumber;
const int Puls = 7;
int paso = 0;
LiquidCrystal lcd(13,12,5,4,3,2);
int horas = 0;
int minutos = 0;
int segundos = 0;
int decimas = 0;
long milisegundos = 0;
bool estado, estadoAnt;
int suma=1;
void setup() {
pinMode(Puls, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Inicio de sketch - secuencia de numeros aleatorios");
randomSeed(analogRead(A0));
lcd.begin(16, 2);
estado=digitalRead(Puls);
if (estado == HIGH && estadoAnt == LOW)
{
paso++;
}
estadoAnt = estado;
}
void loop()
{
randomNumber = random(5, 20);
if (digitalRead(Puls) == LOW)
{
paso=paso+suma;
while (digitalRead(Puls)==LOW) ;
}
if (paso==0)
{
lcd.setCursor(0,0);
lcd.print("Pulsar el boton");
lcd.setCursor(0,1);
lcd.print("para empezar");
}
if (paso==1)
{
lcd.clear();
Serial.print("El numero aleatorio es = ");
Serial.println(randomNumber);
lcd.setCursor(0, 0);
lcd.print("numero azar =");
lcd.setCursor(0, 1);
lcd.print(randomNumber);
delay(1000);
}
if (paso==2)
{
lcd.clear();
lcd.print("Jugando...");
}
if(paso==3)
{
lcd.clear();
lcd.print(minutos);
lcd.print(":");
lcd.setCursor(3,0);
if(segundos < 10)
{
lcd.print("0");
}
lcd.print(segundos);
lcd.print(":");
lcd.setCursor(6,0);
lcd.print(decimas);
}
}
Te repito, los pulsadores NO te pueden funcionar cómo quieres al poner este tipo de cosas:
while (digitalRead(Puls)==LOW) ;
Y sí, hay muchos más errores al tener los conceptos sin entender pero ve poco a poco. Primero haz que el botón funcione con un debounce y a partir de ahí podrás seguir.
Veo que cogiste el código de mi tutorial de botones y lo aplicaste bien, pero no lo entendiste del todo bien.
Cuando ves la pulsación incrementas el paso, pero no haces nada mas. Es en ese momento cuando tienes que actuar según el paso en el que estes: mostrar datos, guardar tiempo, calcular.
Mira como sería mas o menos:
void loop() {
randomNumber = random(5, 20);
if ( estado == digitalRead(7) ) {
temporizador = 0;
}
else if ( temporizador == 0 ) {
temporizador = millis();
}
else if ( millis() - temporizador > tiemporebote ) {
estado = !estado;
}
if ( anterior == HIGH && estado == LOW ) {
// ESTE CODIGO SOLO SE EJECUTA CUANDO PULSAS EL BOTON.
// Incrementas el paso.
paso = paso + 1;
// Si el paso es mayor que 3 lo ponemos a cero. Esto te sirve para empezar de nuevo.
if ( paso>3 ) paso = 0;
// Ahora vemos que tenemos que hacer en cada paso.
switch ( paso ) {
case 0:
// En el paso 0 mostramos solo información.
lcd.clear();
lcd.print(F("Pulsar el boton"));
lcd.setCursor(0,1);
lcd.print(F("Para empezar"));
break;
case 1:
// En el paso 1 generamos el número y lo mostramos.
lcd.clear();
randomNumber = random(5,20);
lcd.print(F("Numero azar"));
lcd.print(randomNumber);
break;
case 2:
// En el paso 2 guardamos en una variable de tiempo
// el valor actual de millis y mostramos jugando.
tjuego = millis();
lcd.clear();
lcd.print(F("Jugando.."));
case 3:
// En el paso 3 mostramos el tiempo que ha transcurrido
// desde el paso 2, para ello tenemos la variable guardada
// de antes.
// Te dejo como ejercicio que calcules el tiempo en minutos,
// segundo, o como quieras.
lcd.clear();
lcd.print(F("Tiempo:"));
lcd.print(millis()-tjuego));
break;
default: break;
}
}
anterior = estado;
}
Considero que esto es más simple si usamos un flag, es decir, un boolean para controlar los pasos y no entrar todo el rato en el switch() y hacemos un debounce sin cosas raras del pulsador, pero por supuesto para gustos colores.
#include <LiquidCrystal.h>
#define DEBOUNCE 30
#define PIN_BTN A5
LiquidCrystal lcd(2, 3, 4, 8, 9, 10, 11);
void setup() {
pinMode(PIN_BTN, INPUT);
randomSeed(analogRead(A0));
lcd.begin(16, 2);
mostrar_texto(0,0,"Inicio");
}
void loop(){
static byte paso;
static bool fue_pulsado, cambio_en_menu;
static unsigned long tiempo;
//debounce
if(millis() - tiempo >= DEBOUNCE){
if(digitalRead(PIN_BTN) ){
fue_pulsado = true; // se pulsó
}
else if(fue_pulsado){ // se suelta tras pulsar
paso = (paso+1 < 4) ? paso+1 : 0; // cambiamos el indice del menú
fue_pulsado = false;
cambio_en_menu = true; //permitimos que se cambie de pantalla (flag para no repetir acciones)
}
tiempo = millis();
}
if(cambio_en_menu){
static unsigned long tiempo_juego;
switch(paso) {
case 0:
lcd.clear();
mostrar_texto(0,0,"Pulsar el boton");
mostrar_texto(0,1,"para empezar");
break;
case 1:
lcd.clear();
mostrar_texto(0,0,"Numero aleatorio");
mostrar_texto(0,1, String(random(5, 20)) );
break;
case 2:
lcd.clear();
mostrar_texto(0,0,"Jugando");
tiempo_juego = millis();
break;
case 3:
lcd.clear();
mostrar_texto(0,0,"Tiempo:");
// colocar luego con centécimas, déccimas, segundos...
// millis() - tiempo_juego / 10
// ... / 100
// ... / 1000
mostrar_texto(0,1, String(millis() - tiempo_juego));
break;
}
cambio_en_menu = false;
}
}
void mostrar_texto(byte f, byte c, String str){
lcd.setCursor(f, c);
lcd.print(str);
}
#include <LiquidCrystalISP.h>
long randomNumber;
const int Puls = 7;
int paso = 0;
LiquidCrystal lcd(13,12,5,4,3,2);
int intervalo=0;
unsigned long tiempo1;
unsigned long tiempo2;
bool estado, estadoAnt;
int suma=1;
void setup() {
pinMode(Puls, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Inicio de sketch - secuencia de numeros aleatorios");
randomSeed(analogRead(A0));
lcd.begin(16, 2);
estado=digitalRead(Puls);
if (estado == HIGH && estadoAnt == LOW)
{
paso++;
}
estadoAnt = estado;
}
void loop() {
randomNumber = random(5, 20);
if (digitalRead(Puls) == LOW) //se ha oprimido el pulsador de subir variable
{
paso=paso+suma; //subir variable
while (digitalRead(Puls)==LOW) ; //esperar a que el pulsador se suelte
}
if ( paso>3 ) paso = 0;
switch ( paso ) {
case 0:
lcd.clear();
lcd.print(F("Pulsar el boton"));
lcd.setCursor(0,1);
lcd.print(F("Para empezar"));
break;
case 1:
lcd.clear();
randomNumber = random(5,20);
lcd.print(F("Numero azar"));
lcd.print(randomNumber);
break;
case 2:
tiempo1 = millis();
lcd.clear();
lcd.print(F("Jugando.."));
case 3:
tiempo2=millis();
intervalo=tiempo2-tiempo1;
intervalo/1000;
lcd.clear();
lcd.print(F("Tiempo:"));
if(intervalo)
break;
default: break;
}
}
}
He hecho un cambio teniendo en cuenta mi void setup, aunque no se si estará bien. Pero como podría hacer para que en el último paso se viera a cuántas décimas nos hemos quedado del número generado por el monitor serial sabiendo que el tiempo pasa desde que empieza el caso 2 hasta que termina, sabiendo que el número generado son segundos.