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)
;
}
}
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:
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);
}
}
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.
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.
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.
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
}
}
@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.
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.