It has only one elevator (5 floors).
My intention was to make 3 algorithms . 1 of them is finished (FIFO queue). Here is the code that works fine:
#include <AccelStepper.h>
#include <CircularBuffer.h>
#include <Servo.h>
Servo myservo;
#define dirPin 4
#define stepPin 5
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
const byte NumberOfFloors = 5;
const unsigned long FloorLevel[NumberOfFloors] = {0, 180, 360, 540, 720};
const unsigned long pins [NumberOfFloors] = {2, 3, 18, 19, 20};
const int LED[NumberOfFloors] = {40, 41, 42, 43, 44};
volatile int state = 0;
int doorspeed = 8;
int servopin = 14;
CircularBuffer<int,50> buffer;
CircularBuffer<int,20> led;
int segPins[] = {30, 31, 32, 33, 34, 35, 36};/*assigning pins of Arduino for the seven-segment*/
byte segCode[6][7] = { /*declaring an array of the number from 0 to 9 in the order from a of g*/
//a b c d e f g
{ 1, 1, 1, 1, 1, 1, 0}, // for displaying 0
{ 0, 1, 1, 0, 0, 0, 0}, // for displaying 1
{ 1, 1, 0, 1, 1, 0, 1}, // for displaying 2
{ 1, 1, 1, 1, 0, 0, 1}, // for displaying 3
{ 0, 1, 1, 0, 0, 1, 1}, // for displaying 4
{ 0, 0, 0, 0, 0, 0, 0}, // for displaying off
};
void displayDigit(int digit) /*creating a function for initializing the each segment of the display*/
{
for (int a=0; a < 7; a++)
{
digitalWrite(segPins[a], segCode[digit][a]);/* instructing the respective segments for the numbers from 0 to 4 */
}
}
void setup()
{
Serial.begin(9600);
delay(200);
attachInterrupt(digitalPinToInterrupt(pins[0]), button0_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[1]), button1_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[2]), button2_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[3]), button3_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[4]), button4_ISR, RISING);
myservo.write(180);
for (int a=0; a < 5; a++) // assigning the OUTPUT mode to all the 7 seven-segments*/
{
pinMode(LED[a], OUTPUT);
}
for (int a=0; a < 7; a++) // assigning the OUTPUT mode to all the 7 seven-segments*/
{
pinMode(segPins[a], OUTPUT);
}
myservo.attach(servopin);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(100);
}
void loop()
{
showdigit();
switch (state){
case 0:
empty();
break;
case 1:
steppermove();
break;
case 2:
delay(100);
door();
delay(100);
state=3;
break;
case 3:
buffer.shift();
state=0;
break;
}
}
void showdigit(){
if(buffer.isEmpty()==false){
displayDigit(buffer.first());
}
else{
displayDigit(5);
}
}
void empty(){
if(buffer.isEmpty()==false) {
stepper.moveTo(FloorLevel[buffer.first()]);
//show led display
state=1;
}
}
void steppermove(){
stepper.run();
if (stepper.currentPosition() == FloorLevel[buffer.first()]){
digitalWrite(LED[led.first()], LOW);
led.shift();
keepled();
state=2;
}
}
void interrupt(long pin){
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 200)
{
buffer.push(pin);
led.push(pin);
}
last_interrupt_time = interrupt_time;
digitalWrite(LED[pin], HIGH);
delay(100);
if (stepper.currentPosition() == FloorLevel[buffer.first()]){
digitalWrite(LED[buffer.first()], LOW);
}
}
void button0_ISR(){
interrupt(0);
}
void button1_ISR(){
interrupt(1);
}
void button2_ISR(){
interrupt(2);
}
void button3_ISR(){
interrupt(3);
}
void button4_ISR(){
interrupt(4);
}
void door(){
myservo.write(0);
delay(1000);
myservo.write(180);
}
void keepled(){
for(int i = 0; i < led.size(); i++ )
digitalWrite(LED[led[i]], HIGH);
}
Then I want to make another that when it finishes a call input, it goes to the nearest one. This is the code (it does not work):
#include <CircularBufferLib.h>
#include <AccelStepper.h>
#include <Servo.h>
Servo myservo;
#define dirPin 4
#define stepPin 5
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
const byte NumberOfFloors = 5;
const unsigned long FloorLevel[NumberOfFloors] = {0, 100, 200, 300, 400};
const unsigned long pins [NumberOfFloors] = {2, 3, 18, 19, 20};
const int LED[NumberOfFloors] = {40, 41, 42, 43, 44};
volatile int state = 0;
int doorspeed = 8;
int servopin = 14;
CircularBuffer<int> buffer(50);
CircularBuffer<int> temp(10);
int segPins[] = {22, 23, 24, 25, 26, 27, 28};/*assigning pins of Arduino for the seven-segment*/
byte segCode[6][7] = { /*declaring an array of the number from 0 to 9 in the order from a of g*/
//a b c d e f g
{ 0, 0, 0, 0, 0, 0, 1}, // for displaying 0
{ 1, 0, 0, 1, 1, 1, 1}, // for displaying 1
{ 0, 0, 1, 0, 0, 1, 0}, // for displaying 2
{ 0, 0, 0, 0, 1, 1, 0}, // for displaying 3
{ 1, 0, 0, 1, 1, 0, 0}, // for displaying 4
{ 1, 1, 1, 1, 1, 1, 1}, // for displaying off
};
void displayDigit(int digit) /*creating a function for initializing the each segment of the display*/
{
for (int a=0; a < 7; a++)
{
digitalWrite(segPins[a], segCode[digit][a]);/* instructing the respective segments for the numbers from 0 to 9 */
}
}
void setup()
{
Serial.begin(9600);
delay(200);
attachInterrupt(digitalPinToInterrupt(pins[0]), button0_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[1]), button1_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[2]), button2_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[3]), button3_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[4]), button4_ISR, RISING);
for (int a=0; a < 7; a++) // assigning the OUTPUT mode to all the 7 seven-segments*/
{
pinMode(segPins[a], OUTPUT);
}
myservo.attach(servopin);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(100);
}
void loop()
{
showdigit();
switch (state){
case 0:
empty();
break;
case 1:
newtarget();
break;
case 2:
steppermove();
break;
case 3:
delay(100);
door();
delay(100);
state=4;
break;
case 4:
buffer.RemoveFirst();
state=0;
break;
}
}
void showdigit(){
if (buffer.Count()>0){
displayDigit(buffer.First());
}
else{
displayDigit(5);
}
}
void steppermove(){
stepper.run();
if (stepper.currentPosition() == FloorLevel[buffer.First()]){
state=3;
}
}
void interrupt(long pin){
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 200)
{
buffer.Add(pin);
}
last_interrupt_time = interrupt_time;
}
void button0_ISR(){
interrupt(0);
}
void button1_ISR(){
interrupt(1);
}
void button2_ISR(){
interrupt(2);
}
void button3_ISR(){
interrupt(3);
}
void button4_ISR(){
interrupt(4);
}
void door(){
myservo.write(90 + doorspeed);
delay(1000);
myservo.write(90);
delay(1000);
myservo.write(90 - doorspeed);
delay(1000);
myservo.write(90);
}
void empty(){
if (buffer.Count()>0){
stepper.moveTo(FloorLevel[buffer.First()]);
state=1;
}
}
void newtarget(){
int dist;
const int count=buffer.Count();
for(int i = 0; i < count; i++ ){
dist=stepper.currentPosition()-FloorLevel[buffer[i]];
if (abs(dist) < abs(stepper.distanceToGo())){
temp.Add(buffer[i]);
buffer.ReplaceAt(i, buffer.First());
buffer.ReplaceFirst(temp.ExtractFirst());
state=0;
}
}
state=2;
}
Finally, I want to make an algorithm that only goes up, e.g. if the cabis is at floor 0 and there are calls at 2,3,4 it will stop at all of them, and once there is a lower input the cabin needs to reach the top floor, then back to 0 and go to those calls (it doesn't work too):
Adam Gills
#include <CircularBufferLib.h>
#include <AccelStepper.h>
#include <Servo.h>
Servo myservo;
#define dirPin 4
#define stepPin 5
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
const byte NumberOfFloors = 5;
const unsigned long FloorLevel[NumberOfFloors] = {0, 100, 200, 300, 400};
const unsigned long pins [NumberOfFloors] = {2, 3, 18, 19, 20};
const int LED[NumberOfFloors] = {40, 41, 42, 43, 44};
int segPins[] = {22, 23, 24, 25, 26, 27, 28};/*assigning pins of Arduino for the seven-segment*/
volatile int state = 0;
int doorspeed = 8;
int servopin = 14;
volatile int count;
CircularBuffer<int> higher(50);
CircularBuffer<int> lower(50);
CircularBuffer<int> temp(10);
byte segCode[6][7] = { /*declaring an array of the number from 0 to 9 in the order from a of g*/
//a b c d e f g
{ 0, 0, 0, 0, 0, 0, 1}, // for displaying 0
{ 1, 0, 0, 1, 1, 1, 1}, // for displaying 1
{ 0, 0, 1, 0, 0, 1, 0}, // for displaying 2
{ 0, 0, 0, 0, 1, 1, 0}, // for displaying 3
{ 1, 0, 0, 1, 1, 0, 0}, // for displaying 4
{ 1, 1, 1, 1, 1, 1, 1}, // for displaying off
};
void displayDigit(int digit) /*creating a function for initializing the each segment of the display*/
{
for (int a=0; a < 7; a++)
{
digitalWrite(segPins[a], segCode[digit][a]);/* instructing the respective segments for the numbers from 0 to 9 */
}
}
void setup()
{
Serial.begin(9600);
delay(200);
attachInterrupt(digitalPinToInterrupt(pins[0]), button0_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[1]), button1_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[2]), button2_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[3]), button3_ISR, RISING);
attachInterrupt(digitalPinToInterrupt(pins[4]), button4_ISR, RISING);
myservo.attach(servopin);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(100);
for (int a=0; a < 5; a++) // assigning the OUTPUT mode to all the 7 seven-segments*/
{
pinMode(LED[a], OUTPUT);
}
for (int a=0; a < 7; a++) // assigning the OUTPUT mode to all the 7 seven-segments*/
{
pinMode(segPins[a], OUTPUT);
}
}
void loop()
{
newtarget();
showdigit();
switch (state) {
case 0:
empty();
break;
case 1:
steppertop();
break;
case 2:
stepperbottom();
break;
case 3:
steppermove();
break;
case 4:
delay(100);
door();
delay(100);
state = 5;
break;
case 5:
higher.RemoveFirst();;
state = 0;
break;
}
}
void showdigit(){
if(higher.Count() > 0 ){
displayDigit(higher.First());
}
else{
displayDigit(5);
}
}
void empty(){
if (higher.Count() > 0 ) {
stepper.moveTo(FloorLevel[higher.First()]);
//show led display
state = 3;
}
if (higher.Count() == 0 && lower.Count() > 0) {
stepper.moveTo(FloorLevel[4]);
state = 1;
}
}
void steppertop() {
stepper.run();
if (stepper.currentPosition() == FloorLevel[4]) {
stepper.moveTo(FloorLevel[0]);
state = 2;
}
}
void stepperbottom() {
stepper.run();
if (stepper.currentPosition() == FloorLevel[0]) {
lowtohigh();
stepper.moveTo(FloorLevel[higher.First()]);
state = 3;
}
}
void steppermove() {
stepper.run();
if (stepper.currentPosition() == FloorLevel[higher.First()]) {
digitalWrite(LED[higher.First()], LOW);
state = 4;
}
}
void interrupt(long pin) {
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 200)
{
if (stepper.currentPosition()>FloorLevel[pin] || state==2){
lower.Add(pin);
}
else{
higher.Add(pin);
}
}
last_interrupt_time = interrupt_time;
digitalWrite(LED[pin], HIGH);
if (stepper.currentPosition() == FloorLevel[higher.First()]){
digitalWrite(LED[higher.First()], LOW);
}
}
void button0_ISR() {
interrupt(0);
}
void button1_ISR() {
interrupt(1);
}
void button2_ISR() {
interrupt(2);
}
void button3_ISR() {
interrupt(3);
}
void button4_ISR() {
interrupt(4);
}
void door() {
myservo.write(90 + doorspeed);
delay(1000);
myservo.write(90);
delay(1000);
myservo.write(90 - doorspeed);
delay(1000);
myservo.write(90);
}
void newtarget(){
int dist;
count=higher.Count();
for(int i = 0; i < count; i++ ){
dist=stepper.currentPosition()-FloorLevel[higher[i]];
if (abs(dist) < abs(stepper.distanceToGo())){
temp.Add(higher[i]);
higher.ReplaceAt(i, higher.First());
higher.ReplaceFirst(temp.ExtractFirst());
stepper.moveTo(FloorLevel[higher.First()]);
state=3;
}
}
}
void lowtohigh(){
count=lower.Count();
for(int i=0; i<count; i++){
higher.Add(lower.ExtractFirst());
}
}
The ones that do not work use circularbufferLib