Arduino elevator using the side kick basic kit servo

Hello guys,

i'm an engineering student and i'm working on my project for digital systems. I chose the project of an elevator using a servomotor. I connected the servomotor to a wheel to make sure i can lift over a certain height. I am using pushbuttons for 3 different heights (0°,90° and 180°) Here are my problems:

  • When i want to go from 0 -> 180, the motor first accelerates to 90 and then rotates with the speed i chose to 180 (delay of 30ms).

  • When i want to go grom 0 -> 90, the motor first accelerates to 180 and then rotates with the speed i chose to 90.

  • When i want to go from 180 -> 0, the motor first accelerates to 90 and then rotates with the speed i chose to 0.

  • When i am on a certain level and i push the button of that level again, it first moves a bit (up or down) and then just goes to that same level.

Here's my code : (PS: verdiepingNul, verdiepingEen and verdiepingTwee are respectively the pushbuttons of 0,90 and 180 degrees)

#include <Servo.h>

//Alles voor het display
int a = 6;
int b = 5;
int c = 3;
int d = 2;
int e = 1;
int f = 7;
int g = 8;

//Alles voor de drukknoppen
int verdiepingNul = 14;
int verdiepingEen = 15;
int verdiepingTwee = 16;

//Alles voor de servo
Servo myServo;
int pos=0;

void setup() {

 pinMode(a, OUTPUT);
 pinMode(b, OUTPUT);
 pinMode(c, OUTPUT);
 pinMode(d, OUTPUT);
 pinMode(e, OUTPUT);
 pinMode(f, OUTPUT);
 pinMode(g, OUTPUT); 

 pinMode(verdiepingNul, INPUT);
 pinMode(verdiepingEen, INPUT);
 pinMode(verdiepingTwee, INPUT);

 myServo.attach(12);
 myServo.write(0);
}

void displayDigit(int digit){
  if(digit ==0){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,HIGH);
    digitalWrite(g,LOW);
  }
  else if(digit ==1) {
    digitalWrite(a,LOW);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,LOW);
    digitalWrite(e,LOW);
    digitalWrite(f,LOW);
    digitalWrite(g,LOW);
  }
  else if(digit ==2){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,LOW);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,LOW);
    digitalWrite(g,HIGH);
  }
}

  
  void loop() 
  {

    
    //Om naar verdiepingNul te gaan.
    if (digitalRead(verdiepingNul)==HIGH){
      if(pos=90){
        for(pos=90; pos>=0; pos-=1){
          myServo.write(pos);
          delay(30);
        }
      }
      else if(pos = 180) {
        for(pos=180; pos>=90; pos-=1){
        myServo.write(pos);  
        delay(30);
        }
        for(pos=90; pos>=0; pos-=1){
          myServo.write(pos);
          delay(30);
        }
      }
  }
      
    
    //Om naar verdiepingEen te gaan.
    if (digitalRead(verdiepingEen)==HIGH){
      if(pos=0){
        for(pos=0; pos<=90; pos+=1){
          myServo.write(pos);
          delay(30);
          
        }
      }
      else if(pos = 180) {
        for(pos=180; pos>=90; pos-=1){
          myServo.write(pos); 
          delay(30);
        }
      }
    }

    //Om naar verdiepingTwee te gaan.
    if(digitalRead(verdiepingTwee)==HIGH){
      if(pos=0){
        for(pos=0; pos<=90; pos+=1){
          myServo.write(pos);
          delay(60);
        }
        for(pos=90; pos<=180; pos+=1){
          myServo.write(pos);
          delay(30);
        }
      }
      else if(pos = 90) {
        for(pos=90; pos<=180; pos+=1){
        myServo.write(pos); 
        delay(30);
        }
      }
    }

    if(myServo.read()==0){
      displayDigit(0);
    }

    else if(myServo.read()==90){
      displayDigit(1);
    }

    else if(myServo.read()==180){
      displayDigit(2);
    }
    
  }

Thanks for the help :slight_smile:

PS: the displayDigit() function is to display the level on a 7-segment display.

