伺服电机控制代码问题 - Arduino

Servo Motor control code issues - Arduino

是否有修改以下代码的简单方法,以便我可以用另一个输入中断 case '0'。我很确定它与 millis() 有关,但我看到的例子似乎太复杂了。我对编码很陌生,所以任何帮助都会很棒!谢谢。 :)

    #include <Servo.h> 

Servo myservo;  // create servo object to control a servo 

void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Serial.begin(9600); //begins serial communication
} 

void loop() 
{ 
  int pos;
  if (Serial.available()){
    delay(100);
    while(Serial.available()>0){
      pos=Serial.read();     //reads the value sent from Visual Basic  
      if(pos=='0'){
   myservo.write(45);  // Turn Servo Left to 45 degrees
   delay(1000);
   // Wait 1 second
   myservo.write(0);   // Turn Servo Left to 0 degrees
   delay(1000);          // Wait 1 second
   myservo.write(90);  // Turn Servo back to center position (90 degrees)
   delay(2000);          // Wait 2 second
   myservo.write(135); // Turn Servo Right to 135 degrees
   delay(1000);          // Wait 1 second
   myservo.write(180); // Turn Servo Right to 180 degrees
   delay(4000);          // Wait 4 second
   myservo.write(90);  // Turn Servo back to center position (90 degrees)
   delay(1000);}          // Wait 1 second
      else if(pos=='1')
        myservo.write(-90);  //rotates the servo 90 degrees (right)
      else if(pos=='2')
        myservo.write(180);  //rotates the servo 180 degrees (Left)
      else if(pos=='3')
        myservo.write(-180); //rotates the servo 180 degrees (right)     
    }
  } 
} 

您可以在循环外创建两个新变量 int servoStep;int timer。然后创建一个新函数来控制伺服,而不是使用 delay() 你可以像这样使用 millis()。

#include <Servo.h> 

Servo myservo;  // create servo object to control a servo 
int servoStep;  // variable to hold witch step is pending
int timer;      // variable to hold time since last step

void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Serial.begin(9600); //begins serial communication
} 

void loop() 
{ 
  int pos;
  if (Serial.available()){
    delay(100);
    while(Serial.available()>0){
      pos=Serial.read();     //reads the value sent from Visual Basic  
      if(pos=='0'){
        servoStep = 1;
      }  
      else if(pos=='1') {
        servoStep = 0;
        myservo.write(-90);  //rotates the servo 90 degrees (right)
      }
      else if(pos=='2') {
        servoStep = 0;
        myservo.write(180);  //rotates the servo 180 degrees (Left)
      }
      else if(pos=='3') {
        servoStep = 0;
        myservo.write(-180); //rotates the servo 180 degrees (right) 
      }    
    }
  }
   if(servoStep != 0) {
    servoControle(servoStep);
   } 
} 
void servoControle(int v) {
  switch (v) {
    case 1:
      timer = millis();
      myservo.write(45);
      servoStep++;
      break;
    case 2:
      if(timer+1000 <= millis()) {
        myservo.write(0);
        servoStep++;
        timer = millis();
      }
      break;
    case 3:
      if(timer+1000 <= millis()) {
        myservo.write(90);
        servoStep++;
        timer = millis();
      }
      break;
    case 4:
      if(timer+2000 <= millis()) {
        myservo.write(135);
        servoStep++;
        timer = millis();
      }
      break;
    case 5:
      if(timer+1000 <= millis()) {
        myservo.write(180);
        servoStep++;
        timer = millis();
      }
      break;
    case 6:
      if(timer+4000 <= millis()) {
        myservo.write(90);
        servoStep = 0;
      }
      break;
  }
}

使用millis()会让草图在需要延迟的地方保持运行。 我还没有测试它,所以让我知道它是否有效。

这里是实现伺服速度的相同代码。

#include <Servo.h> 

Servo myservo;  // create servo object to control a servo 
int servoStep;
int stepActive;
int timer;
int speedTimer;

void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Serial.begin(9600); //begins serial communication
  speedTimer = millis();
} 

