使用带有接线端子的硬件PWM控制带有树莓派的伺服

时间:2013-11-19 20:23:09

标签: c raspberry-pi pwm

我尝试使用wiringPi Library使用softPwm控制伺服,但这使得伺服卡顿。 因此,我想使用Raspberry Pi(GPIO18)上的硬件PWM引脚和wiringPi库。 但我不明白如何将频率设置为50 Hz并将占空比更改为脉冲宽度范围为0.8 ms至2.5 ms。

我在互联网上发现了以下关系(我不知道它是否正确):

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange.

我知道时钟除数最大值大约为4000,而Raspberry Pi PWM时钟的基本频率为19.2 MHz。所以这给了我~4,8KHz。

我已经得到了这些设置,应该使用以下关系给我~50Hz:

//put PWM in mark-space mode, which will give you 
//the traditional (and easily predictable) PWM    
pwmSetMode(PWM_MODE_MS);
//setting ping GPIO 18 as a pwm output
pinMode(18,PWM_OUTPUT);
//Set clock divisor to 4000
pwmSetClock(4000);
pwmSetRange (10) ;

我没有示波器来测试输出信号以检查什么设置改变了什么。这让我很难自己找到它。

长话短说: 任何人都可以告诉我如何使用Raspberry Pi上的硬件PWM控制伺服的脉冲宽度为0.8ms到2,1ms的占空比。

4 个答案:

答案 0 :(得分:8)

我是Pi和Servo的完整新手。但是我让它与wiringPi一起工作。

它说here我们正在寻找创建长度为1ms到2ms的脉冲,每20ms左右。假设这个19.2Mhz基本时钟确实是正确的,将pwm时钟设置为400并且pwm范围设置为1000,应该给出48Hz或每20.8ms的脉冲。然后将pwm值设置为48应该给你一个1ms长的脉冲,pwm值为96应该给你一个2ms长的脉冲。 但您需要将芯片设置为pwm-ms模式。 (这里有很多应有的,因为我也没有示波器)

所以要设置它:

  • gpio mode 1 pwm
  • gpio pwm-ms
  • gpio pwmc 400
  • gpio pwmr 1000

然后你可以通过

从左到右转动伺服
  • gpio pwm 1 48
  • gpio pwm 1 96

(实际上,伺服我从28到118工作;可能是伺服) (设置顺序似乎很重要;可能是一个错误)

答案 1 :(得分:5)

if (wiringPiSetup () == -1) //using wPi pin numbering
 exit (1) ;

pinMode(1, PWM_OUTPUT);
pwmSetMode(PWM_MODE_MS); 
pwmSetClock(384); //clock at 50kHz (20us tick)
pwmSetRange(1000); //range at 1000 ticks (20ms)
pwmWrite(1, 75);  //theretically 50 (1ms) to 100 (2ms) on my servo 30-130 works ok
return 0 ;

确保使用正确的gpio引脚!

型号A和B在引脚18 BCM(1 wPi)上有一个硬件PWM。

模型A +和B +可以在引脚13和19 BCM(23,24 wPi)上输出第二个硬件pwm

答案 2 :(得分:2)

如何使用RPIO呢?这是图书馆的链接:http://pythonhosted.org/RPIO/index.html

这是PWM示例:http://pythonhosted.org/RPIO/pwm_py.html 您也可以直接使用C源:https://github.com/metachris/RPIO/tree/master/source/c_pwm

答案 3 :(得分:0)

我通过软件bit-banging得到了wirePi。我可能尝试过RPIO,但我的特定应用要求音频输出有效,而且我知道RPIO的DMA会让音频消失。我可能也尝试过wirePi的softPwm甚至是softServo,但我还要求通过PWM运行直流电机,我不想将整个系统降低到50Hz只是为了伺服。

该程序用作演示,没有抖动(因为它不会连续驱动定位脉冲),并且每次都会出现明显无法区分的错误。当然,Pi当时没有做太多干扰程序的时间安排(除了通过SSH,gedit,终端会话,top中的所有内容运行X服务器等)。

// Servo trial 11/15/14 by SLC

#include <wiringPi.h>

#include <stdio.h>
#include <unistd.h>

int main()
{
    wiringPiSetup();
    pinMode( 6, OUTPUT );
    digitalWrite( 6,  HIGH );

    int idx = 0, tries = 0;
    while ( tries++ < 30 )
    {
        int i;
        const int period[] = { 500, 1500, 2500 };

        printf( "Setting period to %i ms\n", period[idx] );
        for ( i = 0; i < 20; ++i )
        {
            // Output going through an inverter (to convert 3.3V to 5V)
            digitalWrite( 6, LOW );
            usleep( period[idx] );
            digitalWrite( 6,  HIGH );
            usleep( 20 * 1000 );
        }
        ++idx;
        idx %= 3;

        sleep( 2 );
    }
}

我的伺服系统是Radio Shack Micro Servo,看起来与其他“微型”伺服系统完全相同。我还发现我可以放弃逆变器并使用3.3V GPIO驱动信号。