Two problems in only two lines...

    if (digitalRead(verdiepingNul)==HIGH){

if(pos=90){

The more serious problem is the assignment operator on the second line. I think you meant equality. (==)

The first line tells you that the button IS pressed, not that it just became pressed. All the delays in your program are hiding this problem as nobody will hold their finger on the button that long, but it's going to be a problem if you try to do anything more complex.

Thanks for the reply!

But how could i fix this that it would be like a kind of memory spot that memorizes when a button was pressed. Because in a further step, i want to make a register that when you press 1 and 2 it will first go to 1 and then to 2.

I also changed the code, but when i do 1 action now e.g. i go from 0 to 90, it does it with the delay, but when i want to do another action, it doesn't respond.

I would implement an elevator program with almost complete separation between the buttons and the motor movement.

I would have an array with an entry for each floor let's call it floorRequested[] (and give it one more space than there are floors to make the numbering simple). When a button for floor3 is pressed it sets the floorRequested[3] to true. This means that every floor could be requested at once.

There needs to be other variables to record the current floor number and whether the elevator is going up or down

Then your code that moves the motor needs to start at the current floor and work through the floorRequested[] array in the current direction. If the next floor is requested, move to it and clear the request. If it is going up and gets to the top, or if there is no higher floor requested, change the direction to down.

My code in loop() would probably be as simple as

void loop() {
  checkButtons();
  moveMotor();
}

...R

So @Robin2, you say that i should actually make 2 different arrays : floorRequested[] , upOrDown[] ?

You don't need an array for upOrDown. It could be a char variable holding the values 'U' or 'D'

...R

@Piring, you sent me a PM about this. But you have not responded here since my last Reply.

...R

Hey guys,

i changed the = to ==. The motor seems to operate at the speed inserted by the delay(30). But now, when i try to do a second action , the motor doesn't respond and it just stays at the level.

#include <Servo.h>

//Alles voor het display
int a = 6;
int b = 5;
int c = 3;
int d = 2;
int e = 1;
int f = 7;
int g = 8;

//Alles voor de drukknoppen
int verdiepingNul = 14;
int verdiepingEen = 15;
int verdiepingTwee = 16;

//Alles voor de servo
Servo myServo;
int pos=0;

void setup() {

 pinMode(a, OUTPUT);
 pinMode(b, OUTPUT);
 pinMode(c, OUTPUT);
 pinMode(d, OUTPUT);
 pinMode(e, OUTPUT);
 pinMode(f, OUTPUT);
 pinMode(g, OUTPUT); 

 pinMode(verdiepingNul, INPUT);
 pinMode(verdiepingEen, INPUT);
 pinMode(verdiepingTwee, INPUT);

 myServo.attach(12);
}

void displayDigit(int digit){
  if(digit ==0){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,HIGH);
    digitalWrite(g,LOW);
  }
  else if(digit ==1) {
    digitalWrite(a,LOW);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,LOW);
    digitalWrite(e,LOW);
    digitalWrite(f,LOW);
    digitalWrite(g,LOW);
  }
  else if(digit ==2){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,LOW);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,LOW);
    digitalWrite(g,HIGH);
  }
}

  
  void loop() 
  {

    
    //Om naar verdiepingNul te gaan.
    if (digitalRead(verdiepingNul)==HIGH){
      if(pos == 90){
        for(pos=90; pos>=0; pos-=1){
          myServo.write(pos);
          delay(30);
        }
      }
      else if(pos == 180) {
        for(pos=180; pos>=0; pos-=1){
        myServo.write(pos);  
        delay(30);
        }
      }
  }
      
    
    //Om naar verdiepingEen te gaan.
    if (digitalRead(verdiepingEen)==HIGH){
      if(pos == 0){
        for(pos=0; pos<=90; pos+=1){
          myServo.write(pos);
          delay(30);
          
        }
      }
      else if(pos == 180) {
        for(pos=180; pos>=90; pos-=1){
          myServo.write(pos); 
          delay(30);
        }
      }
    }

    //Om naar verdiepingTwee te gaan.
    if(digitalRead(verdiepingTwee)==HIGH){
      if(pos == 0){
        for(pos=0; pos<=180; pos+=1){
          myServo.write(pos);
          delay(30);
        }

      }
      else if(pos == 90) {
        for(pos=90; pos<=180; pos+=1){
        myServo.write(pos); 
        delay(30);
        }
      }
    }

    if(myServo.read()==0){
      displayDigit(0);
    }

    else if(myServo.read()==90){
      displayDigit(1);
    }

    else if(myServo.read()==180){
      displayDigit(2);
    }
    
  }