void loop() 
{ 
  int pos;
  if (Serial.available()){
    delay(100);
    while(Serial.available()>0){
      pos=Serial.read();     //reads the value sent from Visual Basic  
      if(pos=='0'){
        servoStep = 1;
        Serial.println("0");
      }  
      else if(pos=='1') {
        servoStep = 0;
        myservo.write(-90);  //rotates the servo 90 degrees (right)
        Serial.println("1");
      }
      else if(pos=='2') {
        servoStep = 0;
        myservo.write(180);  //rotates the servo 180 degrees (Left)
        Serial.println("2");
      }
      else if(pos=='3') {
        servoStep = 0;
        myservo.write(-180); //rotates the servo 180 degrees (right) 
        Serial.println("3");
      }    
    }
  }
  if(servoStep != 0) {
    servoControle(servoStep);
  } 
} 
void servoControle(int v) {
  switch (v) {
    case 1:
      if(stepActive == 0) {
        timer = millis();
        stepActive = 1;
      }
      if(speedControle(20, 45) == 1) { // calls the function with these parameters delay=20, new position=45
        servoStep++;                   // and cheks if it is done
        stepActive = 0;
      }
      break;
    case 2:
      if(timer+1000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 0) == 1) {
        servoStep++;
        stepActive = 0;
        }
      }
      break;
    case 3:
      if(timer+1000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 90) == 1) {
        servoStep++;
        stepActive = 0;
        }
      }
      break;
    case 4:
      if(timer+2000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 135) == 1) {
        servoStep++;
        stepActive = 0;
        }
      }
      break;
    case 5:
      if(timer+1000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 180) == 1) {
        servoStep++;
        stepActive = 0;
        }
      }
      break;
    case 6:
      if(timer+4000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 90) == 1) {
        servoStep = 0;
        stepActive = 0;
        }
      }
      break;
  }
}
int speedControle(int dly, int pos) {   // function that needs delay and new position
  int currentPos = myservo.read();      // reads last position
  if(speedTimer+dly <= millis()) {      // manages the delay
    if(currentPos > pos) {              // chek if new position is clockwise og not
      myservo.write(currentPos-1);      // moves servo one degree
      speedTimer = millis();            
    } else if(currentPos < pos) {
      myservo.write(currentPos+1);
      speedTimer = millis();
    } else if(currentPos == pos) {      // cheks if function is completed
      return 1;
    }
  }
}

如果您在理解代码方面需要帮助,欢迎提问。这个想法是让你自己学习做这件事。 ;)

代码应如下所示:

#include <Servo.h>

Servo myservo[3];  // create servo object to control 3 servos
int servoStep;
int stepActive;
int timer;
int speedTimer;`

void setup() 
{ 
  myservo[0].attach(9);  // attaches servo 1 on pin 9 to the servo object 
  myservo[1].attach(10);  // attaches servo 2 on pin 10 to the servo object 
  myservo[2].attach(11);  // attaches servo 3 on pin 11 to the servo object 
//...ect
  Serial.begin(9600); //begins serial communication
  speedTimer = millis();
} 

void loop() 
{ 
  int pos;
  if (Serial.available()){
    delay(100);
    while(Serial.available()>0){
      pos=Serial.read();     //reads the value sent from Visual Basic  
      if(pos=='0'){
        servoStep = 1;
        Serial.println("0");
      }  
      else if(pos=='1') {
        servoStep = 0;
        myservo[1].write(-90);  //rotates the servo 90 degrees (right)
        Serial.println("1");
      }
      else if(pos=='2') {
        servoStep = 0;
        myservo[1].write(180);  //rotates the servo 180 degrees (Left)
        Serial.println("2");
      }
      else if(pos=='3') {
        servoStep = 0;
        myservo[1].write(-180); //rotates the servo 180 degrees (right) 
        Serial.println("3");
      }    
    }
  }
  if(servoStep != 0) {
    servoControle(servoStep);
  } 
} 
void servoControle(int v) {
  switch (v) {
    case 1:
      if(stepActive == 0) {
        timer = millis();
        stepActive = 1;
      }
      if(speedControle(20, 45, 0) == 1) { // calls the function with these parameters delay=20, new position=45, servo=0(really 1)
        servoStep++;                   // and cheks if it is done
        stepActive = 0;
      }
      break;
    case 2:
      if(timer+1000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 0, "The servo you want to controle fx. 1") == 1) {
        servoStep++;
        stepActive = 0;
        }
      }
      break;
    case 3:
      if(timer+1000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 90, "The servo you want to controle fx. 1") == 1) {
        servoStep++;
        stepActive = 0;
        }
      }
      break;
    case 4:
      if(timer+2000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 135, "The servo you want to controle fx. 1") == 1) {
        servoStep++;
        stepActive = 0;
        }
      }
      break;
    case 5:
      if(timer+1000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 180, "The servo you want to controle fx. 1") == 1) {
        servoStep++;
        stepActive = 0;
        }
      }
      break;
    case 6:
      if(timer+4000 <= millis()) {
        if(stepActive == 0) {
          timer = millis();
          stepActive = 1;
        }
        if(speedControle(20, 90, "The servo you want to controle fx. 1") == 1) {
        servoStep = 0;
        stepActive = 0;
        }
      }
      break;
  }
}
int speedControle(int dly, int pos, int servo) {   // function that needs delay and new position
  int currentPos = myservo[servo].read();      // reads last position
  if(speedTimer+dly <= millis()) {      // manages the delay
    if(currentPos > pos) {              // chek if new position is clockwise og not
      myservo[servo].write(currentPos-1);      // moves servo one degree
      speedTimer = millis();            
    } else if(currentPos < pos) {
      myservo[servo].write(currentPos+1);
      speedTimer = millis();
    } else if(currentPos == pos) {      // cheks if function is completed
      return 1;
    }
  }
}

还没试过..