C语言 使用带有wiringPi的硬件PWM控制带有树莓派的伺服器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20081286/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Controlling a servo with raspberry pi using the hardware PWM with wiringPi
提问by user2543697
I tried controlling the servo with softPwm using the wiringPi Library but this made the servo stutter. Therefore I want to use the hardware PWM pin on the Raspberry Pi (GPIO18) with the wiringPi library. But I don't understand how to set the frequency to 50 Hz and change the duty cycle to have a pulse width ranging from 0.8 ms to 2.5 ms.
我尝试使用 WiringPi 库通过 softPwm 控制伺服,但这导致伺服卡顿。因此,我想将 Raspberry Pi (GPIO18) 上的硬件 PWM 引脚与 WiringPi 库一起使用。但我不明白如何将频率设置为 50 Hz 并将占空比更改为具有 0.8 ms 到 2.5 ms 的脉冲宽度。
I found the following relationship on the internet (i dont know if it is correct):
我在网上找到了如下关系(不知道对不对):
pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange.
i know the clock divisor max value is something around 4000 and the Raspberry Pi PWM clock has a base frequency of 19.2 MHz. so this gives me ~4,8KHz.
我知道时钟分频器的最大值约为 4000,而 Raspberry Pi PWM 时钟的基频为 19.2 MHz。所以这给了我 ~4,8KHz。
i already got these settings which should give me ~50Hz using the following relationship:
我已经得到了这些设置,使用以下关系应该给我 ~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) ;
I dont got a oscilloscope to test the output signal to check what setting changes what. this makes it hard to find it out myself.
我没有示波器来测试输出信号来检查什么设置改变了什么。这使得我自己很难找到它。
Long story short: Can anyone tell me how I can achieve a duty cycle with a pulse width of 0,8ms to 2,1ms for controlling a servo using the hardware PWM on the Raspberry Pi.
长话短说:谁能告诉我如何使用 Raspberry Pi 上的硬件 PWM 来实现脉冲宽度为 0.8ms 到 2.1ms 的占空比来控制伺服。
采纳答案by gat
How about using RPIO instead? Here's the link to the library: http://pythonhosted.org/RPIO/index.html
改用 RPIO 怎么样?这是图书馆的链接:http: //pythonhosted.org/RPIO/index.html
Here's the PWM example: http://pythonhosted.org/RPIO/pwm_py.htmlAnd you may also use the C source directly: https://github.com/metachris/RPIO/tree/master/source/c_pwm
这是 PWM 示例:http: //pythonhosted.org/RPIO/pwm_py.html你也可以直接使用 C 源代码:https: //github.com/metachris/RPIO/tree/master/source/c_pwm
回答by Koen
I'm a complete newby to Pi and to Servo's. But I got it to work with wiringPi.
我是 Pi 和 Servo 的新手。但我让它与wiringPi一起工作。
It says herethat we're looking to create pulse of 1ms to 2ms in length, every 20ms or so. Assuming this 19.2Mhz base clock is indeed correct, setting pwm clock to 400 and pwm range to 1000, should give a pulse at 48Hz or every 20.8 ms. Then setting pwm value to 48 should give you a 1ms long pulse and a pwm value of 96 should give you a 2ms long pulse. But you need to set the chip in pwm-ms mode. (Lots of shoulds here, since I do not have an osciolloscope either)
它在这里说,我们希望每 20 毫秒左右创建 1 到 2 毫秒长度的脉冲。假设这个 19.2Mhz 基本时钟确实是正确的,将 pwm 时钟设置为 400 并将 pwm 范围设置为 1000,应该以 48Hz 或每 20.8 ms 给出一个脉冲。然后将 pwm 值设置为 48 应该会给你一个 1ms 长的脉冲,而 96 的 pwm 值应该会给你一个 2ms 长的脉冲。但是需要将芯片设置为pwm-ms模式。(这里有很多应该,因为我也没有示波器)
So to set it up:
所以要设置它:
- gpio mode 1 pwm
- gpio pwm-ms
- gpio pwmc 400
- gpio pwmr 1000
- gpio 模式 1 pwm
- gpio pwm-ms
- GPIO pwmc 400
- GPIO pwmr 1000
And then you can turn the servo from left to right via
然后你可以通过从左到右转动伺服
- gpio pwm 1 48
- gpio pwm 1 96
- GPIO PWM 1 48
- GPIO PWM 1 96
(Actually, the servo I got worked from 28 up to 118; could be the servo) (The setup sequence seems important; could be a bug)
(实际上,我从 28 到 118 工作的舵机;可能是舵机)(设置顺序似乎很重要;可能是一个错误)
回答by user1606576
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 ;
Make sure you are using correct gpio pins!
确保您使用的是正确的 gpio 引脚!
Models A and B have one hardware PWM on pin 18 BCM (1 wPi).
模型 A 和 B 在引脚 18 BCM (1 wPi) 上有一个硬件 PWM。
Models A+ and B+ can output second hardware pwm on pins 13 and 19 BCM (23, 24 wPi)
型号 A+ 和 B+ 可以在引脚 13 和 19 BCM(23、24 wPi)上输出第二个硬件 pwm
回答by Scott
I got wiringPi to do it through software bit-banging. I might have tried RPIO but my particular application requires that the audio output works, and I understand that RPIO's DMA makes audio go away. I might have also tried wiringPi's softPwm or even softServo, but I also require to run a DC motor through PWM, and I don't want to bring the whole system down to 50Hz just for the servo.
我让wiringPi通过软件位敲击来做到这一点。我可能尝试过 RPIO,但我的特定应用程序要求音频输出正常工作,而且我知道 RPIO 的 DMA 会使音频消失。我可能也尝试过 WiringPi 的 softPwm 甚至 softServo,但我还需要通过 PWM 运行直流电机,而且我不想将整个系统降低到 50Hz 仅用于伺服。
This program worked as a demonstration, has no jitter (because it doesn't continuously drive the positioning pulses), and lands on its target each time with a visibly indistinguishable error. Granted the Pi isn't doing much else at the time to interfere with the program's timing (except running an X server through SSH, gedit, terminal session, everything in top, etc.).
该程序用作演示,没有抖动(因为它不会连续驱动定位脉冲),并且每次降落在目标上时都会出现明显无法区分的错误。授予 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 );
}
}
My servo is a Radio Shack Micro Servo, which appears identical to the other "micro" servos out there. I also found I could ditch the inverter and just drive the signal using the 3.3V GPIO.
我的伺服器是 Radio Shack 微型伺服器,它看起来与其他“微型”伺服器相同。我还发现我可以放弃逆变器并使用 3.3V GPIO 驱动信号。

