3 floors elevator electric

Hello, I have an Arduino project which is a three-storey electric elevator.
The electronic parts are the ir sensor, number three, as well as three buttons, also h bridge and dc motor. I have a problem, which is how to connect the electronic parts to each other without overlapping the condition, meaning if I press the second button, it moves to the third floor as soon as the second ir sensor works, the motor stops And if you press the third button, the motor works, as soon as the third ir sensor works, the motor stops, as well as the first, and so on. At the same time, the ball is repeated. Please help please.

int enA=5;
int in1=0;
int in2=1;

int ir_1=2;
int ir_2=3;
int ir_3=4;

int btn_1=10;
int btn_2=11;
int btn_3=12;

 Int A = 2;
 Int B = 3;
 Int F = 4;
 Int D = 5;
 Int E = 6;
 Int G = 7;


void setup() {
  pinMode (A, OUTPUT);
  pinMode (B, OUTPUT);
  pinMode (F, OUTPUT);
  pinMode (D, OUTPUT);
  pinMode (E, OUTPUT);
  pinMode (G, OUTPUT);


  pinMode(enA,OUTPUT);
  pinMode(in1,OUTPUT);
  pinMode(in2,OUTPUT);

  pinMode(ir_1,INPUT);
  pinMode(ir_2,INPUT);
  pinMode(ir_3,INPUT);
  
  pinMode(btn_1,INPUT);
  pinMode(btn_2,INPUT);
  pinMode(btn_3,INPUT);
}

void loop() {
 b1=digitalRead(btn_1);
 b2=digitalRead(btn_2);
 b3=digitalRead(btn_3);
 

  if(digitalRead(btn_1)==1){
     if(digitalRead(ir_3)==1){
       motor_Fade();
     }else if(digitalRead(ir_1)==0){
      motor_off();
     }
  }
   if(digitalRead(btn_3)==1){
     if(digitalRead(ir_1)==1){
       motor_back_Fade();
     }else if(digitalRead(ir_3)==0){
      motor_off();
     }
  }
      if(digitalRead(btn_2)==1){
     if(digitalRead(ir_1)==1){
       if(digitalRead(ir_3)==1){
          motor_Fade();
       }else if(digitalRead(ir_1)==0){
        motor_back_Fade();
       }else{
        motor_off();
       }
     }
  }

}
void motor_Fade(){
  digitalWrite(in1,1);
  digitalWrite(in2,0);

  analogWrite(enA,200);
  delay(400);
}
void motor_back_Fade(){
  digitalWrite(in1,0);
  digitalWrite(in2,1);

  analogWrite(enA,200);
  delay(400);
}
void motor_off(){
 
  digitalWrite(in1,0);
  digitalWrite(in2,0);

  delay(400);
}

I didn't study your code but you need to think-through the logic. The software has to "remember" which buttons have been pushed (if any) and it needs to know where it is and which direction it's going, and it has to clear the button-press after that floor has been serviced.

In a real elevator for people you also need to know if the doors are open or closed and you need a mechanical safety mechanism so you're not relying on electricity or electronics if the cable breaks (or something).

There are some other standard features too but I might not remember them all... Somebody has to press a button to "call" the elevator and there are two buttons (up & down) except at the top or bottom floor. And when the doors open there has to be a light showing if the elevator is going-up or going-down before the person steps-in.

And delay() is "bad" because the processor isn't doing anything during the delay-time so it can't read a button push during the delay time. You can use millis() timers in place of a delay (see the Blink Without Delay Example).

1 Like

Bro my project is a project that I presented to the university, so the elevator is just a miniature version. I only want to loop the condition, repetition and non-interference in connecting the buttons and the IR sensor, and the rest will become easy for me.

there are several obvious problems

your code checks for button pressed by comparing the pin to 1.
button switches are typically connected between a pin and ground and there is a pull-up resistor on the pin (INPUT_PULLUP) so that the pin is HIGH (1) when not pressed and LOW (0) when pressed.

looks like the monitoring of the IR sensors only occurs while the button is being pressed.

the code should recognize when the button is pressed, going from HIGH to LOW and set a target floor and possibly start the elevator moving toward that floor. other code, independent of a button press should check the IR sensor corresponding to the floor associated with the button pressed using some state variable and stop the elevator when the IR sensor indicates the floor is reached

there are of course better approaches. disk drives used the "elevator algorithm" to maintain direction instead of reacting immediately to floor requests

1 Like

So bro can you modify the code??

prefer not to post code i haven't tested. you'll have to remove the #ifdef MYHWs that i used to add code changes for my hardware

