Problem to control 2 LEDs with 1 sensor

Hello all,
this is my first post on this forum, therefore please excuse me for posting some mistakes. I'm new to Arduino programming and when I wrote my first sketch I encountered some problems that I would like to solve in this way. My device consists of a sensor that is connected to pin A0 and it provides signals HIGH and LOW. Also, the pins A1 and A2 want to connect two LEDs. When A0 is HIGH, LED 1 lights 2 seconds then goes off and remains so even if A0 is still HIGH. The second phase of A0 is LOW, when the LED 2 flashes and then turns off after 2 seconds even if A0 is still LOW. In the code I wrote myself a LED 1 remains on as long as A0 is HIGH, the LED 2 remains on as long as A0 is LOW. I do not know where is wrong, so please give me an explanation on this issue. Thank you

// These constants won't change:
const int sensorPin = A0;    // pin that the sensor is attached to
const int ledPin1 = A1;       // pin that the LED1 is attached to
const int ledPin2 = A2;       // pin that the LED2 is attached to

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  // initialize the sensor pin as an input:
  pinMode(sensorPin, INPUT);
}

void loop() {
  // read the value of the sensor:
  int sensorValue = digitalRead(sensorPin);
  
  // turn on the LED1:
  if (sensorValue == HIGH) {
    digitalWrite(ledPin1, HIGH);
    delay(2000);
    digitalWrite(ledPin1, LOW);
  }
  
   // turn on the LED2:
  if (sensorValue == LOW) {
    digitalWrite(ledPin2, HIGH);
    delay(2000);
    digitalWrite(ledPin2, LOW);
  }
 }

How does loop() know what the state was last time it went through? If you don't remember the previous state, you can't know if the state has changed.

At the moment you are doing what is known as "level" triggering, where you look at if it is high or low. You need "edge" triggering, where you are looking for transitions between low and high, and high and low.

Thank you for your reply. I understand what you say, but unfortunately I do not know how to do this. It seems I do not know enough programming language. I have much to learn.

Just before you exit the loop() you save the current value in a variable called something like lastValue. Then next time round the loop you can use this lastValue and compare it with the current value, only do stuff when they are different. That is edge triggering.

My device consists of a sensor that is connected to pin A0 and it provides signals HIGH and LOW.

Why are you connecting a digital device to an analog pin? It would make more sense to connect it to a digital pin.

const int sensorPin = A0;    // pin that the sensor is attached to
  pinMode(sensorPin, INPUT);
  int sensorValue = digitalRead(sensorPin);

So, you are using the analog pin as a digitial pin. Why not actually use a digital pin?

You're absolutely right. I intend to use an analog pin as digital pin as the code given to me is just a part throughout the scetch that will be longer control a stepper motor and LCD. These two hardware use almost all digital pins, reason for wanting to do this. Since I did not realize yet how to do it, so you have to temporarily abandon the idea until I better document this.Thank you all for advice given.

I solved this problem as follows:

// These constants won't change:
const int sensorPin = A0;    // pin that the sensor is attached to
const int ledPin1 = A1;       // pin that the LED1 is attached to
const int ledPin2 = A2;       // pin that the LED2 is attached to
int val;

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  // initialize the sensor pin as an input:
  pinMode(sensorPin, INPUT);
}

void loop() {
  // read the value of the sensor:
val = digitalRead(sensorPin); 

 // turn on the LED1:
 if (val == HIGH) {
    digitalWrite(ledPin1, HIGH);
    delay(500);
    do digitalWrite(ledPin1, LOW); 
    while(digitalRead(sensorPin) == HIGH);
  } 
 else {
    digitalWrite(ledPin1, LOW);
   }
  // turn on the LED2:
  if (val == LOW) {
    digitalWrite(ledPin2, HIGH);
    delay(500);
    do digitalWrite(ledPin2, LOW); 
    while(digitalRead(sensorPin) == LOW);
   } 
  else {
    digitalWrite(ledPin2, LOW);
   }
}

I do not know if this is the best solution, but for me it works. If you think I should change something in this code please let me know.

    do digitalWrite(ledPin1, LOW); 
    while(digitalRead(sensorPin) == HIGH);

Please explain what you understand this block of code to be doing. Particularly the need to turn the pin off over and over.

I think you really need to look at detecting transitions. Record, in a global variable, at the end of loop(), the current state of the switch as the previous state. Then, after getting the current state of the switch, at the top of loop(), determine if the current state is the same as the previous state. If not, a transition has occurred, from pressed to released or from released to pressed. Do stuff if a transition has occurred, and is the appropriate kind (to pressed or to released).

