【问题标题】:Continuous servo rotation Arduino连续伺服旋转Arduino
【发布时间】:2014-04-28 06:44:00
【问题描述】:

我有一个连续旋转伺服,我需要顺时针和逆时针旋转。我发现中点在 100,我发现最合适的顺时针和逆时针速度分别是 110 和 85。按下按钮 A 时舵机顺时针旋转,按下按钮 B 时舵机逆时针旋转。

我想要一种方法来减慢伺服,一旦按钮被释放,以指数速率,所以它会说从 110 到 100,或 85 到 100 秒(用户可定义)秒。有没有人知道的功能可以帮助我完成这个?或这样做的一种方式。由于我是 Arduino 菜鸟,因此感谢详细的答案。

#include <Servo.h>

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

// CONSTANTS

// PINS
const int crServo = 12; // sets pin 12 as servo
const int buttonPinCW = 2; // sets pin 2 as button; CW => clockwise => FOCUS FAR
const int buttonPinCC = 3; // sets pin 3 as button; CC => counterclockwise => FOCUS NEAR
const int ledPinB = 4; // sets pin 10 as LED
const int ledPinG = 5; // sets pin 10 as LED
const int ledPinR = 6; // sets pin 10 as LED

// SERVO PROPERTIES
const int crSpeedDefault = 100; // is the stay still position, motor should not turn
const int crSpeedCW = 110; // turns the motor full speed clockwise
const int crSpeedCC = 85; // turns the motor full speed counter-clockwise

// SET BUTTON STATES
int buttonStateCW = 0; //sets button 1 as off
int buttonStateCC = 0; // sets button 2 as off

void setup()
{
  myservo.attach(crServo); // attaches the servo on pin 12 to the servo object
  pinMode (buttonPinCW, INPUT); // sets button as input
  pinMode (buttonPinCC, INPUT); // sets button as input
  pinMode (ledPinB, OUTPUT); // sets led as output
  pinMode (ledPinG, OUTPUT); // sets led as output
  pinMode (ledPinR, OUTPUT); // sets led as output
  myservo.write(crSpeedDefault); // default servo to crSpeedDefault
  startup();
}

int startup() {
  blinker(2, ledPinB);
  blinker(1, ledPinG);
  blinker(1, ledPinR);
}

void blinker(int count, int pin) {
    for ( int x = 0; x < count; x++ )
    {
      digitalWrite(pin, HIGH);
      delay(1000);
      digitalWrite(pin, LOW);
      delay(1000);
    }
}

void loop()
{
  buttonStateCW = digitalRead(buttonPinCW);
  buttonStateCC = digitalRead(buttonPinCC);
  // clockwise rotation
  if (buttonStateCW == HIGH) {
    digitalWrite(ledPinR, HIGH);
    myservo.write(crSpeedCW);
    // counterclockwise rotation
  } 
  else if (buttonStateCC == HIGH) {
    digitalWrite(ledPinG, HIGH);
    myservo.write(crSpeedCC);
  } 
  else {
    myservo.write(crSpeedDefault);
    digitalWrite(ledPinR, LOW); 
    digitalWrite(ledPinG, LOW);     // turn the LED off by making the voltage LOW
  }
}

更新了 RMI 的答案

#include <Servo.h>

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

// CONSTANTS

// PINS
const int crServo = 12; // sets pin 12 as servo
const int buttonPinCW = 2; // sets pin 2 as button; CW => clockwise => FOCUS FAR
const int buttonPinCC = 3; // sets pin 3 as button; CC => counterclockwise => FOCUS NEAR
const int ledPinB = 4; // sets pin 10 as LED
const int ledPinG = 5; // sets pin 10 as LED
const int ledPinR = 6; // sets pin 10 as LED

const int t = 1;  // slow down

// SERVO PROPERTIES
const int crSpeedDefault = 100; // is the stay still position, motor should not turn
const int crSpeedCW = 107; // turns the motor full speed clockwise
const int crSpeedCC = 87; // turns the motor full speed counter-clockwise

// SET BUTTON STATES
int buttonStateCW = 0; //sets button 1 as off
int buttonStateCC = 0; // sets button 2 as off

