Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arduino 如何编程ESC以增量增加/减少PWM_Arduino_Robotics_Pwm - Fatal编程技术网

Arduino 如何编程ESC以增量增加/减少PWM

Arduino 如何编程ESC以增量增加/减少PWM,arduino,robotics,pwm,Arduino,Robotics,Pwm,我以前用Python编写过代码,但是我正在学习C语言,据我所知,Arduino在某些方面与C语言非常相似(至少在编码方面是如此)。我注意到,当我在我的机器人上运行代码时,由于PWM的快速变化,它会震动。因此,我想要一些关于如何在Arduino上执行if语句的指导,因为我试图以增量增加/减少PWM //On Roboclaw set switch 1 and 6 on. // <-- what does this refer to? //mode 2 option 4 // <-- m

我以前用Python编写过代码,但是我正在学习C语言,据我所知,Arduino在某些方面与C语言非常相似(至少在编码方面是如此)。我注意到,当我在我的机器人上运行代码时,由于PWM的快速变化,它会震动。因此,我想要一些关于如何在Arduino上执行if语句的指导,因为我试图以增量增加/减少PWM

//On Roboclaw set switch 1 and 6 on. // <-- what does this refer to?
//mode 2 option 4 // <-- my note based on user manual pg 26


#include <Servo.h> 


Servo myservo1;  // create servo object to control a Roboclaw channel
Servo myservo2;  // create servo object to control a Roboclaw channel

//int pos = 0;    // variable to store the servo position  //<-- left-over from arduino ide servo sweep example?

void setup() 
{ 
  myservo1.attach(9);  // attaches the RC signal on pin 5 to the servo object (Left Motor)
  myservo2.attach(11);  // attaches the RC signal on pin 6 to the servo object (Right Motor)
} 


void loop() 
{ 
  //forward
  myservo1.writeMicroseconds(1000);
  myservo2.writeMicroseconds(1000);
  delay(2000);

  //backward
  myservo1.writeMicroseconds(2000);
  myservo2.writeMicroseconds(2000);
  delay(2000);

  //left
  myservo1.writeMicroseconds(1500);
  myservo2.writeMicroseconds(1000);
  delay(2000);

  //right
  myservo1.writeMicroseconds(1000);
  myservo2.writeMicroseconds(1500);
  delay(2000);

}

//在Roboclaw上设置开关1和6。// 好的,每当你向伺服写入一个不同的值时,它会尽快移动到那个位置。所以你需要一步一步地移动你的伺服

但是,对于此任务,您将无法使用延迟,因为它们会阻塞处理器。您需要模拟“无延迟闪烁”示例(即,当时间流逝时,使用millis()函数执行某些操作)

加速度控制只是每X毫秒移动1°(在本例中为6ms,使整个移动-180°-持续约1秒)。因此,uC每X毫秒向目标位置移动1°。在其他代码中,您只需将目标设置到所需位置,即可完成

这是我写的代码。让我知道它是否适合你

#include <Servo.h> 

Servo myservo1;
Servo myservo2;
unsigned long prevMillisAccel = 0, prevMillisAction = 0;
uint8_t servo1_target;
uint8_t servo2_target;
uint8_t currAction;

#define TIME_FOR_ONE_DEGREE_MS 6

void setup()
{
    myservo1.attach(9)
    myservo2.attach(11);
    prevMillisAccel = millis();
    prevMillisAction = millis();
    servo1_target = 0;
    servo2_target = 0;
    myservo1.write(0);
    myservo2.write(0);
    currAction = 0;
}

void moveServoTowardsTarget(Servo *servo, uint8_t target)
{
    uint8_t pos = servo->read();
    if (pos > target)
        servo->write(pos-1);
    else if (pos < target)
        servo->write(pos+1);
}

void loop()
{
    unsigned long currMillis = millis();
    if (currMillis - prevMillisAccel >= TIME_FOR_ONE_DEGREE_MS)
    {
        prevMillisAccel += TIME_FOR_ONE_DEGREE_MS;

        moveServoTowardsTarget(&myservo1, servo1_target);
        moveServoTowardsTarget(&myservo2, servo2_target);
    }

    if (currMillis - prevMillisAction >= 2000)
    {
        prevMillisAction += 2000;
        currAction = (currAction + 1) % 4;
        switch(currAction)
        {
            case 0: // forward
                servo1_target = 0;
                servo2_target = 0;
                break;
            case 1: // backward
                servo1_target = 180;
                servo2_target = 180;
                break;
            case 2: // left
                servo1_target = 90;
                servo2_target = 0;
                break;
            case 3: // right
                servo1_target = 0;
                servo2_target = 90;
                break;
        }
    }
}
#包括
伺服myservo1;
伺服myservo2;
无符号长prevMillisAccel=0,prevMillisAction=0;
uint8_t伺服1_目标;
uint8_t伺服2_目标;
uint8_t货币;
#定义一个学位的时间6
无效设置()
{
myservo1.附件(9)
myservo2.附件(11);
prevMillisAccel=millis();
prevMillisAction=millis();
伺服1_目标=0;
伺服2_目标=0;
myservo1.write(0);
myservo2.write(0);
货币=0;
}
无效向StarGet移动伺服(伺服*伺服,uint8_t目标)
{
uint8_t pos=伺服->读取();
如果(位置>目标)
伺服->写入(位置1);
否则如果(位置<目标)
伺服->写入(位置+1);
}
void循环()
{
无符号长电流毫秒=毫秒();
如果(currMillis-prevMillisAccel>=一度的时间)
{
prevMillisAccel+=一度的时间;
向StarGet(和myservo1、servo1_目标)移动伺服;
将ServorTowardStarGet(和myservo2、servo2_目标)移动;
}
如果(当前毫秒-当前毫秒数>=2000)
{
预测值+=2000;
货币=(货币+1)%4;
开关(电流动作)
{
案例0://转发
伺服1_目标=0;
伺服2_目标=0;
打破
案例1://向后
伺服1_目标=180;
伺服2_目标=180;
打破
案例2://左
伺服1_目标=90;
伺服2_目标=0;
打破
案例3://对
伺服1_目标=0;
伺服2_目标=90;
打破
}
}
}

另外,我使用了
write
函数而不是writeMicroseconds,因为你可以
读取你写的值。如果你真的需要使用
writeMicroseconds
(在我看来这是非常无用的,因为伺服精度小于1°,所以
write
就足够了)只需将目标存储为
uint16\t
,并同时存储最后一个设置值(并使用该设置值而不是
read
函数)

web上充斥着关于如何执行If语句的C/C++教程。因此,请尝试一下,如果代码不起作用,请显示代码,让我们看看我们能做些什么。