Robin2:
@Piring, you sent me a PM about this. But you have not responded here since my last Reply.

...R

Yes, i'm sorry...
@Robin2

Hi guys, me again,

The motor seems to operate at the speed inserted by the delay(30). But now, when i try to do a second action , the motor doesn't respond and it just stays at the level i chose with the pushbutton.

#include <Servo.h>

//Alles voor het display
int a = 6;
int b = 5;
int c = 3;
int d = 2;
int e = 1;
int f = 7;
int g = 8;

//Alles voor de drukknoppen
int verdiepingNul = 14;
int verdiepingEen = 15;
int verdiepingTwee = 16;

//Alles voor de servo
Servo myServo;
int pos=0;

void setup() {

 pinMode(a, OUTPUT);
 pinMode(b, OUTPUT);
 pinMode(c, OUTPUT);
 pinMode(d, OUTPUT);
 pinMode(e, OUTPUT);
 pinMode(f, OUTPUT);
 pinMode(g, OUTPUT); 

 pinMode(verdiepingNul, INPUT);
 pinMode(verdiepingEen, INPUT);
 pinMode(verdiepingTwee, INPUT);

 myServo.attach(12);
}

void displayDigit(int digit){
  if(digit ==0){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,HIGH);
    digitalWrite(g,LOW);
  }
  else if(digit ==1) {
    digitalWrite(a,LOW);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,LOW);
    digitalWrite(e,LOW);
    digitalWrite(f,LOW);
    digitalWrite(g,LOW);
  }
  else if(digit ==2){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,LOW);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,LOW);
    digitalWrite(g,HIGH);
  }
}

  
  void loop() 
  {

    
    //Om naar verdiepingNul te gaan.
    if (digitalRead(verdiepingNul)==HIGH){
      if(pos == 90){
        for(pos=90; pos>=0; pos-=1){
          myServo.write(pos);
          delay(30);
        }
      }
      else if(pos == 180) {
        for(pos=180; pos>=0; pos-=1){
        myServo.write(pos);  
        delay(30);
        }
      }
  }
      
    
    //Om naar verdiepingEen te gaan.
    if (digitalRead(verdiepingEen)==HIGH){
      if(pos == 0){
        for(pos=0; pos<=90; pos+=1){
          myServo.write(pos);
          delay(30);
          
        }
      }
      else if(pos == 180) {
        for(pos=180; pos>=90; pos-=1){
          myServo.write(pos); 
          delay(30);
        }
      }
    }

    //Om naar verdiepingTwee te gaan.
    if(digitalRead(verdiepingTwee)==HIGH){
      if(pos == 0){
        for(pos=0; pos<=180; pos+=1){
          myServo.write(pos);
          delay(30);
        }

      }
      else if(pos == 90) {
        for(pos=90; pos<=180; pos+=1){
        myServo.write(pos); 
        delay(30);
        }
      }
    }

    if(myServo.read()==0){
      displayDigit(0);
    }

    else if(myServo.read()==90){
      displayDigit(1);
    }

    else if(myServo.read()==180){
      displayDigit(2);
    }
    
  }

Piring:
Hi guys, me again,

Why have you started a new Thread for what seems to be the same project.

Either convince me that it has nothing to do with your other thread or click Report to Moderator and ask to have the Threads merged

...R

I just wrote my code again. This time i am using an array with booleans. I also used interrupts to make sure my buttonstate would keep high after letting go the button.

My problem now is, that my motor isn't doing anything. Please help :frowning:

#include <Servo.h>