In my understanding this block of code initially put ledPin1 LOW, then check sensorPin state, and if it is HIGH, will keep ledPin1 on LOW. As I said earlier in this topic, what I want from this code is the following:
case 1: if sensorPin is HIGH, to light LED1 for a period of time, then put LOW LED1 and it stays LOW until sensorPin will be again HIGH.
case 2: if sensorPin is LOW, LED2 to light for a period of time, then go LOW LED2 and it stays LOW until sensorPin will be again LOW.
In short, I want sensorPin to manage two coils of a latching relay.
It is very possible for me to complicate things a bit, but for now, I do not have another method to control the relay coils.

I tested this code block combined with another one that controls a stepper motor and I did not obtained the desired result. More specifically, my code, blocking the the program flow and stepper no longer work. In conclusion my problem still remains unresolved. I would appreciate if anyone has an idea about this issue.

I tested this code block combined with another one that controls a stepper motor and I did not obtained the desired result

And we can see neither the code nor the result obtained.

In my understanding this block of code initially put ledPin1 LOW, then check sensorPin state, and if it is HIGH, will keep ledPin1 on LOW.

You don't need to keep putting a pin low or high. Once it is set to one level it will stay there until you put it to another level.

my code, blocking the the program flow

That is because it is stuck in an unnecessary loop. - Note this is not the loop() function.

If you want help then post what you have, say what it does, say what you want it to do.

If you want help then post what you have, say what it does, say what you want it to do.

I have nothing concrete yet. What I do is to drive a hobby turntable. This block of code that I discussed, I want to order two relay coils of a latch (LED1 and LED2 represented) by the signal read from a sensor. In order not to damage these two coils the voltage must be short. For this reason, if is possible, I would like the two coils have a timed feed. Another option would be to make a timer with an IC 555, but still I prefer the first option.

Hi b97joe,
I am very much new to all this too so im only suggesting you try this someone might correct me but for my understanding you need a flag(lastState). You need this because your code is checking if the pin is high, setting the led to high, waiting 2 seconds,turning led off. but before you see the led going off the program has got back to the start of the loop and if the pin is still high it is turning the led on again. the same problem is happening when it is low with the other led.

So basically you need the flag to stop this section of your loop from running a second time until something changes with pin A0 have a look at my adaption of your code and let me know if this helps.

// These constants won't change:
const int sensorPin = A0;    // pin that the sensor is attached to
const int ledPin1 = A1;       // pin that the LED1 is attached to
const int ledPin2 = A2;       // pin that the LED2 is attached to
int lastState;
int currentState;
void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  // initialize the sensor pin as an input:
  pinMode(sensorPin, INPUT);
}

void loop() {
  // read the value of the sensor:
  int sensorValue = digitalRead(sensorPin);
  
  int currentState=sensorValue;//store current value of A0 pin
  //check if state has changed since last run though loop
  if(currentState != lastState){
  // turn on the LED1:
  if (sensorValue == HIGH) {
    digitalWrite(ledPin1, HIGH);
    delay(2000);
    digitalWrite(ledPin1, LOW);
  }
  
   // turn on the LED2:
  if (sensorValue == LOW) {
    digitalWrite(ledPin2, HIGH);
    delay(2000);
    digitalWrite(ledPin2, LOW);
  }
  lastState=currentState;//set lastState equal to currentState to prevent loop 
  //running until pin A0 value changes
 }
}

Hi slavetosound,
well thank you both for adaptation made ??and the explanations on the subject. Now I understand how it works this flag. I tested the code you changed and works very well, but with one small exception found during the test, namely that when the code starts and the sensor is LOW, the LED should be HIGH, and not do this.
Now, I try to combine this code with another, to see whether the code can work with other code or not. I was thinking to do this by pasting the two codes and both side by side to form a single sketch. I try to do this by putting the constants together, content from both void setup () together, and the contents of both void loop () together. Is it fair to do it this way?

b97joe:
Hi slavetosound,
well thank you both for adaptation made ??and the explanations on the subject. Now I understand how it works this flag. I tested the code you changed and works very well, but with one small exception found during the test, namely that when the code starts and the sensor is LOW, the LED should be HIGH, and not do this.
Now, I try to combine this code with another, to see whether the code can work with other code or not. I was thinking to do this by pasting the two codes and both side by side to form a single sketch. I try to do this by putting the constants together, content from both void setup () together, and the contents of both void loop () together. Is it fair to do it this way?

Probably best you post the code to make easier to check what you mean.
The easiest way to fix the bug I can see is to set laststate to 10 or some value that will make it different to current state for the first run through so

int laststate=10;

Replacing

int laststate ;

At the start of the code I pasted
That should ensure the code sets LEDs correctly at the start

Thank you. Now the code works very well.

Probably best you post the code to make easier to check what you mean.

I have nothing concrete yet, this question was one of principle. I have not written any code yet. Being the beginning of this activity are many things unknown to me, in conclusion I have many questions. Some of these are relevant, while others may seem foolish to start. For the second category to display little tolerance please.
To be more explicit on the question asked earlier to take the following examples:

