How to run if/else statement only once?

I’ve attached an IR sensor and also a 360 full servo motor onto the Arduino.
This is the code I have so far:

#include <Servo.h>
 
Servo myservo;
int pos = 0;
int i;
int IRpin=0;

void setup() {
myservo.attach(52); //servomotor attached to pin 52//
pinMode(IRpin,INPUT); //IR sensor attached to A0//

Serial.begin(9600);
  }   
void loop () {
  i=analogRead(IRpin); //reading of the IR sensor//
Serial.println(i); //Printing the i value every 20ms//
delay(20);
  {
 if(i>50 && i<=100)
  myservo.write(107);
  delay(1000);
  myservo.write(90); //If IR sensor reads between 50 and 100, SWservo moves at 107 for 1 second then stops//

 if(i>100 && i<=150)
  myservo.write(120);
  delay(1000);
  myservo.write(90); //If IR sensor reads between 100 and 150, SWservo moves at 120 for 1 second then stops//
 }}

QUESTION:

When the value of the IR sensor reads between 50 and 100,
I want the motor to turn 107 with the duration of 1 second.
But I want this action to ONLY HAPPEN ONCE until the reading becomes between 100 and 150. (or outside of the 50~100)
At the moment the servo moves 107 when the IR reads between 50 and 100. But the servo moves 107 again after this action i is still between 50 and 100.

Code that will at least compile will get you better answers.

You need to look at the state change detection example. The value is in one range, or it isn't. When it becomes in range and when it becomes out of range are identical to a pin becoming HIGH or becoming LOW.

I’m not sure if I interpreted what you want to do correctly, but here’s my guess.

#include <Servo.h>

Servo myservo;
int pos = 0;
int i;
int IRpin = 0;

void setup()
{
  myservo.attach(52); //servomotor attached to pin 52//
  pinMode(IRpin, INPUT); //IR sensor attached to A0//

  Serial.begin(9600);
}
void loop ()
{
  i = analogRead(IRpin); //reading of the IR sensor//
  Serial.println(i); //Printing the i value every 20ms//
  delay(20);

  if (i > 50 && i <= 100)
  {
    myservo.write(107)
    delay(1000);
  }
  else if (i > 100 && i <= 150)
  {
    myservo.write(120);
    delay(1000);
  }
  myservo.write(90);

}

Does this produce the desired behaviour?

I suggest you name your variables with meaningful names, having ‘i’ for sensor value is weird, usually you leave i, j, k for ‘for’ statements. Same for the values 50, 100, 107; maybe you should have:

const int minLevel = 50;
const int midLevel = 100;
const int highLevel = 150;
const int servoStep = 107;

This subtle change will allow you to adapt your code for further changes, so you don’t have to manually find every 50 and see if it’s the one you need to change for a new minimum sensor value.

Anyways, for your question

Didn’t have tome to test it, but try this:

bool moveServo = true; // outside void loop()


if(sensorValue >= 50 && sensorValue <= 100)
{
    if (moveServo){
        myservo.write(107);
        moveServo = false;
    }
}
if (sensorValue >= 100 && sensorValue <= 150)
    moveServo = true;

He means literally take a look at this example.

And instead of feeding ‘buttonState’ directly into the logic below it, take your analog input and convert it to digital with one statement.

if (i > 50 && i <= 100)
{
  buttonState = HIGH;
}else
{
buttonState = LOW;
}

Obviously your variable names will be your own, and you could just use a Boolean value.
You would likely add one more Boolean to make sure that it isn’t triggered a second time.