我尝试使用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的占空比。
答案 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模式。 (这里有很多应有的,因为我也没有示波器)
所以要设置它:
然后你可以通过
从左到右转动伺服(实际上,伺服我从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驱动信号。