使用操纵杆时舵机运动更顺畅 - Arduino

问题描述 投票:0回答:1

我有一个 Arduino 项目,其中我使用操纵杆模块移动 2 个伺服系统。效果不错,但动作一点也不流畅。我观看了许多有关插值的视频,但不知道如何在现有代码中实现它。你能帮我吗?

这是我使用的代码:

#include <Servo.h>

#define SERVO_PIN 9
#define GROUND_JOY_PIN A3            //joystick ground pin will connect to Arduino analog pin A3
#define VOUT_JOY_PIN A2              //joystick +5 V pin will connect to Arduino analog pin A2
#define XJOY_PIN A1                  //X axis reading from joystick will go into analog pin A1
#define YJOY_PIN A0

Servo myservoX;
Servo myservoY;

 
void setup()
{
 Serial.begin(9600);
 pinMode(VOUT_JOY_PIN, OUTPUT) ;    //pin A3 shall be used as output
 pinMode(GROUND_JOY_PIN, OUTPUT) ;  //pin A2 shall be used as output
 digitalWrite(VOUT_JOY_PIN, HIGH) ; //set pin A3 to high (+5V)
 digitalWrite(GROUND_JOY_PIN,LOW) ; //set pin A3 to low (ground)
 myservoX.attach(9);
 myservoY.attach(6);
}
 
void loop()
{                    
 int joystickXVal = analogRead(XJOY_PIN) ;  //read joystick input on pin A1
 Serial.print(joystickXVal);                //print the value from A1
 Serial.println(" = input from joystick");  //print "=input from joystick" next to the value
 Serial.print((joystickXVal+520)/5);       //print a from A1 calculated, scaled value
 Serial.println(" = output to servo");      //print "=output to servo" next to the value
 Serial.println() ;

 myservoX.write((joystickXVal+520)/10);      //write the calculated value to the servo  
                    
 int joystickYVal = analogRead(YJOY_PIN) ;  //read joystick input on pin A1
 Serial.print(joystickYVal);                //print the value from A1
 Serial.println(" = input from joystick");  //print "=input from joystick" next to the value
 Serial.print((joystickYVal+520)/5);       //print a from A1 calculated, scaled value
 Serial.println(" = output to servo");      //print "=output to servo" next to the value
 Serial.println() ;
 myservoY.write((joystickYVal+520)/10);      //write the calculated value to the servo  
}

我尝试使用延迟,但没有成功

arduino smoothing joystick servo
1个回答
0
投票

将输入映射到输出

在最常见的 Arduino 板上,

analogRead

 的返回值为 0 到 1023 之间的数字。如果您不确定特定微处理器的模拟值范围,请查看文档。

写入伺服器的输出应该是 0 到 180 之间的值,对应于以度为单位的角度。如果你写90,那么舵机应该转到中间位置。许多舵机可以旋转整个 180 度(甚至更多),但有些舵机的范围更有限。

将模拟输入可靠地转换为伺服输出的一种简单方法是 Arduino

map

 功能:

int joystickXVal = analogRead(XJOY_PIN); int servoX = map(joystickXVal, 0, 1023, 0, 180); myservoX.write(servoX);
低通滤波

为了获得平滑的运动,您可以对操纵杆输入、伺服输出或两者应用滤波。

由于控制电路和伺服机构的物理原理,输出侧已经有一些滤波,所以我通常从平滑输入开始。

一个简单有效的方法是使用

指数平滑

// We use a static (or global) variable to persist the filtered // position of the joystick. static int xVal = 512; // Update the filtered position by doing a weighted average // with the "instantaneous" reading. int joystickXVal = analogRead(XJOY_PIN); xVal = (7*xVal + joystickXVal) / 8; // Note that we now use xVal, the filtered position, when // figuring out where we want the servo. int servoX = map(xVal, 0, 1023, 0, 180); myservoX.write(servoX);
如果您大约定期更新位置,则此方法效果很好。

与分配给瞬时读数的权重相比,您对现有位置的权重越大,变化就越平滑。不过,如果朝这个方向走得太远,您会发现舵机明显滞后于操纵杆。

请注意,由于我们使用 int 值,因此我们必须警惕平均整数的陷阱和可能的溢出。这就是为什么我设置表达式最后进行除法,以及为什么我选择系数以确保中间结果不会超过 2^15。

© www.soinside.com 2019 - 2024. All rights reserved.