const// These constants won't change:
 int sensorPin = A0;    // pin that the sensor is attached to
const int ledPin1 = A1;       // pin that the LED1 is attached to
const int ledPin2 = A2;       // pin that the LED2 is attached to
int lastState;
int currentState;
void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  // initialize the sensor pin as an input:
  pinMode(sensorPin, INPUT);
}

void loop() {
  // read the value of the sensor:
  int sensorValue = digitalRead(sensorPin);
  
  int currentState=sensorValue;//store current value of A0 pin
  //check if state has changed since last run though loop
  if(currentState != lastState){
  // turn on the LED1:
  if (sensorValue == HIGH) {
    digitalWrite(ledPin1, HIGH);
    delay(2000);
    digitalWrite(ledPin1, LOW);
  }
  
   // turn on the LED2:
  if (sensorValue == LOW) {
    digitalWrite(ledPin2, HIGH);
    delay(2000);
    digitalWrite(ledPin2, LOW);
  }
  lastState=currentState;//set lastState equal to currentState to prevent loop 
  //running until pin A0 value changes
 }
}

Code that we discussed, and the following code examples taken from the Arduino, which will put the LED on pin 13, when the button is actuated to pin 2.

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);    
}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {    
    // turn LED on:    
    digitalWrite(ledPin, HIGH);  
  }
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

After combining them I got this code that is functional:

// These constants won't change:
const int sensorPin = A0;    // pin that the sensor is attached to
const int ledPin1 = A1;       // pin that the LED1 is attached to
const int ledPin2 = A2;       // pin that the LED2 is attached to
int lastState=10;
int currentState;

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  // initialize the sensor pin as an input:
  pinMode(sensorPin, INPUT);
  
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT); 
}

void loop() {
  // read the value of the sensor:
  int sensorValue = digitalRead(sensorPin);
  
  int currentState=sensorValue;//store current value of A0 pin
  //check if state has changed since last run though loop
  if(currentState != lastState){
  // turn on the LED1:
  if (sensorValue == HIGH) {
    digitalWrite(ledPin1, HIGH);
    delay(2000);
    digitalWrite(ledPin1, LOW);
  }
  
   // turn on the LED2:
  if (sensorValue == LOW) {
    digitalWrite(ledPin2, HIGH);
    delay(2000);
    digitalWrite(ledPin2, LOW);
  }
  lastState=currentState;//set lastState equal to currentState to prevent loop 
  //running until pin A0 value changes
 }
 // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {    
    // turn LED on:    
    digitalWrite(ledPin, HIGH);  
  }
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

I wanted to know if this kind of combination of codes is normal or whether it should do otherwise.
I ask this question because the sketch that I intend to do for railway turntable contains two sensors, keyboard control, a stepper motor, an LCD, and all that, I want to make one code to test it separately, then to unite all these codes.
If my way of approaching this problem is unusual, I request someone to correct me.

Like I mentioned before I am new to this as well so someone else would be better to answer your question to approach than me.

But personally I see no problem with doing it this way.

One suggestion I would make. put the different operations into functions to make it easier to read rather than straight into the loop. like below.

// These constants won't change:
const int sensorPin = A0;    // pin that the sensor is attached to
const int ledPin1 = A1;       // pin that the LED1 is attached to
const int ledPin2 = A2;       // pin that the LED2 is attached to
int lastState=10;
int currentState;

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  // initialize the sensor pin as an input:
  pinMode(sensorPin, INPUT);
  
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT); 
}

void loop() {
 readSensor(); 
 readPushButton();
}



void readPushButton(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {    
    // turn LED on:    
    digitalWrite(ledPin, HIGH);  
  }
     else {
     // turn LED off:
     digitalWrite(ledPin, LOW);
     }
}

void readSensor(){
  // read the value of the sensor:
  int sensorValue = digitalRead(sensorPin);
  int currentState=sensorValue;//store current value of A0 pin
  //check if state has changed since last run though loop
 if(currentState != lastState){
     // turn on the LED1 if HIGH
     if (sensorValue == HIGH) {
     digitalWrite(ledPin1, HIGH);
     delay(2000);
     digitalWrite(ledPin1, LOW);
     }
        // turn on the LED2 if LOW
        if (sensorValue == LOW) {
        digitalWrite(ledPin2, HIGH);
        delay(2000);
        digitalWrite(ledPin2, LOW);
        }
        
 lastState=currentState;//set lastState equal to currentState to prevent loop 
 //running until pin A0 value changes
 }

}

Hope this helps a little.

Don't forget that those delays are going to make the system unresponsive when they're called.
This may or may not be a problem.

Thank you for your advice. I will certainly follow them.