//Alles voor het display
int a = 6;
int b = 5;
int c = 3;
int d = 2;
int e = 1;
int f = 7;
int g = 8;

//Alles voor de drukknoppen
int verdiepingNul = 14;
int verdiepingEen = 15;
int verdiepingTwee = 16;

//Alles voor de servo
Servo myServo;
int pos=0;

//Array voor de wachtrij
boolean statusVerdiepingNul = false;
boolean statusVerdiepingEen = false;
boolean statusVerdiepingTwee = false;
boolean liftArray[3]= {statusVerdiepingNul, statusVerdiepingEen, statusVerdiepingTwee};

int verdiepingNulState = 0;
int verdiepingEenState = 0;
int verdiepingTweeState= 0;

void setup() {

 pinMode(a, OUTPUT);
 pinMode(b, OUTPUT);
 pinMode(c, OUTPUT);
 pinMode(d, OUTPUT);
 pinMode(e, OUTPUT);
 pinMode(f, OUTPUT);
 pinMode(g, OUTPUT); 

 pinMode(verdiepingNul, INPUT);
 pinMode(verdiepingEen, INPUT);
 pinMode(verdiepingTwee, INPUT); 

 myServo.attach(12);

 attachInterrupt(digitalPinToInterrupt(verdiepingNul), pin_ISR, CHANGE);
 attachInterrupt(digitalPinToInterrupt(verdiepingEen), pin_ISR, CHANGE);
 attachInterrupt(digitalPinToInterrupt(verdiepingTwee), pin_ISR, CHANGE);
 
}

void displayDigit(int digit){
  if(digit ==0){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,HIGH);
    digitalWrite(g,LOW);
  }
  else if(digit ==1) {
    digitalWrite(a,LOW);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,LOW);
    digitalWrite(e,LOW);
    digitalWrite(f,LOW);
    digitalWrite(g,LOW);
  }
  else if(digit ==2){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,LOW);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,LOW);
    digitalWrite(g,HIGH);
  }
  myServo.write(0);
}
  
  void loop() { 

  liftArray[0]=verdiepingNulState;
  liftArray[1]=verdiepingEenState;
  liftArray[2]=verdiepingTweeState;
    
    if(liftArray[0]==true){
       if(pos==0){
        for(pos=0; pos<=90; pos++){
          myServo.write(pos);
          delay(30);
        }
       }
       else if(pos==180){
        for(pos=180; pos>=90; pos--){
          myServo.write(pos);
          delay(30);
        }
       }
    }

    if(liftArray[1]==true){
      if(pos==0){
        for(pos=0; pos<=90; pos++){
          myServo.write(pos);
          delay(30);
        }
      }
        else if(pos==180){
          for(pos=180; pos>=90; pos--){
            myServo.write(pos);
            delay(30);
          }
        }
      }

    if(liftArray[2]==true){
      if(pos==0){
        for(pos=0; pos<=180; pos++){
          myServo.write(pos);
          delay(30);
        }
      }
      else if(pos==90){
        for(pos=90; pos<=180; pos++){
          myServo.write(pos);
          delay(30);
        }
      }
    }
  }

  void pin_ISR() {
    verdiepingNulState = digitalRead(verdiepingNul);
    verdiepingEenState = digitalRead(verdiepingEen);
    verdiepingTweeState = digitalRead(verdiepingTwee);

    digitalWrite(liftArray[0], verdiepingNulState);
    digitalWrite(liftArray[1], verdiepingEenState);
    digitalWrite(liftArray[2], verdiepingTweeState);
    
  }

Piring:
I just wrote my code again.

You don't seem to have attempted what I suggested in Reply #3

There is NO (repeat NO) need to use interrupts in this project. That will just make things more complicated than necessary.

...R

Thanks for the reply,

i thought i was doing what you said in reply#3.

Could you maybe give me an example of how you mean to do it?

Piring:
Could you maybe give me an example of how you mean to do it?

Re-read Reply #3 several times and spend a few hours (12 would not be too many - seriously) thinking about it.

Before you start writing code you need to decide what the code needs to do to achieve your objective. That does not require any programming knowledge.