#undef MyHW
#ifdef MyHW
const byte ir1 = 6;
const byte ir2 = 7;
const byte ir3 = 8;

const byte enA = 10;
const byte in1 = 11;
const byte in2 = 12;

const byte butPins [] = { A1, A2, A3 };

unsigned long msecLst;
unsigned long msec;

// -------------------------------------
#else
const byte ir1 = 2;
const byte ir2 = 3;
const byte ir3 = 4;

const byte enA = 5;
const byte in1 = 0;
const byte in2 = 1;

const byte butPins [] = { 10, 11, 12 };
#endif

// -------------------------------------
#define N_BUT   sizeof (butPins)
byte butState [N_BUT];

const byte motorPins [] = { in1, in2, enA };
const byte irPins    [] = { ir1, ir2, ir3 };

enum { Off = HIGH, On = LOW };

int level;
int levelRqt;

char s [80];

// -----------------------------------------------------------------------------
// scan buttons and return index value when pressed
#define ButNone   -1
int
chkButtons ()
{
    for (unsigned n = 0; n < sizeof (butPins); n++)  {
        byte but = digitalRead (butPins [n]);

        if (butState [n] != but)  {
            butState [n] = but;

            delay (10);     // debounce

            if (On == but)
                return n;
        }
    }
    return ButNone;
}

// -----------------------------------------------------------------------------
// simply use sign of pwm to set direction and turn off motor if pwm is zero
#define MotorSpd     200
void
motor (
    int  pwm)
{
    sprintf (s, "motor: pwm %d", pwm);
    Serial.println (s);

    if (0 > pwm) {
        digitalWrite (in1, HIGH);
        digitalWrite (in2, LOW);
    }
    else {
        digitalWrite (in1, LOW);
        digitalWrite (in2, HIGH);
    }

    analogWrite (enA, pwm);

   // simulate moving away from all levels
#ifdef MyHW
    msecLst = msec;

   for (unsigned n = 0; n < sizeof (motorPins); n++)
        digitalWrite (irPins [n], Off);
#endif
}

// -----------------------------------------------------------------------------
// don't have enough inputs on my hardware
// use this routine to set the IR input pin after a 2 sec delay
#ifdef MyHW
void
irSim ()
{
    msec  = millis ();

    byte irInp = digitalRead (irPins [levelRqt]);

#if 0
    sprintf (s, "irSim: levelRqt %d, irInp %d, %ld %ld",
            levelRqt, irInp, msec, msecLst);
    Serial.println (s);
#endif

    if (Off == irInp && (msec - msecLst) > 2000)  {
        digitalWrite (irPins [levelRqt], On);
        Serial.println ("irSim, set pin");
    }

    delay (100);
}
#endif

// -----------------------------------------------------------------------------
void
loop ()
{
    // check for but, set level if different and start motor is proper direction
    int but = chkButtons ();
    if (ButNone != but)  {
        levelRqt = but;
        if (level < levelRqt)
            motor (MotorSpd);
        else if (level > levelRqt)
            motor (-MotorSpd);

        sprintf (s, "loop: levelRqt %d, level %d, but %d", levelRqt, level, but);
        Serial.println (s);
    }

    // simulate IR input
#ifdef MyHW
    irSim ();
#endif

    // if not at requested level, check IR input, turn off motor and set level
    if (level != levelRqt && On == digitalRead (irPins [levelRqt]))  {
        motor (0);
        level = levelRqt;

        sprintf (s, "loop: levelRqt %d, level %d", levelRqt, level);
        Serial.println (s);
    }
}

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

    // configure but pins and capture current state
    for (unsigned n = 0; n < sizeof (butPins); n++)  {
        pinMode (butPins [n], INPUT_PULLUP);
        butState [n] = digitalRead (butPins [n]);
    }

    // IR pins are inputs
    //  but for MyHW are outputs that can set and and read back as inputs
    for (unsigned n = 0; n < sizeof (irPins); n++)  {
#ifdef MyHW // may be redundant
        pinMode      (irPins [n], OUTPUT);
        digitalWrite (irPins [n], Off);
#else
        pinMode (irPins [n], INPUT_PULLUP);
#endif
    }

    // configure motor pins as outputs
    for (unsigned n = 0; n < sizeof (motorPins); n++)
        pinMode (motorPins [n], OUTPUT);
}
1 Like

The way you are asking and how you adress people saying "bro"
gives me the impression that you want other people to modify your code until the code works as intended.

