Need help with nested code

I make a code that you have 3 wires called correcto1, correcto2 and correcto3, you need to "cut them" in certain order to light up a green led, if you don't "cut them" in the correct order, it will turn on a red led. My problem is, whatever i do the correct order or not, it always turn on the red led.

i'm using arduino uno

my code have other 3 wires called fallo1, fallo2 and fallo3. if you "cut" one of them, It will turn on the red led

const int fallo1 = 2;
const int fallo2 = 3;
const int fallo3 = 4;
const int correcto1 = 6;
const int correcto2 = 7;
const int correcto3 = 8;
const int ledError = 10;
const int ledOk = 11;

void setup() {
  pinMode(fallo1, INPUT);
  pinMode(fallo2, INPUT);
  pinMode(fallo3, INPUT);
  pinMode(correcto1, INPUT);
  pinMode(correcto2, INPUT);
  pinMode(correcto3, INPUT);
  pinMode(ledError, OUTPUT);
  pinMode(ledOk, OUTPUT);
}

void loop() {
  int estado_fallo1 = digitalRead(fallo1);
  int estado_fallo2 = digitalRead(fallo2);
  int estado_fallo3 = digitalRead(fallo3);
  int estado_correcto1 = digitalRead(correcto1);
  int estado_correcto2 = digitalRead(correcto2);
  int estado_correcto3 = digitalRead(correcto3);


  // Comprobar si alguno de los pines de fallo está en estado LOW
  if (estado_fallo1 == LOW || estado_fallo2 == LOW || estado_fallo3 == LOW) {
    digitalWrite(ledError, HIGH);
    digitalWrite(ledOk, LOW);  // Apagar el LED "ledCorrecto" si hay un fallo
  } else {
    digitalWrite(ledError, LOW);
  }



  if (estado_correcto1 == LOW && (estado_correcto2 == HIGH && estado_correcto3 == HIGH)) {
    if (estado_correcto1 == LOW && estado_correcto2 == LOW && estado_correcto3 == HIGH) {
      if (estado_correcto1 == LOW && estado_correcto2 == LOW && estado_correcto3 == LOW) {
        digitalWrite(ledOk, HIGH);
        digitalWrite(ledError, LOW);
        while (1)
          ;
      }
    }
  }
  if (estado_correcto1 == HIGH && estado_correcto2 == LOW || estado_correcto1 == HIGH && estado_correcto3 == LOW) {
    digitalWrite(ledError, HIGH);
    while (1)
      ;
  }
}

In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.

Use the </> icon from the ‘posting menu’ to attach the copied sketch.


Always show us a good schematic of your proposed circuit.
Show us a good image of your ‘actual’ wiring.
Give links to components.

Hello daclica

Post the schematic, too.

What are the differences between the input signals 'fallo' and 'correcto'?

done

Where ?

I can´t see a schematic.

now i uploaded the correct image

There seems to be a misunderstanding about "if".
Your three nested "if" condition is used in same time.
So your green led is turned on when all three conditions are satisfied at the same time.
But both estado_correcto2 and estado_correcto3 cannot be HIGH and LOW at the same time.

There are many ways to achieve this function.
One of them use global variables to save how far someone has cleared.
like below:


bool is_correct1_cutted = false;
bool is_correct2_cutted = false;
bool is_correct3_cutted = false;
void loop() {
  if (estado_correcto1 == LOW && (estado_correcto2 == HIGH && estado_correcto3 == HIGH))
  {
    is_correct1_cutted = true;
  }
  if (is_correct1_cutted && (estado_correcto2 == LOW && estado_correcto3 == HIGH))
  {
    is_correct2_cutted = true;
  }
  ...

This is a makeshift approach. There are cooler approaches.
For more advanced writing, you can try using a "state machine".

1 Like

thx, i'm gonna try

seems like a bomb defuser simulation

after each if statement, all the wire conditions need to be reread. and then both the conditions for the proper and one of several possible improper wires need to be checked.

consider

const byte PinWires [] = { A1, A2, A3 };
const int  Nwire = sizeof(PinWires);

const byte PinLeds [] = { 12, 13 };
enum { LedBad = 0, LedGood = 1 };

enum { Off = HIGH, On = LOW };

const byte Seq [] = { 1, 0, 2 };
int idx = 0;

byte wireLst [Nwire];

// -----------------------------------------------------------------------------
void
loop (void)
{
    // monitor for changes
    for (int n = 0; n < Nwire; n++)  {
        byte wire = digitalRead (PinWires [n]);

        // check for the next wire cut
        if (wireLst [n] != wire)  {
            wireLst [n] = wire;
            delay (50);         // debounce

            // wrong wire?
            if (Seq [idx] != n)  {
                digitalWrite (PinLeds [LedBad], On);
                while (1)
                    ;
            }

            // last wire?
            if (Nwire <= ++idx)  {
                digitalWrite (PinLeds [LedGood], On);
                while (1)
                    ;
            }
        }
    }
}

void
setup (void)
{
    Serial.begin (9600);

    for (int n = 0; n < Nwire; n++)  {
        pinMode (PinWires [n], INPUT_PULLUP);
        wireLst [n] = digitalRead (PinWires [n]);
    }
    
    for (unsigned n = 0; n < sizeof(PinLeds); n++)  {
        pinMode      (PinLeds [n], OUTPUT);
        digitalWrite (PinLeds [n], Off);
    }
}
1 Like

it works, now I'm gonna use it to brute force the other options to the red led

Good.
The experience of making something that works is a great motivation for the next step.
So to brute force is not bad, but I would like to recommend you rewriting if it worked.
In many cases, the initial source code is not understandable even by the person who wrote it weeks later, so I try to write comments and make the names of functions and variables easier to understand.
It would be good to change the process flow as indicated by @gcjr .
Knowing the various methods will help you with your next craft.

comments are in spanish and i'm spanish jajajaja, but i want first finish it

too much advanced for me sorry, i didn't even know where to put the inputs and outputs

You appear to have your wires connected between the INPUT pins and +5V. If you do that you must have pull-down resistors on the INPUT pins or the inputs will float when you 'cut' the wire.

I would change the pins to INPUT_PULLUP to enable the internal pull-up resistors. Then, connect the 'wires' between the pins and GROUND. When you 'cut' the wire, the pull-up resistor will cause the pin to read HIGH. Until you 'cut' the wire the GROUND will cause the pin to read LOW.

1 Like

Yes. The logic should require the cutting of a wire, or in a test the opening of a slide switch.

It would also make sense to check if a previously cut wire is reconnected.

It would be nice if there some logic to reset and recycle the challenge, like waiting until all the wires were connected again (or their proxy slide switches closed).

The sketch will see bouncing, at least if slide switches are used.

I haven't checked to see if a wires cutter results in a glitchy digitalRead() indication. :expressionless:

a7

Here is how I would do it:

const int fallo1 = 2;
const int fallo2 = 3;
const int fallo3 = 4;
const int correcto1 = 6;
const int correcto2 = 7;
const int correcto3 = 8;
const int ledError = 10;
const int ledOk = 11;

void setup()
{
  pinMode(fallo1, INPUT_PULLUP);
  pinMode(fallo2, INPUT_PULLUP);
  pinMode(fallo3, INPUT_PULLUP);
  pinMode(correcto1, INPUT_PULLUP);
  pinMode(correcto2, INPUT_PULLUP);
  pinMode(correcto3, INPUT_PULLUP);

  digitalWrite(ledError, LOW);
  pinMode(ledError, OUTPUT);

  digitalWrite(ledOk, LOW);
  pinMode(ledOk, OUTPUT);
}

void loop()
{
  // Store the states of the input pins (0=intact, 1=cut) in the
  // bottom 6 bits of an integer variable.
  int state = digitalRead(fallo1);
  state = (state << 1) | digitalRead(fallo2);
  state = (state << 1) | digitalRead(fallo3);
  state = (state << 1) | digitalRead(correcto1);
  state = (state << 1) | digitalRead(correcto2);
  state = (state << 1) | digitalRead(correcto3);

  if (state == 0b000111)  // Complete!  All three 'correcto' wires cut
  {
    digitalWrite(ledOk, HIGH);
  }
  else if (state == 0b000000      // Nothing cut
           || state == 0b000100   // Only correcto1 cut
           || state == 0b000110)  // Only correcto1 and correcto2 cut
  {
    // Valid state. Keep going.
  }
  else
  {
    // Invalid state!  One of the 'fallo' wires was cut OR a 'correcto'
    // wire was cut out of turn.
    digitalWrite(ledOk, LOW);
    digitalWrite(ledError, HIGH);
    while (1) {}  // Stuck here until reset
  }
}
2 Likes

OIC…

Three wires that must be cut in order, and three wires that must not be cut.

I prefer real bombs where all you have to do is cut the red wire. :wink:

a7

@johnwasser nice, nerds would jump to direct port reading.

Your solution allows cutting and uncutting the next wire as many times as one might, as long as it is left cut before moving to the next wire in order.

a7

it's suposed to, if you cut a wire that it's suposed to no be cutted, game over and restart the program

I'm a nerd, but I value portable code more than unnecessary speed improvements. I think loop() is already running thousands of times per second.

I figured there was no advantage to be gained and thus no point in ever 'un-cutting' a wire. If you got it wrong you're already dead and if you got it right, the only valid move is to leave it cut.

1 Like