This will be a little different from my usual posts. No graphics, no detailed step by step directions. Just some code. This uses some Arduino but the effort for porting to anything would be pretty minimal. Don’t forget to match the pin #define statements to your actual hardware, the example ones I used here don’t work for most board types.
This is a pretty standard programming homework assignment, but I never was given this one as a student so when an IRC user asked about it, I thought I’d give it a go.
I’ve only used 3 states, this can be done with more inside the state machine, but I wanted to keep it simple so I split the other aspects into separate tests.
Students; this is not the homework answer you’re looking for. See the permissions in the copyright.
Without further ado:
/*
Copyright © Chisight 2018
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
This software may not be used as a significant portion of the work in
completing a school assignment.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
Hardware is:
digital pin — 1k resistor — button — ground
digital pin — 120 ohm resistor — white led — ground
*/
#define SWITCH1 11
#define SWITCH2 12
#define SWITCH3 3
#define SWITCH4 4
#define SWITCH5 5
#define LED1 6
#define LED2 7
#define LED3 8
#define LED4 9
#define LED5 10
#define TOPFLOOR 5
#define IDLELIMIT 10
#define INTERVAL 2000L
enum direction { UP, DOWN, STOPPED }; // this is our main STATE enumeration
unsigned long previousMillis = 0;
short currentFloor=0; // computers start counting at zero, unlike humans
short floorSelected[TOPFLOOR]={0,0,0,0,0}; // array of buttons, initalized to not pressed
enum direction elevatorDirection=STOPPED; // this is our STATE variable
short moved;
unsigned int idleCount=0;
void setup(){
Serial.begin(115200);
pinMode(SWITCH1, INPUT); // set pin to input
digitalWrite(SWITCH1, HIGH); // turn on pullup resistor
pinMode(SWITCH2, INPUT); // set pin to input
digitalWrite(SWITCH2, HIGH); // turn on pullup resistor
pinMode(SWITCH3, INPUT); // set pin to input
digitalWrite(SWITCH3, HIGH); // turn on pullup resistor
pinMode(SWITCH4, INPUT); // set pin to input
digitalWrite(SWITCH4, HIGH); // turn on pullup resistor
pinMode(SWITCH5, INPUT); // set pin to input
digitalWrite(SWITCH5, HIGH); // turn on pullup resistor
pinMode(LED1, OUTPUT); // set pin to output
digitalWrite(LED1, LOW); // turn LED off
pinMode(LED2, OUTPUT); // set pin to output
digitalWrite(LED2, LOW); // turn LED off
pinMode(LED3, OUTPUT); // set pin to output
digitalWrite(LED3, LOW); // turn LED off
pinMode(LED4, OUTPUT); // set pin to output
digitalWrite(LED4, LOW); // turn LED off
pinMode(LED5, OUTPUT); // set pin to output
digitalWrite(LED5, LOW); // turn LED off
setLED(0);
}
void printEnum(enum direction elevatorDirection){
switch(elevatorDirection){
case UP :
Serial.print(“UP”);
break;
case DOWN :
Serial.print(“DOWN”);
break;
case STOPPED :
Serial.print(“STOPPED”);
break;
default :
Serial.print(“Out of range!”);
}
}
void setLED(short currentFloor){
Serial.print(“3 setting LED:”);
Serial.println(itoa(currentFloor+1,(char*)” “,10));
digitalWrite(LED1,(currentFloor==0)?HIGH:LOW); // set LED on or off if currentFloor
digitalWrite(LED2,(currentFloor==1)?HIGH:LOW); // set LED on or off if currentFloor
digitalWrite(LED3,(currentFloor==2)?HIGH:LOW); // set LED on or off if currentFloor
digitalWrite(LED4,(currentFloor==3)?HIGH:LOW); // set LED on or off if currentFloor
digitalWrite(LED5,(currentFloor==4)?HIGH:LOW); // set LED on or off if currentFloor
}
void openDoors(short currentFloor){
unsigned long currentMillis;
Serial.print(“5 Open doors at floor:”);
Serial.println(itoa(currentFloor+1,(char*)” “,10));
do {
currentMillis = millis();
delay(INTERVAL/10);
setLED(-1);
delay(INTERVAL/10);
setLED(currentFloor);
} while(currentMillis – previousMillis = INTERVAL) { // is it time to move?
previousMillis = currentMillis; // save the time to have it for the next cycle
moved=0; // we haven’t moved during this cycle yet
switch(elevatorDirection){
case UP : // we’re moving upwards
if(currentFloor=0; i–){ // for each floor below us
if(floorSelected[i]){ // check if selected
setLED(–currentFloor); // move down one and set led for that floor
moved=1; // we’ve not stopped yet
break; // only move one floor per cycle
}
}
if(floorSelected[currentFloor]){
openDoors(currentFloor);
floorSelected[currentFloor]=0; // we’ve arrived, clear the button
}
}
break;
case STOPPED :
for(short i=0; icurrentFloor?UP:DOWN); //head towards that floor
moved=1; // avoid stopping before we even moved
break;
}
}
}
break;
}
if(!moved) elevatorDirection=STOPPED;
else idleCount=0;
if((elevatorDirection==STOPPED) && (currentFloor != 0)) idleCount++; // if stopped, count seconds
if(idleCount>IDLELIMIT) { // once over the preset limit
floorSelected[0]=1; // return to the ground floor
idleCount=0;
}
Serial.print(“2 elevatorDirection:”);
printEnum(elevatorDirection);
Serial.print(” currentFloor:”);
Serial.print(itoa(currentFloor+1,(char*)” “,10));
Serial.print(” buttons:”);
Serial.print(itoa(floorSelected[0],(char*)” “,10));
Serial.print(itoa(floorSelected[1],(char*)” “,10));
Serial.print(itoa(floorSelected[2],(char*)” “,10));
Serial.print(itoa(floorSelected[3],(char*)” “,10));
Serial.print(itoa(floorSelected[4],(char*)” “,10));
Serial.print(” idleCount:”);
Serial.println(idleCount);
}
if(!digitalRead(SWITCH1)){ if(floorSelected[0]==0) Serial.println(“SWITCH1 pressed”); floorSelected[0]=1; } // read the buttons and adjust the floor if needed
if(!digitalRead(SWITCH2)){ if(floorSelected[1]==0) Serial.println(“SWITCH2 pressed”); floorSelected[1]=1; }
if(!digitalRead(SWITCH3)){ if(floorSelected[2]==0) Serial.println(“SWITCH3 pressed”); floorSelected[2]=1; }
if(!digitalRead(SWITCH4)){ if(floorSelected[3]==0) Serial.println(“SWITCH4 pressed”); floorSelected[3]=1; }
if(!digitalRead(SWITCH5)){ if(floorSelected[4]==0) Serial.println(“SWITCH5 pressed”); floorSelected[4]=1; }
}
That’s all there is to it.