首页 文章

如何使代码重复非预定义的次数

提问于
浏览
-1

作为一个学校的项目,我有一个触摸传感器作为连接到arduino的开/关开关 . 一旦它启动马达, Servo 和超声波传感器接触触摸 . 然后当再次触摸传感器时,它们都停止 . 我的问题是,我不能使 Servo 和超声波重复转动和计算距离超过一次的过程,我不能使用循环,因为我不知道电路运行多长时间,如果我做了后在第二次按下按钮我将不得不等待所有插入的循环数量在所有内容也停止之前结束 .

这是到目前为止的代码:

#include <Servo.h>
    Servo servo; 
    int pos = 0;
    const int trigPin = 4;
    const int echoPin = 5; 
    long duration;
    int distance; 


    #define TouchSensor 13 
    int relay = 2; 
     // motor one
    int enA = 10;
    int in1 = 6;
    int in2 = 7;
    // motor two
    int enB = 5;
    int in3 = 8;
    int in4 = 9;

    boolean currentState = LOW;
    boolean lastState = LOW;
    boolean RelayState = LOW;

    void setup() {
      Serial.begin(9600);
      pinMode(enA, OUTPUT);  
      pinMode(enB, OUTPUT);  
      pinMode(in1, OUTPUT);
      pinMode(in2, OUTPUT);
      pinMode(in3, OUTPUT);
      pinMode(in4, OUTPUT);
      pinMode(TouchSensor, INPUT);
      servo.attach(3);
      pinMode(trigPin, OUTPUT); 
      pinMode(echoPin, INPUT);
    }

    void loop() {
      currentState = digitalRead(TouchSensor);
        if (currentState == HIGH && lastState == LOW){
        Serial.println("pressed");
        digitalWrite(in1, LOW);
        digitalWrite(in2, HIGH);  
        digitalWrite(in3, HIGH);
        digitalWrite(in4, LOW);

        servo.write(40);
     digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    distance= duration*0.034/2;
    Serial.print("Distance: ");
    Serial.println(distance);
     delay(500);
     servo.write(80);
     digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    distance= duration*0.034/2;
    Serial.print("Distance: ");
    Serial.println(distance);
     delay(500);
     servo.write(120);
     digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    distance= duration*0.034/2;
    Serial.print("Distance: ");
    Serial.println(distance);
     delay(500);
     servo.write(160);
     digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    distance= duration*0.034/2;
    Serial.print("Distance: ");
    Serial.println(distance);
    delay(500);

      delay(1);

        if (RelayState == HIGH){
          digitalWrite(relay, LOW);
          RelayState = LOW;
        digitalWrite(in1, LOW);
        digitalWrite(in2, LOW);  
        digitalWrite(in3, LOW);
        digitalWrite(in4, LOW); 
        } else {
          digitalWrite(relay, HIGH);
          RelayState = HIGH;
        }
      }
      lastState = currentState;
    }

提前致谢 . 对不起,任何错误,英语不是我的第一语言 .

2 回答

  • 0

    在C语言中,与大多数其他语言一样,可以使用 break 语句从循环中提前输出,因此您可以执行以下操作:

    // A loop condition that will never terminate on its own
    while(true)
    {
      // Exit the loop when the sensor is triggered again
      if (sensorPressed()) {
        break;
      }
    
      // Otherwise, continue doing whatever is needed
    }
    
    // After the break, execution will resume here
    

    请注意,在进入主循环之前,您可能还需要另一个循环来确保传感器仍然不会被触发 .

  • 0

    你真的应该考虑让你的代码更容易阅读 . 很难跟进 . 即使它不是代码编写服务,我觉得必须让它更具可读性作为一个例子 . 功能应相同,不包括该状态的添加循环 . 我不能在这里尝试一下 . 这不是完美的,但我已经用了一段时间重写这个,所以是的,希望你从中得到一些东西 . 干杯 .

    #include <Servo.h>
    
    
    /*
       Here I have added couple of definitions,
       like max servo position and speed of sound.
       Good rule is to name definitions in capital letters.
     */
    
    #define TOUCHSENSOR 13
    #define STEPSIZE 40
    #define SPEED_OF_SOUND 0.034
    #define MAX_SERVO_POS 160
    const int trigPin = 4;
    const int echoPin = 5;
    
    int relay = 2;
    
    /*
       its good to name variables so they indicate usage if possible,
       Here I have renamed motor PIN variables and enable pins.
       Not only for others but you will also eventually forget.
     */
    int enableMotorOne = 10;
    int motorOneTerminalOne = 6;
    int motorOneTerminalTwo = 7;
    // motor two
    int enableMotorTwo = 5;
    int motorTwoTerminalOne = 8;
    int motorTwoTerminalTwo = 9;
    
    boolean currentState = LOW;
    boolean lastState = LOW;
    boolean relayState = LOW;
    
    Servo servo;
    
    void setup() {
            Serial.begin(9600);
            pinMode(enableMotorOne, OUTPUT);
            pinMode(motorOneTerminalOne, OUTPUT);
            pinMode(motorOneTerminalTwo, OUTPUT);
    
            pinMode(enableMotorTwo, OUTPUT);
            pinMode(motorTwoTerminalOne, OUTPUT);
            pinMode(motorTwoTerminalTwo, OUTPUT);
    
            pinMode(TOUCHSENSOR, INPUT);
            servo.attach(3);
            pinMode(trigPin, OUTPUT);
            pinMode(echoPin, INPUT);
    }
    
    
    void getDistance()
    {
            /*
               Whole function for getting distance from ultrasonic sensor is moved Here
               usage in older implementation was repetitive and unnecessary
             */
    
            long duration;
            int distance;
    
            digitalWrite(trigPin, LOW);
            delayMicroseconds(2);
            digitalWrite(trigPin, HIGH);
            delayMicroseconds(10);
            digitalWrite(trigPin, LOW);
    
            duration = pulseIn(echoPin, HIGH);
            distance= duration*(SPEED_OF_SOUND/2);
            Serial.print("Distance: ");
            Serial.println(distance);
    }
    
    void scanState()
    {
            Serial.println("pressed");
            digitalWrite(motorOneTerminalOne, LOW);
            digitalWrite(motorOneTerminalTwo, HIGH);
            digitalWrite(motorTwoTerminalOne, HIGH);
            digitalWrite(motorTwoTerminalTwo, LOW);
    
            while(currentState == HIGH && lastState == LOW)
            {
                    /*
                       I think this is what you were asking, to loop this functionality
                       until state pins change state.
                     */
    
                    for (size_t servoPos = 40; servoPos <= MAX_SERVO_POS; servoPos+=STEPSIZE) {
                            /*
                               This code in for loop here should do kinda 
                               same as you old code rows 
                               48-91. Please get familiar.
                             */
                            servo.write(servoPos);
                            getDistance();
                            delay(500);
                    }
    
                    if (relayState == HIGH) {
                            digitalWrite(relay, LOW);
                            relayState = LOW;
                            digitalWrite(motorOneTerminalOne, LOW);
                            digitalWrite(motorOneTerminalTwo, LOW);
                            digitalWrite(motorTwoTerminalOne, LOW);
                            digitalWrite(motorTwoTerminalTwo, LOW);
                    } else {
                            digitalWrite(relay, HIGH);
                            relayState = HIGH;
                    }
            }
            delay(1);
    }
    
    void loop() {
    
            /*
               This is your new loop function, much easier to understand what is
               going on..
             */
            currentState = digitalRead(TOUCHSENSOR);
            if (currentState == HIGH && lastState == LOW) {
                    scanState();
            }
            lastState = currentState;
    }
    

相关问题