Page 1 of 1

PWM on raspberry pi 3

Posted: Fri Jun 03, 2016 3:45 pm
by smufdwag
In one application we are using the raspberry p to control motor speed via PWM. We were able to get a valid working code on the rapsberry pi 2, but when we transferred this code and drivers over to the pi 3 the code simply does not work. Is there any easy thing we are missing in switching from the pi 2 to the pi 3 to get this code working? Thank you for any help.

Code: Select all

#include <bcm2835.h>
#include <stdio.h>

#define PIN RPI_BPLUS_GPIO_J8_32
#define PIN2 RPI_BPLUS_GPIO_J8_33

#define PWM_CHANNEL 0
#define PWM_CHANNEL2 1

#define RANGE 1024

int main(int argc, char **argv)
//		bcm2835_delay(10000);
    if (!bcm2835_init())
	return 1;

    // Set the output pin to Alt Fun 5, to allow PWM channel 0 to be output there
    bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_ALT0);
    bcm2835_gpio_fsel(PIN2, BCM2835_GPIO_FSEL_ALT0);
    bcm2835_gpio_fsel(CTL_PIN, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(CTL_PIN2, BCM2835_GPIO_FSEL_OUTP);

    // Clock divider is set to 16.
    // With a divider of 16 and a RANGE of 1024, in MARKSPACE mode,
    // the pulse repetition frequency will be
    // 1.2MHz/1024 = 1171.875Hz, suitable for driving a DC motor with PWM
    bcm2835_pwm_set_mode(PWM_CHANNEL, 1, 1);
    bcm2835_pwm_set_range(PWM_CHANNEL, RANGE);
    bcm2835_pwm_set_mode(PWM_CHANNEL2, 1, 1);
    bcm2835_pwm_set_range(PWM_CHANNEL2, RANGE);

    // Vary the PWM m/s ratio between 1/RANGE and (RANGE-1)/RANGE
    int direction = 1;
    int data = 1;
    int j;
    bcm2835_gpio_write(CTL_PIN, HIGH);
	bcm2835_gpio_write(CTL_PIN2, HIGH);

    for (j=0;j<4096;j++)
	    if (j==2048) {
	      bcm2835_gpio_write(CTL_PIN, LOW);
//	      bcm2835_gpio_write(CTL_PIN2, LOW);
	if (data == 1)
	  direction = 1;
	else if (data == RANGE-1)
	  direction = -1;
	data += direction;
	  bcm2835_pwm_set_data(PWM_CHANNEL, data);
	  bcm2835_pwm_set_data(PWM_CHANNEL2, data);
	  bcm2835_pwm_set_data(PWM_CHANNEL, 0);
	  bcm2835_pwm_set_data(PWM_CHANNEL2, 0);

    return 0;

Re: PWM on raspberry pi 3

Posted: Fri Jun 03, 2016 10:44 pm
by MarkHaysHarris777
What is the failure?

... does it fail to compile?

... does it compile with warnings? (use the -Wall switch setting )

... does it compile, yet runs with errors?

... does it compile, yet runs with no errors, yet has unexpected results?

And, you might list the results you have so that we're not guessing. Thanks

Re: PWM on raspberry pi 3

Posted: Sat Jun 04, 2016 4:33 am
by smufdwag
failure = compiles, runs, and motors do not move at all.

Re: PWM on raspberry pi 3

Posted: Sat Jun 04, 2016 4:41 am
by MarkHaysHarris777
smufdwag wrote:failure = compiles, runs, and motors do not move at all.
ok, for your CTL_PIN(s) use instead :

board pin 35 GPIO19 (for channel 1)
board pin 12 GPIO18 (for channel 0)


Re: PWM on raspberry pi 3

Posted: Sat Jun 04, 2016 6:22 am
by gregeric
@smufdwag do you have access to a scope? Can you see PWM on your pins?

The core clock on the Pi3 is 400MHz, not 250, so your PWM frequency may be 1875Hz instead of the intended 1172. There may be insufficient time for the current to rise in the motor coils with those shortened pulses.

You might try setting the Pi3 core clock to 250MHz in /boot/config.txt, or set a lower PWM frequency in your code.

Re: PWM on raspberry pi 3

Posted: Sat Jun 04, 2016 7:49 am
by joan
The Pi3 is odd. Even if I put core_clock=400 in /boot/config.txt the reported frequency is 250.

Try the following

sudo pigpiod

pigs pfs 11 1000 # 1kHz
pigs pfs 14 1000 # 1kHz
pigs p 11 64 # 25% PWM
pigs hp 12 1000 250000 # 1kHz 25% (hardware) PWM
pigs hp 13 1000 250000 # 1kHz 25% (hardware) PWM
pigs p 14 64 # 25% PWM
pigs p 11 0 # Off
pigs p 12 0 # Off
pigs p 13 0 # Off
pigs p 14 0 # Off

Re: PWM on raspberry pi 3

Posted: Fri Dec 23, 2016 7:13 pm
by SteveA
I have exactly the same problem as per smufdwag, the original poster. The example PWM code as supplied with the bcm2835 lib and shown by smufdwag compiles and runs fine on my RPi2 and I can get a varying PWM signal on the 40W connector pin 12 (as seen on my scope and any connected devices).

When transfer and compiled on my RPI3 it will compile fine. All of my i/o routines work exactly fine and exactly the same as when compiled and run on the RPI2, except the PWM, which does not work at all.

The PWM is set to use channel 0, as that it the only available pin to use. The PWM pin level remains static as seen on an oscilloscope.

To check if it was a hardware fault, I obtained and tried it on other RPi3 devices and cannot get PWM to work at all. The PWM i/o pin is being set to ALT FUN 5, etc, as requred for PWM operation.

Here is a simple example of C code which works fine on RPI2 but not on RPI3, using bcm2835 lib (current version 1.51):

c = bcm2835_gpio_fsel(RPI_GPIO_P1_12, BCM2835_GPIO_FSEL_ALT5); // set PMW pin 40W connector 1 - pin 12 to alt5
c = bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_16); // info PRF = (PWM clock / divisor) / pwm range
c = bcm2835_pwm_set_mode(0, 1, 1); // pwm chan=0, markspace mode=1, pwm on=1
c= bcm2835_pwm_set_range(0, 1024); // range 1024 into channel 0
c = bcm2835_pwm_set_data(0, 300); // Set PWM data to say 300 to give a MSR of 1024:300
while(1) { // wait whilst monitoring pin 12 to see the PWM square wave
if (ScanKey(ALL)) break; // Just my test for any key press to break out

So, to recap, I am sure that it is not a hardware fault. In all instances they are run at sudo level.

For completeness, my Linux/Broadcom/GPU versions are
Linux version 4.4.38-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #938 SMP Thu Dec 15 15:22:21 GMT 2016

Dec 9 2016 15:11:26
Copyright (c) 2012 Broadcom
version 2e557d8dac70add28597c3b449cb52c34588d818 (clean) (release)

If anyone has experienced this on the RPI3 and found a cure, please let me know,

Re: PWM on raspberry pi 3

Posted: Fri Dec 23, 2016 8:52 pm
by joan should work (need to sudo pigpiod before entering the pigs command).