Maybe also look at Planning and Implementing a Program

...R

    digitalWrite(liftArray[0], verdiepingNulState);

digitalWrite(liftArray[1], verdiepingEenState);
    digitalWrite(liftArray[2], verdiepingTweeState);

What is going on here? You are writing to pins numbered with booleans? There is no pin TRUE on the Arduino circuit board.

You do not need interrupts so long as you only expect to press a button when the lift is stationary. Or you re-write without delay().

Hello!

I thought about my problem and i think i found it. This is my code :

#include <Servo.h>

//Alles voor het display
int a = 6;
int b = 5;
int c = 3;
int d = 2;
int e = 1;
int f = 7;
int g = 8;

//Alles voor de drukknoppen
int verdiepingNul = 14;
int verdiepingEen = 15;
int verdiepingTwee = 16;

//Alles voor de servo
Servo myServo;
int pos=0;
int currentFloor;
//Array voor de wachtrij
boolean floorRequested[3];

void setup() {
  Serial.begin(9600);
 pinMode(a, OUTPUT);
 pinMode(b, OUTPUT);
 pinMode(c, OUTPUT);
 pinMode(d, OUTPUT);
 pinMode(e, OUTPUT);
 pinMode(f, OUTPUT);
 pinMode(g, OUTPUT); 

 pinMode(9, INPUT);
 pinMode(10, INPUT);
 pinMode(11, INPUT); 

 myServo.attach(12);
 myServo.write(0);
 int currentFloor=myServo.read();

 Serial.begin(9600);
 }

void displayDigit(int digit){
  if(digit ==0){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,HIGH);
    digitalWrite(g,LOW);
  }
  else if(digit ==1) {
    digitalWrite(a,LOW);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,LOW);
    digitalWrite(e,LOW);
    digitalWrite(f,LOW);
    digitalWrite(g,LOW);
  }
  else if(digit ==2){
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,LOW);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,LOW);
    digitalWrite(g,HIGH);
  }

}
  
  void loop() { 
  if(digitalRead(verdiepingNul)==HIGH){
    floorRequested[0]=true;
  }
  
  if(digitalRead(verdiepingEen)==HIGH){
    floorRequested[1]=true;
  }

  if(digitalRead(verdiepingTwee)==HIGH){
    floorRequested[2]=true;
  }

  for(int i=0; i<3; i++){
    int floorCalculation = i * 90;
    if(floorRequested[i]==true){
      if(currentFloor > floorCalculation){
        for(currentFloor ; currentFloor>= floorCalculation; currentFloor--){
          myServo.write(currentFloor);
          delay(30);
        }
      }
      if(currentFloor < floorCalculation){
        for(currentFloor; currentFloor <= floorCalculation; currentFloor++){
          myServo.write(currentFloor);
          delay(30);
          }
        }
      }
      delay(30);
      floorRequested[i]=false;
    }
    Serial.println(floorRequested[1]);
  }

Now i have the other problem that i don't know how i can make a queue that can save the steps in which the buttons were pressed. Any thoughts on that?

Piring:
i don't know how i can make a queue that can save the steps in which the buttons were pressed. Any thoughts on that?

Elevators don't usually work like that. If they are going up they usually respond to higher calls before starting back down even if the lower call came first. They only start going down if there are no higher calls.

It looks like you are a good distance into the correct solution but I don't think your code is there yet. And it is certainly more complicated than it needs to be. Break your code into functions. As an example, I don't think you should be using FOR because an elevator just moves one place to another in any move. It will not make several successive moves as a group. Also it should be able to go from 1 to 3 without stopping at 2.

...R

Hey Robin, which for loop do you mean?

If i delete the for loop with the motor movement, the motor will turn quick. This for will actually care for the slower movement of the motor.

Piring:
If i delete the for loop with the motor movement, the motor will turn quick. This for will actually care for the slower movement of the motor.

I guess I misunderstood your code. I thought it was effectively doing for (floor = 0; floor <= max; floor ++)

Perhaps another reason for writing your code more clearly :slight_smile:

...R