Accion en VOID LOOP que se genere 1 sola vez

Saludos.

Estoy tratando de hacer un Codigo que me permita modificar la rom de una Commodore 64 pero bajo unos parametros definidos.

Es basico, el Arduino debe controlar dos senales a la ROM (LOW/HIGH), 2 LEDS (VERDE/AZUL) y enviar una senal a la linea de RESET (HIGH/LOW).

Todo seria manejado por un boton de 2 estados (ON/OFF)

Cuando el sistema se inicia si el Boton esta en ON envia una senal HIGH al pin A13 (LOW a A14) del ROM, enciende el LED Verde (Apaga Azul). Cuando el boton esta en OFF hace lo mismo pero a la inversa.

Ahora bien,

necesito que cada vez que cambie el estado del boton, despues de accionar los cambios arriba descritos, envie una senal a la linea RESET de la commodore, yo agregue eso pero tal como lo veo, voy a dejar la maquina reseteada eternamente porque esta en el loop.

Este es el codigo:

#define LED_Green 6
#define LED_Blue 7
#define BUTTON_PIN 8
#define A13 9
#define A14 10
#define RESET 11

//RUTINA PARA EL RESET
void resetC64() {
  digitalWrite(RESET, LOW);
  delay(200);
  digitalWrite(RESET, HIGH);


void setup() {
  pinMode(LED_Green, OUTPUT);
  pinMode(LED_Blue, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);
  pinMode (A13, OUTPUT);
  pinMode (A14, OUTPUT);
  pinMode (RESET, OUTPUT);
}
void loop() {
  if (digitalRead(BUTTON_PIN) == HIGH) {
    digitalWrite(LED_Green, HIGH);
    digitalWrite(LED_Blue, LOW);
    digitalWrite(A13, HIGH);
    digitalWrite(A14, LOW);
    resetC64();
    
  }
  
else {
    digitalWrite(LED_Green, LOW);
    digitalWrite(LED_Blue, HIGH);
    digitalWrite(A13, LOW);
    digitalWrite(A14, HIGH);
    resetC64()

  }
}

Como podria hacer para que cuando ocurra el cambio de estado se produzca el reset solo una vez?

Muchas gracias, apreciaria cualquier ayuda.

¿Lo que en realidad necesitas es accionar si el botón cambia de OFF a ON?

Si, no me exprese bien.

El boton en realidad va ser un selector de estado.

Si esta en una posicion enciende led verde, manda senal a pin A13 y luego corre la rutina de Reset 1 sola vez hasta que la posicion del boton cambie..
Si esta en la otra posicion invierte lo anterior (apaga led verde, enciende azul, A13 pasa a low y A14 a high) y corre la rutina de RESET 1 sola vez hasta que la posicion del boton cambie.

Moderador
Te envío un privado para que hagas correcciones a tu titulo

Respondo tu consulta
Nunca hagas esto

 if (digitalRead(BUTTON_PIN) == HIGH) {

justamente hará la operacion en cada loop

debes usar dos variables auxiliares.

// en globales define
int estado, estadoAnt = 0;
int accion = 0;

en el loop

void loop() {
     estado = digitalRead(BUTTON_PIN);
     if (estado && !estadoAnt) {
        accion = 1 -accion;
        if (accion) {
          digitalWrite(LED_Green, HIGH);
          digitalWrite(LED_Blue, LOW);
          digitalWrite(A13, HIGH);
          digitalWrite(A14, LOW);
          resetC64();
      } else {
          digitalWrite(LED_Green, LOW);
          digitalWrite(LED_Blue, HIGH);
          digitalWrite(A13, LOW);
          digitalWrite(A14, HIGH);
          resetC64()
     }
     estadoAnt = estado;
  }

Esta parte va asi? sin condicion?

Si lo corro asi, al enceder no se manda ninguna señal. Ambas A13 y A14 estan low.

Eso es una simplificacion de:

Si no entendí mal quieres que se ejecute el reset cuando se produzca un cambio del estado del botón.
Obviamente al encender el sistema no se ha producido aun ningún cambio, si necesitas fijar un estado inicial para A13 y A14 o incluso un reset inicial hazlo en el "setup".

Ok, no se si estoy haciendo una burrada, pero sirvio fijando estados al inicio, basicamente repeti el loop en el setup:

#define LED_Green 6
#define LED_Blue 7
#define BUTTON_PIN 8
#define A13 13
#define A14 10
#define RESET 11

int estado, estadoAnt=0;
int accion=0;

void resetC64() {
  digitalWrite(RESET, LOW);
  delay(200);
  digitalWrite(RESET, HIGH);
}

void setup() {
  pinMode(LED_Green, OUTPUT);
  pinMode(LED_Blue, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);
  pinMode (A13, OUTPUT);
  pinMode (A14, OUTPUT);
  pinMode (RESET, OUTPUT);

if (digitalRead(BUTTON_PIN) == HIGH) {
    digitalWrite(LED_Green, HIGH);
    digitalWrite(LED_Blue, LOW);
    digitalWrite(A13, HIGH);
    digitalWrite(A14, LOW);
    resetC64();
  }
  else {
    digitalWrite(LED_Green, LOW);
    digitalWrite(LED_Blue, HIGH);
    digitalWrite(A13, LOW);
    digitalWrite(A14, HIGH);
    resetC64();
  }
}

void loop() {
     estado = digitalRead(BUTTON_PIN);
     if (estado && !estadoAnt) {
        accion = 1 -accion;
        if (accion) {
          digitalWrite(LED_Green, HIGH);
          digitalWrite(LED_Blue, LOW);
          digitalWrite(A13, HIGH);
          digitalWrite(A14, LOW);
          resetC64();
      } else {
          digitalWrite(LED_Green, LOW);
          digitalWrite(LED_Blue, HIGH);
          digitalWrite(A13, LOW);
          digitalWrite(A14, HIGH);
          resetC64();
     }
     estadoAnt = estado;
  }
}

Lo que pasa ahora es que a veces al accionar el switch, el arduino pareciera que no capta el cambio.

Aqui hice la prueba simulada:

Muchas Gracias @gonpezzi en realidad me has ayudado un monton!!!!!

Lo unico que aun no entiendo es como puedo manejar el switch. Cuando lo muevo para "llevarlo" a LOW, en realidad estoy quitandole el HIGH al pin 8. Como puedo hacer que el Arduino detecte con el switch ese cambio a LOW?

No no estas haciendo ninguna burrada, has inicializado el sistema según como se encuentre el interruptor al encender y para mi esta correcto.

Ni yo con el puñetero Wokwi. He quitado todo los componentes menos el interruptor ,he añadido un serial print de la variable estado y no se consigue una lectura clara, siempre se que queda atascado en HIGH.
Para mi el código funciona, deberías pasar a un montaje real o a otro simulador como el Tinkercad por ejemplo.

Ya descubri lo que le pasaba a tu simulacion con el Wokwi. tenias mal colocada la instruccion:

Tu loop ha de quedar asi:

void loop() {
     estado = digitalRead(BUTTON_PIN);
     if (estado && !estadoAnt) {
        accion = 1 -accion;
        if (accion) {
          digitalWrite(LED_Green, HIGH);
          digitalWrite(LED_Blue, LOW);
          digitalWrite(A13, HIGH);
          digitalWrite(A14, LOW);
          resetC64();
      } else {
          digitalWrite(LED_Green, LOW);
          digitalWrite(LED_Blue, HIGH);
          digitalWrite(A13, LOW);
          digitalWrite(A14, HIGH);
          resetC64();
     }    
  }
   estadoAnt = estado;
}

Cambialo y funcionara la simulacion.

Si, el estadoAnt ==estado tenia que estar un nivel abajo, muchas gracias.

Algo que no entiendo es el estado del pin 11.

Si ves el codigo ese pin es el que hace el RESET, y su rutina es:

void resetC64() {
  digitalWrite(RESET, LOW);
  delay(500);
  digitalWrite(RESET, HIGH);

No entiendo por que esta trabajando al reves, deberi estar siempre HIGH y hacer el LOW para reset y volver a HIGH

La rutina de reset está bien, pone el pin en LOW durante 500 mseg y lo vuelve a poner en HIGH hasta que la vuelva a llamar y se repita en ciclo.

Lo que ocurre es que por alguna extraña razón, en la simulación, los LED están trabajando con la polaridad invertida.

Agrego: Ya encontré el problema.

Hay un puente entre el pin 5V y el pin GND adyacente (aclaré la captura para que sea más evidente el puente errado).

Evidentemente el simulador tiene un "bug" y en lugar de marcar el cortocircuito asigna 5V al carril GND.

Debes borrar ese puente y, obviamente, polarizar correctamente los LED (salvo el RGB, que está correcto).
Respecto al RGB debes seleccionar "cathode" en lugar de "anode" como pin común.

Listo! Fui descuidado ahi! Muchas Gracias. En teoria ahora si funciona todo como debe. Estoy esperando me llegue un Pro Mini para hacer la prueba fisica.

Un millon de Gracias a todos! En realidad aprecio la dedicacion y el tiempo!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.