IF Loops and timers

Yes, I know I am lame and it has been far too long since I programmed. That said, I am trying to remember how to write a simple loop. Online tutorials are not working for me. I have this in WOWKI simulator and the LED immediately comes on, I don't get an ON serial print, and the LED doesn't turn off with switch changes (nor do i get an OFF serial print).

INTENT: If the accessory switch is off and the door is closed, then the LED should turn on. If either input changes the LED should turn off. I also want to add a 20 second timer to count down if the LED is ON (but that can be later once I get the basic ON/OFF loop working.


int ACC = digitalRead(25); // Accessory key position
int DOOR_JAMB = digitalRead(12); // door open or close


void setup() {
  pinMode(4, OUTPUT);
}

void loop() {
  if (ACC == LOW && DOOR_JAMB == LOW) { // If ACC is off and door is closed
          digitalWrite(4, HIGH); // Turn dome light on
      Serial.println("Dome light is on...");
      // 20 second counter in here eventually
    } else {
      digitalWrite(4, LOW); // Turn dome light off
      Serial.println("Dome light is off");
    }
    }

You don’t read your digitals outside of the code, those two lines do nothing.

Look at some examples.

These code lines will read the input pins once, before setup() runs. Nothing in your code reads them again, so if the pins change, it will not be detected.

I guess you were thinking that reading the variable later will read the pins again. It doesn't work like that, unfortunately.

You are reading the state of 2 pins at the start of the sketch and assigning the states to 2 variables

In loop() you test the values of the 2 variables and execute different code depending on the values. However, as the values of the variables never changes the same code is always executed

If you want the code in loop() to react to the state of the 2 pins then you must read their states in loop() using digitalRead()

If you did it this way, it would work like you were expecting:

#define ACC digitalRead(25)
#define DOOR_JAMB digitalRead(12)

void setup() {
  pinMode(4, OUTPUT);
}

void loop() {
  if (ACC == LOW && DOOR_JAMB == LOW) { // If ACC is off and door is closed
      digitalWrite(4, HIGH); // Turn dome light on
      Serial.println("Dome light is on...");
      // 20 second counter in here eventually
    } else {
      digitalWrite(4, LOW); // Turn dome light off
      Serial.println("Dome light is off");
    }
  }

The reason it works this way and not the way you wrote it is that this way, every time your code says "AAC", the expression "digitalRead(25)" gets substituted. So this way, the pins get read again each place ACC is used.

1 Like

Thank you sir. Based on what the other responses are, I am only reading the inputs once and before the loops, so their status will never change. So I think i need to read the input pins inside the loop before my IF statement. Correct?

Yes. The code I suggested would achieve that. Did you try it?

I did and it did not.

Try adding pinMode()s for the two input pins, and a Serial.begin() for good measure

I'm not very familiar with WOKWI and can't explain why it does not work. It would work in a real circuit.

I got this to turn on the LED but not serial write ??


int ACC =25;
int DOOR_JAMB = 12;
int DOME = 4;

void setup() {
  pinMode(4, OUTPUT);
  pinMode(25, INPUT);
  pinMode(12, INPUT);
}

void loop() {
  if (digitalRead(ACC) == LOW && digitalRead(DOOR_JAMB) == LOW) { // If ACC is off and door is closed
      digitalWrite(DOME, HIGH); // Turn dome light on
      Serial.println("Dome light is on...");
      // 20 second counter in here eventually
    } else {
      digitalWrite(DOME, LOW); // Turn dome light off
      Serial.println("Dome light is off");
    }
  }

I suspect that

Add a Serial.begin();

Could it have something to do with the fact that the #defines are expanded at compile time so the pins may not be initialised at that time ?

indeed!


int ACC =25;
int DOOR_JAMB = 12;
int DOME = 4;

void setup() {
  pinMode(4, OUTPUT);
  pinMode(25, INPUT);
  pinMode(12, INPUT);
  Serial.begin(115200);
}

void loop() {
  if (digitalRead(ACC) == LOW && digitalRead(DOOR_JAMB) == LOW) { // If ACC is off and door is closed
      digitalWrite(DOME, HIGH); // Turn dome light on
      Serial.println("Dome light is on...");
      // 20 second counter in here eventually
    } else {
      digitalWrite(DOME, LOW); // Turn dome light off
      Serial.println("Dome light is off");
    }
  }

What is connected to pin 4? What is the dome light's voltage and current?

Just looking for the HIGH output right now. The output will eventually go to an N-FET to pass ground to the dome light.

True

They never are at compile time. Compiling is done on the PC. The pins are on the Arduino. At least that's how things work in the real world!

But simulators are always an approximation of the real world, so who knows what might happen on a simulator.

It’s compiled in the same way. It’s not like you have a c++ interpreter…

1 Like

Is that how WOKWI works? It compiles the C++ into... something-code and then models executing that?

If that's the case then my idea should have worked, but @burrism reported that it didn't, but the code in post #11 worked (except for Serial).

To the best of my knowledge, when you run a simulation, Wokwi executes the compiled firmware (e.g., .hex or .elf files) within a software emulator that mimics the behavior of the target microcontroller.

you mean his wokwi in post 8 ?

there are many mistakes in that code like counters never being reset or && TURN_COUNTER > 90000 that will never be true...