You wrote it is a university-project. So you are a grownup student that has finished secondary school?

From a university student it is expected to do most of the work on his own.
This working on your own includes asking experts where to find information to learn on your own what is missing.

So some of the keywords are:

detecting state-change (of the button-press and floor-sensors)

how state-machines work

how to do serveral things at once in your code.

So do some research on your own on these terms

Whenever you have a new code-version post the complete sketch
describe the codes behaviour and ask specific questions.

In this way you will receive answers and will learn.
You should be able to answer questions about the functionality of the code you are using. If your professor is asking "what does happen if the sensor on the second floor has a malfunction?

You should be able to answer this question straight away without having to test it and to re-read the code again and do a guessing.

best regards Stefan

1 Like

Thank you, frankly, for the first time I see such code, because they did not teach me at the university such things, and I did not see such things on the Internet. I thought that I had not learned anything. Unfortunately, the code didn't work, but I got some ideas from it

My brother, do not forget that I am in Iraq and the education here is below zero, so most of the things that I learned were not from the university, but I searched for them myself. As for the Arduino, I am still a beginner, so I am still learning.

At the same time, I don't know a lot of things, but I don't have the time now to learn them all because of my studies and my continuous duties....!

If you refer to the code gcjr posted. This code is sophisticated and needs a lot fot time to understanding how it works as it makes use of a lot of advanced things. Well gcjr himself is a professional software-developer for gcjr it's a "piece of cake"

best regards Stefan

1 Like

I got a headache from the amount of instructions out there, new to me..:pleading_face:

As soon as you start to clearly specifiy what "instructions" you mean you will speed up things a lot.

Always posting too short postings with too less information just slows your progress down because there is an extra round of asking back and giving another answer.

So please take 3 minutes time to write down a posting with at least 5 sentences that clearly specify what you mean.

Take another 5 minutes to decide which part about programming your elevator code you want to learn first. In the end you will be faster doing it in small steps.

best regards Stefan

1 Like

Do you mean to write a new post explaining all the details?

No.
If you answer. Be specific enough that it is easy to understand what you mean.
Little words like "it" "this" etc. do not clearly specify and just provoque asking back what do you mean by "it" by "this" etc.

1 Like

Your 3-stage elevator-project has more than one "part".

  • detecting a button-press and remember the buttonpress
  • detecting elevator has reached a certain level and remembering it
  • non-blocking timing to be able to detect a button-press while the elevator is moving

With which part do you want to begin ?

1 Like

We start by pressing the button and then find out which button we pressed and then find out which type of ir sensor works, for example we pressed the second button and the first ir sensor works, the motor will move until the second ir sensor works, then the motor stops

If you have difficulties to write in english use google translate.
There is a high chance that it can translate from and into your native language.

If you go on to post such poor worded and short postings it will take 1000 postings until your code will work

هناك احتمال كبير أن تتم ترجمتها إلى لغتك الأم.

إذا واصلت نشر مثل هذه المنشورات ذات الكلمات الرديئة والقصيرة ، فسوف يستغرق الأمر 1000 رسالة حتى يعمل الرمز الخاص بك
'iidha kunt tuajih sueubat fi alkitabat biallughat al'iinjiliziat , fastakhdim mutarjim jujil.
hunak aihtimal kabir 'an tatima tarjamatuha 'iilaa lughatik al'umu.
'iidha wasalat nashr mithl hadhih almanshurat dhat alkalimat alradiyat walqasirat , fasawf yastaghriq al'amr 1000 risalat hataa yaemal alramz alkhasu bik

As a first step you should describe in normal words what shall happen.
You have to analyse the whole movement and identify each change of anything.

You named the variables name1, name2, name3
So there is position 1, position 2, position 3 of the elevator-cabin

Let's assume your elevator-cabin is in absolute correct position 1
This means ir-sensor1 is switched to state "cabineIsInPosition"

You press button of position 2
what does change ?
Button2 changes from unpressed to pressed.
depending on the elevator-cabin beeing in position 1 or position 3 the motor must move in opposite directions

So there has to be a check at which position is the elevator-cabin
depending on the position switch on motor up or down
short after switching the motor on the ir-sensor1 will switch from state "cabineDetected" to "NoCabine"

Your code has to check if the elevator-cabin makes ir-sensor2 change to state "cabineDetected"

If you only use three ir-sensors your code must move the motor until the cabine has moved a little bit too high which means ir-sensor2 is in state "NoCabine"
and then move back downwards until ir-sesnor detects "cabineDetected"
otherwise the motor would stop as soon as the top of the cabin switches ir-sensor2
and then the cabin is just a little bit above position1

