0

I try to use hardware PWM on RPI 3b+ (Linux 11 bullseye) by using bcm2835.h (ver. 1.71) with small C code given below

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

int main(int argc, char **argv)
{
    if (!bcm2835_init()) return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 2);
    bcm2835_pwm_set_data(0, 1);
    bcm2835_close();

    return 0;
}

It was compiled, built and run with no errors, but oscilloscope connected to corresponding pin shows that output signal has duty cycle approx ~ 99%, not 50%, as expected. Changing corresponding argument in bcm2835_pwm_set_data() has no effect, duty cycle does not change. Changing arguments in bcm2835_pwm_set_clock() and bcm2835_pwm_set_range(0, 2) result in frequency changing, but duty cycle does not varying! Why it could be?

mock_up
  • 1
  • 2

1 Answers1

0

This is a very old library and little used. See https://raspberrypi.stackexchange.com/a/117592/8697 for comparison of libraries.

AFAIK you need to use sudo to access hardware PWM - it applies to most libraries attempting hardware PWM. It may work if you set suid on the compiled binary.

It is possible with pigpio (using the daemon and socket or pipe interface); WiringPi (deprecated) and my pi-gpio (both require sudo) and in python with Pi.GPIO (also requiring sudo).

For interest the following is one of my test programs using pi-gpio.

/*
This is a hardware PWM test program
It generates 2 PWM outputs @10kHz with differing duty cycles

 cc -Wall -o hwPWMtest -lpi-gpio -lpthread -lm -lcrypt -lrt hwPWMtest.c
 2021-10-16
*/

#include <stdio.h>
#include <string.h>

#include <pi-gpio.h>

#define PWM0 12 // this is physical pin 32
#define PWM1 13 // this is physical pin 33

int main(int argc, char *argv[]) {
  rpi_info info;
  // Pi3 & earlier have 19.2MHz clock
  // The following gives a precise 10kHz signal
  int DIVIDER = 15;
  int RANGE = 128;
  setup();

  get_rpi_info(&info);

  if (strcmp(info.processor, "BCM2711") == 0) {
    // Pi4 has 54MHz clock
    DIVIDER = 45;
    RANGE = 120;
  }

  pwmSetGpio(PWM0);
  pwmSetGpio(PWM1);

  pwmSetMode(PWM_MODE_MS); // use a fixed frequency
  pwmSetClock(DIVIDER);    // gives a precise 10kHz signal

  pwmSetRange(PWM0, RANGE);
  pwmWrite(PWM0, RANGE / 4); // duty cycle of 25%

  pwmSetRange(PWM1, RANGE);
  pwmWrite(PWM1, RANGE / 2); // duty cycle of 50%
    cleanup();
  return 0; // PWM output stays on after exit
}
Milliways
  • 54,718
  • 26
  • 92
  • 182
  • Thanks a lot! I newbie in RPI programming and i started it with bcm2835 lib. What is the most commonly used GPIO lib for RPI C-programming now? – mock_up Apr 13 '22 at 11:46
  • @mock_up With the demise of WiringPi there was no suitable library (pigpo is incredibly capable but due to its limitations only really usable through socket or pipe interface) - as a result I wrote my own which provides basic interfaces, but I use also use pigpio - mainly with python. NOTE I have used bcm2835, but object to statically linked code. – Milliways Apr 13 '22 at 11:56
  • And back to bcm2835 lib. Yes, its a very old lib, but it still updates. My interest in RPI GPIO programming not only in PWM, but in general IO, events, "interrups", I2C and SPI interfaces too. And i use sudo to access to hardware PWM, but 2835 lib seems to work incorrect. Does pigpio support operation with events, "interrups", I2C and SPI? – mock_up Apr 13 '22 at 12:09
  • @mock_up I suggest you look at pigpio site http://abyz.me.uk/rpi/pigpio/index.html. In practice I select the best tool for the task in hand (often python using gpiozero ) and use all. – Milliways Apr 13 '22 at 12:22
  • thanks! It seems very interesting. – mock_up Apr 13 '22 at 12:29
  • @Milliways: You consistently claim that `WiringPi` is deprecated, or refer to its *demise*. As I've explained, wiringPi is still available from their GitHub site, and available for `bullseye` as a `.deb` file - easily installed and quite functional AFAICS. Is your experience different? – Seamus Apr 14 '22 at 22:35
  • @Seamus The **author** says it is deprecated. Some others had a half baked attempt, based on an earlier source. Last time I tried this had a number of bugs (some so obvious I was amazed they weren't fixed) - I concluded the project lacks the rigorous testing that Gordon did. If you are so concerned convince Gordon to release his latest source (which he originally said he would do). It is no longer included in Raspberry Pi OS. You are entitled to your opinion. The "clone" should really have been renamed (as I did for my RPi.GPIO clone) to avoid confusion. – Milliways Apr 15 '22 at 00:29
  • @Milliways: This seems to be where you consistently get confused: Gordon *was* the author, but is no longer the maintainer. The [WiringPi team](https://github.com/WiringPi) has done a credible job of resurrecting the code, and they are working at maintenance/upgrades. I don't know why you feel the need to denigrate their efforts constantly. Of course you are also entitled to ***your*** opinion, but you never state it as an opinion - you state it as fact. This is why I object. – Seamus Apr 15 '22 at 07:09