void setup()
{
  myservo.attach(crServo); // attaches the servo on pin 12 to the servo object
  pinMode (buttonPinCW, INPUT); // sets button as input
  pinMode (buttonPinCC, INPUT); // sets button as input
  pinMode (ledPinB, OUTPUT); // sets led as output
  pinMode (ledPinG, OUTPUT); // sets led as output
  pinMode (ledPinR, OUTPUT); // sets led as output
  myservo.write(crSpeedDefault); // default servo to crSpeedDefault
  startup();
}

int startup() {
  //blinker(2, ledPinB);
  //blinker(1, ledPinG);
  //blinker(1, ledPinR);
}

void blinker(int count, int pin) {
  for (int x = 0; x < count; x++)
  {
    digitalWrite(pin, HIGH);
    delay(1000);
    digitalWrite(pin, LOW);
    delay(1000);
  }
}

void loop()
{
  buttonStateCW = digitalRead(buttonPinCW);
  buttonStateCC = digitalRead(buttonPinCC);
  // clockwise rotation
  if (buttonStateCW == HIGH) {
    digitalWrite(ledPinR, HIGH);
    float speed = crSpeedCW;
    Serial.print("CLOCKWISE-ROTATION \n");
    for (int i = 0; i < t * 5; i++) {
      speed += ((float)crSpeedDefault - speed)/ 10;
      Serial.print(speed);
      Serial.print("\n");
      myservo.write((int)speed);
      delay(100);
    }
    myservo.write(crSpeedCW);
  } 
  else if (buttonStateCC == HIGH) {
      digitalWrite(ledPinG, HIGH);
      float speed = crSpeedCC;
      Serial.print("COUNTER-CLOCKWISE-ROTATION \n");
      for (int i = 0; i < t * 5; i++) {
        speed += ((float)crSpeedDefault - speed) / 10;
        Serial.print(speed);
        Serial.print("\n");
        myservo.write((int)speed);
        delay(100);
      }
      myservo.write(crSpeedCC);
    } 
  else {
    myservo.write(crSpeedDefault);
    digitalWrite(ledPinR, LOW); 
    digitalWrite(ledPinG, LOW);     // turn the LED off by making the voltage LOW
  }
}

【问题讨论】:

    标签: arduino


    【解决方案1】:

    试试这个。

    void loop()
    {
      ...
      // clockwise rotation
      if (buttonStateCW == HIGH) {
        digitalWrite(ledPinR, HIGH);
        float speed = crSpeedCW;
        for (int i = 0; i < t * 5; i++) {
            speed -= (speed - (float)crSpeedDefault) / 10;
            myservo.write((int)speed);
            delay(200);
        }
        myservo.write(crSpeedCW);
      } 
      else if (buttonStateCC == HIGH) {
        digitalWrite(ledPinG, HIGH);
        // Do the same here in reverse
        myservo.write(crSpeedCC);
      } 
      else {
        ...
      }
    }
    

    这将成倍地减慢速度。您必须调整硬编码数字以适应您的范围。

    【讨论】:

    • 您能否对方程式中的值 5 和 10 提供更多解释?您能否在上面的代码中指定反向的含义?此外,这很奇怪,但是对于顺时针旋转,电机从 101 转到 110 时,它应该从 110 开始并转到 100
    • 我已经将它更新为从 110 到 100。t * 5 指定了从 110 到 100 修改速度的次数。10 是一种指数减速(这里值越大,速度越低减速。200 是 1000ms/5。算法的工作原理是这样的。从 110 开始,取你必须走的增量。即 110 - 100 => 10。然后将下一个速度设置为该增量的 90%。即当前速度 - 增量 * 10% => 9. 在每次迭代中,您将速度设置为当前速度的一小部分,这是一种指数衰减。
    • 实际上这种算法在这种短范围内的整数表现不佳。您必须了解这个循环,然后尝试将其从 85 修改为 100。
    • 经过反复试验,我通过串行打印功能弄清楚了。我理解您所说的短程效果不佳的意思,因为我自己看到它只有在 t 非常“高”时才有效。不过还是谢谢你的回答!它解决了我的问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多