You have to do such an analysis as the

first step

before starting to write code

best regards Stefan

first is understanding what an elevator should do.

an elevator in a large building is often constantly moving between floors and multiple buttons may be being pressed while moving. so each button press is a request that is queued and the elevator will only stop at that floor as it moves past, not go directly to that floor. hopefully you also understand the elevator algorithm

but in your case you simply want the elevator to move directly to a floor when the button is pressed (no queueing)

in the code i posted, the 1st thing loop() does is check for a button press (INPUT_PULLUP, check for change of state).

it does 2 things when pressed: it sets the level requested and starts the motor in the direction of the floor.

the other (3rd) thing loop() does is check if it's at the requested level and stops the motor. first it compares the current level to the requested level to see if it needs to check and if it does, it also checks if the IR sensor for the requested floor is active indicating that the elevator is at that floor. when it is, it stops the motor and sets level to the request floor which prevents further checking.

unlike your code, there's a single motor functions which is passed a speed argument. If the speed < 0 it moves the motor in reverse and if 0, the motor simply stops. no need for 3 separate motor functions.

loop() also calls irSim() because i don't have your hardware (i have a Multifunction Shield).

the state of an pin configured as OUTPUT can be read using digitalRead() to read it's state (HIGH/LOW). instead of configuring the IR pins as inputs i configure them as OUTPUTs and irSIm() sets the pin corresponding to the requested floor after 2 seconds simulating the travel time between floors and the IR sensor actually sensing the elevator at that floor. this allows code you need to read the IR pins when they are connected to IR sensors.

throughout the code are several #ifdef MyHW which enables code i needed to simulate your hardware and to use pins available on the Multifunction shield. the #undef at the top disables that code inside those #ifdef/#endif blocks but i may have made a mistake. you should understand the code and can remove those blocks.

hopefully with this explanation you have a better understanding of what the code is doing and why and can make it work on your hardware assuming your hardware is wired correctly.

with any hardware, the first thing to do is make sure it does what you require and as a firmware developer we often write test code. so

  • can a button press be detected?
  • can the motor be driven in both directions?
  • does the motor move in the desired direction?
  • do the IR sensors become active when the elevator is at the floor for that sensor?
  • are the IR sensors active HIGH or LOW?

i just went through this step with a robotics team when they tried using motor encoders and found they were wired to the wrong inputs or didn't work. they needed to disassemble parts of the robot to correct the wiring.

good luck

I did a similar thing last summer because I was bored. I don't know if it might be helpful, but here's the code I wrote for it:

/* A 28BYJ-48 Stepper Motor is controlled by a ULN2003 Driver to turn a winch/spool to raise/lower a lift/elevator carriage between three floors. 
 * Wiring diagram for the stepper motor and driver can be found here: https://lastminuteengineers.com/wp-content/uploads/arduino/Wiring-28BYJ48-Stepper-Motor-with-ULN2003-Driver-and-Arduino.png
 * Additional information can be found at https://lastminuteengineers.com/28byj48-stepper-motor-arduino-tutorial/
 * 



A 28BYJ-48 Stepper Motor is controlled by a ULN2003 Driver to turn a winch/spool to raise/lower a lift/elevator carriage between three floors. 



*/

//Includes the Arduino Stepper Library
#include <Stepper.h>

// Defines the number of steps per rotation
const int stepsPerRevolution = 2038;

// Creates an instance of stepper class
// Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

// constants won't change. They're used here to set pin numbers:
const int buttonPinA = 2;     // the number of the pushbutton pin A - Sends lift to floorA
const int buttonPinB = 3;     // the number of the pushbutton pin B - Sends lift to floorB
const int buttonPinC = 4;     // the number of the pushbutton pin B - Sends lift to floorC
const int buttonPinD = 12;    // the number of the pushbutton pin B - Manually lowers the lift for the purpose of resetting. 
const int ledPinA =  5;       // the number of the LED pin that indicates that the lift is on it's way to floorA
const int ledPinB =  6;       // the number of the LED pin that indicates that the lift is on it's way to floorA
const int ledPinC =  7;       // the number of the LED pin that indicates that the lift is on it's way to floorA
const int blinkPin = 13;      // the number of the LED pin that blinks on/off to show the loop is running
const int floorA = 0;         // the notional location of FloorA, the Ground Floor.
const int floorB = 5500;      // the notional location of FloorB, the Middle Floor, halfway up the building.
const int floorC = 11000;     // the notional location of FloorC, the Top Floor.
const int comfortLevel = 30;  // the coefficient of passenger comfort. Higher numbers minimize jerky starts/stops by slowing the motor when the lift car is near it's origin/destination.

