Servo control using raspberry pi using hardware-based PWM wired Pi

I tried to control the servo using softPwm using the wiringPi library, but it made the servo stutter. So I want to use the PWM pin of the equipment 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 so that the pulse width is from 0.8 ms to 2.5 ms.

I found the following relationships on the Internet (I don't know if this is correct):

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

I know that the maximum number of clock dividers is about 4000, and the PWM PWM watch for raspberries has a base frequency of 19.2 MHz. so this gives me ~ 4.8 kHz.

I already got these settings, which should give me ~ 50 Hz using the following ratio:

 //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 do not have an oscilloscope to check the output signal to check which settings are changing. this makes it difficult to find.

In short: Can anyone tell me how I can achieve a duty cycle with a pulse width of 0.8 ms to 2.1 ms for controlling a servo using a hardware PWM on a raspberry pie.

+8
c raspberry-pi pwm
source share
5 answers

How about using RPIO? Here is a link to the library: http://pythonhosted.org/RPIO/index.html

Here's a PWM example: http://pythonhosted.org/RPIO/pwm_py.html And you can also use the C source directly: https://github.com/metachris/RPIO/tree/master/source/c_pwm

+2
source share

I am a complete newbie to Pi and Servo's. But I got it for working with wiring.

It says here that we want to create a pulse from 1 ms to 2 ms long, every 20 ms or so. Assuming that this 19.2Mhz base clock is indeed correct, setting pwm clock to 400 and pwm range to 1000 should give a pulse at a frequency of 48 Hz or every 20.8 ms. Then setting pwm to 48 should give you a 1 ms pulse, and pwm 96 should give you a 2 ms pulse. But you need to install the chip in pwm-ms mode. (There are a lot of bags, since I don’t have an oscilloscope)

So, to configure:

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

And then you can turn on the servo from left to right through

  • gpio pwm 1 48
  • gpio pwm 1 96

(Actually, the servo I received from 28 to 118 may be a servo) (The setup sequence seems important, it may be a mistake)

+7
source share
 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 use the correct gpio contacts!

Models A and B have one hardware PWM on pin 18 BCM (1 wPi).

Models A + and B + can output a second hardware pwm to pins 13 and 19 of the BCM (23, 24 wPi)

+5
source share

I got wiring to do this through a beat-beat software. I might have tried RPIO, but my specific application requires the audio output to work, and I understand that RPIO DMA makes the sound muted. Perhaps I also tried plugPi softPwm or even softServo, but I also need to start the DC motor through PWM, and I do not want to bring the entire system to 50 Hz for servo only.

This program worked as a demonstration, has no jitter (because it does not constantly control the positioning pulses) and each time it lands on its target with an obvious indistinguishable error. The Pi provided does nothing else at the time to interfere with the program time (except for starting the X server through SSH, gedit, a terminal session, just top , etc.).

 // 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 the Radio Shack Micro Servo microserver, which is similar to other "micro" servos. I also found that I could turn off the inverter and just control the signal using GPV 3.3V.

0
source share

Please use hardware PWM and periodically call pwmWrite with the same value. There are glitches that make it impossible to use it. You have nothing like a shadow register or a variable that reloads when counter = 0 ?

-2
source share

All Articles