2016-01-13 226 views
1

我已经开始用arduino编程三层电梯。到目前为止,我可以设法从每个楼层呼叫电梯,并将轿厢移向选定的楼层。现在,我试图将按下的按钮存储在一个阵列中,并按照呼叫顺序将电梯移动到选定的楼层。然而,汽车仅移动到一个楼层并停在那里,并且不会继续到下一个选定的楼层。这是我所做的。Arduino电梯

const int maxfloors = 3; 

byte carcall_buttons[maxfloors] = {22,24,46}; 
byte floor_sensors[maxfloors] = {25,26,47}; 

int buttonstate[3]; 
int sensorstate[3]; 

boolean registered[3] = {false, false, false}; 


int lastbuttonstate0 = LOW; 
int lastbuttonstate1 = LOW; 
int lastbuttonstate2 = LOW; 

int lastsensorstate0 = LOW; 
int lastsensorstate1 = LOW; 
int lastsensorstate2 = LOW; 

const byte led1 = 27; 
const byte led2 = 23; 
const byte led3 = 48; 

const int motor_up = 41; 
const int motor_down = 42; 
const int En = 40; 

enum state {down,stop}; 
state elevator_state; 


void setup() 
{ 
    for (int i = 0; i<maxfloors; i++) 
    { 
    pinMode (carcall_buttons[i], INPUT); 
    pinMode (floor_sensors[i], INPUT); 
    } 

    pinMode (led1, OUTPUT); 
    pinMode (led2, OUTPUT); 
    pinMode (led3, OUTPUT); 

    pinMode(motor_up, OUTPUT); 
    pinMode(motor_down, OUTPUT); 
    pinMode(En, OUTPUT); 

    Serial.begin (9600); 
} 

void loop() 
{ 

    ReadButtons(); 
    ReadSensors(); 
    FloorSelection(); 

    static int elevator_state = stop; 

    switch (elevator_state) 
    { 
    case down: 

    if (registered[0] == true || registered[1] == true) 
    { 
     if (sensorstate[2] == LOW) 
     { 
     movedown(); 
     elevator_state = stop; 
     } 
    } 

    break; 

    case stop: 

    if (registered[1] == true && sensorstate[1] == LOW) 
    { 
     motor_stop(); 
     registered[1] = false; 

     for (int i=0;i<maxfloors;i++) 
     { 
     Serial.println (registered[i]); 
     } 

    } 

    if (registered[0] == true && sensorstate[0] == LOW) 
    { 
     motor_stop(); 
     registered[0] = false; 

     for (int i=0;i<maxfloors;i++) 
     { 
     Serial.println (registered[i]); 
     } 
    } 

    break; 
    } 
} 



void ReadButtons() 
{ 

    for (int i=0;i<maxfloors;i++) 
    { 
    buttonstate[i] = digitalRead (carcall_buttons[i]); 
    } 
} 

void ReadSensors() 
{ 

    for (int i=0;i<maxfloors;i++) 
    { 
    sensorstate[i] = digitalRead (floor_sensors[i]); 
    } 
} 

void FloorSelection() 
{ 

    for (int i=0;i<maxfloors;i++) 
    { 
    if (buttonstate[0] != lastbuttonstate0) 
    { 
    if (buttonstate[0] == HIGH) 
    { 
    registered [0] = true; 

    delay(100); 
    Serial.println (registered [i]); 
    } 
    } 

    if (buttonstate[1] != lastbuttonstate1) 
    { 
    if (buttonstate[1] == HIGH) 
    { 
    registered [1] = true; 

    delay(100); 
    Serial.println (registered [i]); 
    } 
    } 

    if (buttonstate[2] != lastbuttonstate2) 
    { 
    if (buttonstate[2] == HIGH) 
    { 
    registered [2] = true; 

    delay(100); 
    Serial.println (registered [i]); 
    } 
    } 
} 
} 

void motor_stop() 
{ 

    digitalWrite(led1, LOW); 
    digitalWrite(led2, LOW); 
    Serial.println ("idle"); 

    digitalWrite(motor_up, LOW); 
    digitalWrite(motor_down, LOW); 
    digitalWrite(En, LOW); 
} 

void moveup() 
{ 
    digitalWrite(led1, HIGH); 
    digitalWrite(led2, LOW); 
    Serial.println ("up"); 

    digitalWrite(motor_up, LOW); 
    digitalWrite(motor_down, HIGH); 
    digitalWrite(En, HIGH); 
} 


void movedown() 
{ 
    digitalWrite(led1, LOW); 
    digitalWrite(led2, HIGH); 
    Serial.println ("down"); 

    digitalWrite(motor_up, LOW); 
    digitalWrite(motor_down, HIGH); 
    digitalWrite(En, HIGH); 
} 

回答

0

如果我正确理解了您的代码,那么您不会将选定的楼层存储到“按呼叫顺序排列的数组”中。

你应该不断查询键,当按下一个:你的阵列的

  1. 校验字节0。

  2. 如果它是0,请在此处存放地板。

  3. 如果不是的话,校验字节1(等)

  4. 如果它是可用的(即== 0),你的价值是从0字节不同,那么存储地板这里。



你也应该轮询传感器值(知道在哪里的车)和:

  1. 如果是在地板上,检查它是否对应于第一值的array
  2. 如果是这样,请停下汽车并将阵列的每个值减1(array [0] = array [1]; array [1] = array [2]; array [2] = 0;假设你只有三个值的历史记录)

请注意,您的历史记录可能比maxfloors常数长得多。在这种情况下,我建议做一个do {},而找到数组中的第一个可用点。

0

我想我找到了你的问题,但我可能是错的。您的函数中的数组和变量超出了您的switch语句的范围。至少,我认为这是问题。你应该真的把你的代码变成显示错误所需的最小代码,否则我们真的很难帮助你。我必须仔细阅读代码才能弄明白。我很确定,如果你在你的函数参数中使用了通过引用,并在全局或主(循环)范围中声明数组,你的问题将得到解决。此外,除了void之外,您还可以为函数使用不同的返回类型,例如int,但只能从函数返回一个值,所以按引用传递最适合您的目的。请允许我通过引用来证明代码。写它的方式,你的函数什么都不做,因为它们不返回任何值,也不修改任何现有的对象。此解决方案需要应用于所有修改或创建对象的函数以及switch语句。简而言之,将数组和变量声明为更大的范围,并通过引用来修改它们。我希望这可以帮助你。

int buttonstate[2]; 
int sensorstate[2]; 

void ReadButtons(&buttonstate) 
{ 

    for (int i=0;i<maxfloors;i++) 
    { 
    buttonstate[i] = digitalRead (carcall_buttons[i]); 
    } 
} 

void ReadSensors(&sensorstate) 
{ 

    for (int i=0;i<maxfloors;i++) 
    { 
    sensorstate[i] = digitalRead (floor_sensors[i]); 
    } 
}