// variables will change:
int buttonStateA = 0;           // variable for reading the pushbutton status
int buttonStateB = 0;           // variable for reading the pushbutton status
int buttonStateC = 0;           // variable for reading the pushbutton status
int buttonStateD = 0;           // variable for reading the pushbutton status
int turnSpeed = 10;             // variable to store the current motor speed
int destination;                // variable for where the lift is headed
int location = 0;               // where the lift currently is
int journey;                    // variable for the remaining steps between lift location and destination
int travelled = 0;              // how far the lift has travelled on it's current journey
byte ledState = HIGH;           // variable for the current state of the blinking LED
unsigned long previousMillis = 0;
int i;
unsigned long serialUpdate;

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPinA, OUTPUT);
  pinMode(ledPinB, OUTPUT);
  pinMode(ledPinC, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(buttonPinA, INPUT);
  pinMode(buttonPinB, INPUT);
  pinMode(buttonPinC, INPUT);
  pinMode(buttonPinD, INPUT);
  Serial.begin(9600);    // Only needed for testing, commented out in final version.

}

void loop() {
  // delay(200);
  checkButtons();
  showIndicatorLights();
  rotate();
  toggleLight();
  outputSerial();
}

void checkButtons() {
  buttonStateA = digitalRead(buttonPinA);
  buttonStateB = digitalRead(buttonPinB);
  buttonStateC = digitalRead(buttonPinC);
  buttonStateD = digitalRead(buttonPinD);
}

void showIndicatorLights() {
  if (buttonStateA == HIGH) {
    digitalWrite(ledPinA, HIGH);
    digitalWrite(ledPinB, LOW);
    digitalWrite(ledPinC, LOW);
    destination = floorA;
    travelled = 20;
    journey = (destination - location);
  }
  if (buttonStateB == HIGH) {
    digitalWrite(ledPinB, HIGH);
    digitalWrite(ledPinA, LOW);
    digitalWrite(ledPinC, LOW);
    destination = floorB;
    travelled = 20;
    journey = (destination - location);
  }
  if (buttonStateC == HIGH) {
    digitalWrite(ledPinC, HIGH);
    digitalWrite(ledPinA, LOW);
    digitalWrite(ledPinB, LOW);
    destination = floorC;
    travelled = 20;
    journey = (destination - location);
  }
  if (buttonStateD == HIGH) {
    digitalWrite(ledPinC, LOW);
    digitalWrite(ledPinA, LOW);
    digitalWrite(ledPinB, LOW);
    destination = location-1;
    travelled = 20;
    journey = (destination - location);
  }
}



void rotate() {
  // first, determine the appropriate speed. If the lift is just starting out (low 'travelled') or just arriving (low 'journey') then it should move more slowly.
  // for passenger comfort, the lift speed is in proportion to how near it's origin/destination it is.
  // the slowest it can go is 1, the fastest is 15. Between those it goes at the top speed of 15.
  turnSpeed =  max(1, min (abs(journey) / comfortLevel ,  min (travelled / comfortLevel , 15))); // Set the lift speed to a minimum of 1, maximum of 15, and the lowest out of journey/20 or travelled/20
  if (buttonStateD == HIGH) {turnSpeed = 15; }
  myStepper.setSpeed(turnSpeed);
  if (journey > 0) {
    myStepper.step(1);
    journey = journey - 1;
    location = location + 1;
    travelled = travelled + 1;
  }
  if (journey < 0) {
    myStepper.step(-1);
    journey = journey + 1;
    location = location - 1;
    travelled = travelled + 1;
  }
}

void outputSerial() {
  if (millis() - serialUpdate >= 100) {
    serialUpdate = millis();     // save the last time you updated the serial
    Serial.print("Location: ");
    Serial.print(location);
    Serial.print(" Destination: ");
    Serial.print(destination);
    Serial.print(" Journey: ");
    Serial.print(journey);
    Serial.print(" Speed: ");
    Serial.print(turnSpeed);
    Serial.print(" Travelled: ");
    Serial.println(travelled);
  }
}

void toggleLight() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= 1000) {
    previousMillis = currentMillis;     // save the last time you blinked the LED
    if (ledState == LOW) {     // if the LED is off turn it on and vice-versa:
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(13, ledState);  // set the LED with the ledState of the variable.
  }
}