Coder Social home page Coder Social logo

bcm2835_software_pwm's Introduction

bcm2835_software_pwm

Adds support for software pwm for the bcm2835 C library

Advantages and Disadvantages of Software PWM

The speed of software pwm is much slower than using hardware PWM. The Raspberry Pi's hardware PWM runs at 19,200,000 Hertz. That means you get one period every 52 nanoseconds. 1s/19.2 MHz = 52.08

Hardware pwm is great if you need reliabiliy and precision. However, the hardware pwm on a raspberry pi is limited to four output pins and only two channels. If you wanted to light up an RGB LED using pwm, that wouldn't be possible because you would need three separate channels. That's where using software pwm would be more beneficial.

Software pwm is slower than hardware pwm, but it allows you to use any output pin and is not restricted to two channels. This software pwm is default configured to run at 60 Hertz. Meaning you get one period every 16 milliseconds. Software pwm is better if you need more than two channels, and reliability and precision are flexible.

Example Code

Controlling an LED's brightness

#include <signal.h>
#include <stdio.h>
#include <bcm2835.h>
#include "bcm2835_software_pwm.h"

#define GPIO_12 RPI_V2_GPIO_P1_32
#define GPIO_13 RPI_V2_GPIO_P1_33
#define GPIO_18 RPI_V2_GPIO_P1_12
#define GPIO_19 RPI_V2_GPIO_P1_35

#define RANGE 1024
#define CHANNEL_0 0
#define CHANNEL_1 1

void sigIntHandler() {
    // stops all threads and deallocates memory
    bcm2835_software_pwm_close();

    // turns all LEDs off
    bcm2835_gpio_write(GPIO_12, LOW);
    bcm2835_gpio_write(GPIO_13, LOW);
    bcm2835_gpio_write(GPIO_18, LOW);
    bcm2835_gpio_write(GPIO_19, LOW);

    // closes the bcm2835 library
    bcm2835_close();
    exit(0);
}

int main() {
    if (!bcm2835_init()) {
        return 1;
    }

    // set's up a ctrl + c handler to shut down the program and clean up resources
    signal(SIGINT, sigIntHandler);

    // create an arbitrary channel 0
    bcm2835_software_pwm_create_channel(CHANNEL_0);
    // sets the range of the channel to RANGE
    bcm2835_software_pwm_set_range(CHANNEL_0, RANGE);
    // assigns the pins GPIO_12 & GPIO_13 as output pins on channel 0
    bcm2835_software_pwm_assign_pin_to_channel(CHANNEL_0, GPIO_12);
    bcm2835_software_pwm_assign_pin_to_channel(CHANNEL_0, GPIO_13);

    // create an arbitrary channel 1
    bcm2835_software_pwm_create_channel(CHANNEL_1);
    // sets the range of the channel to RANGE
    bcm2835_software_pwm_set_range(CHANNEL_1, RANGE);
    // assigns the pins GPIO_18 & GPIO_19 as output pins on channel 1
    bcm2835_software_pwm_assign_pin_to_channel(CHANNEL_1, GPIO_18);
    bcm2835_software_pwm_assign_pin_to_channel(CHANNEL_1, GPIO_19);

    // starts two new threads for channels 0 and 1
    bcm2835_software_pwm_start_all_channels();

    int direction = 1; // 1 is increase, -1 is decrease
    int data = 0;
    while (1) {
        if (data == 0) {
            direction = 1;   // Switch to increasing
        }
        else if (data == RANGE - 1) {
            direction = -1;  // Switch to decreasing
        }
        data += direction;

        // sets the data on channel 0 to data
        bcm2835_software_pwm_set_data(CHANNEL_0, data);
        // sets the data on channel 0 to data
        bcm2835_software_pwm_set_data(CHANNEL_1, data);

        // delays for one second before continuing
        bcm2835_delay(1);
    }
}

Adjusting a passive buzzers frequency

#include <signal.h>
#include <stdio.h>
#include <bcm2835.h>
#include "bcm2835_software_pwm.h"

#define PASSIVE_BUZZER RPI_V2_GPIO_P1_33
#define FREQUENCY_LOW 1      // frequency in Hertz
#define FREQUENCY_HIGH 1000  // frequency in Hertz

// define a range of 2
// data 0 will be off
// data 1 will be 50% on, 50% off a.k.a. alternating current
// data 2 will be 100% on         a.k.a. direct current
#define RANGE 2
#define CHANNEL_0 0

void sigIntHandler() {
    // stops all threads and deallocates memory
    bcm2835_software_pwm_close();
    
    // set passive buzzer output to low
    bcm2835_gpio_write(PASSIVE_BUZZER, LOW);
    // closes the bcm2835 library
    bcm2835_close();
    exit(0);
}

int main() {
    if (!bcm2835_init()) {
        return 1;
    }

    signal(SIGINT, sigIntHandler);

    // create an arbitrary channel 0
    bcm2835_software_pwm_create_channel(CHANNEL_0);
    // sets the range of the channel to RANGE
    bcm2835_software_pwm_set_range(CHANNEL_0, RANGE);
    // sets the data of the channel to a constant 1
    // data 0 will be off
    // data 1 will be 50% on, 50% off a.k.a. alternating current
    // data 2 will be 100% on         a.k.a. direct current
    bcm2835_software_pwm_set_data(CHANNEL_0, 1);
    // assigns the pin of the passive buzzer as output pins on channel 0
    bcm2835_software_pwm_assign_pin_to_channel(CHANNEL_0, PASSIVE_BUZZER);

    // starts a thread for channel 0
    bcm2835_software_pwm_start_all_channels();

    while (1) {
        for (int i = FREQUENCY_LOW; i < FREQUENCY_HIGH; i++) {
            // sets the frequency to adjust the output sound
            bcm2835_software_pwm_set_frequency(i);
            // give it some time to play the sound
            bcm2835_delay(5);
        }
    }
}

Library Documentation

Set Frequency

  Sets the software frequency in Hertz to the value passed in to the frequency parameter
    Setting the frequency allows us to find how long in time each period is by diving time by freqency
    Tosc = 1 second / Frequency
    
    Setting a higher frequency value will use more processing power, but more periods. The default
    frequency is 60 Hertz
    param[in] frequency Frequency in Hertz
  extern void bcm2835_software_pwm_set_frequency(uint32_t frequency);

Create Channel

    Creates a channel that can be assigned a range, data, and pins to output to
      Each channel will start a new thread once \sa bcm2835_software_pwm_start_all_channels is called
      That channel will manage the active on and active off phase of the electric pulses for every pin
      that has been assigned to the channel using \sa bcm2835_software_pwm_assign_pin_to_channel
      param[in] frequency Frequency in Hertz
    extern void bcm2835_software_pwm_create_channel(uint8_t channel);

Set Range

  Sets the maximum range of the Software PWM output
    The data value can vary between 0 and this range to control PWM output
    param[in] channel An arbitrary PWM channel created earlier by \sa bcm2835_software_pwm_create_channel
    param[in] range The maximum value permitted for DATA.
  extern void bcm2835_software_pwm_set_range(uint8_t channel, uint32_t range);

Set Data

  Sets the Software PWM pulse ratio to emit to DATA/RANGE, where RANGE is set by
    \sa bcm2835_software_pwm_set_range().
    param[in] channel An arbitrary PWM channel created earlier by \sa bcm2835_software_pwm_create_channel
    param[in] data Controls the PWM output ratio as a fraction of the range. 
    Can vary from 0 to RANGE.
  extern void bcm2835_software_pwm_set_data(uint8_t channel, uint32_t data);

Assign Pin to Channel

  Adds a RPiGPIOPin pin to the pins the input parameter channel outputs to
    param[in] channel An arbitrary PWM channel created earlier by \sa bcm2835_software_pwm_create_channel
    param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
  extern void bcm2835_software_pwm_assign_pin_to_channel(uint8_t channel, RPiGPIOPin pin);

Start All Channels

  Creates new threads using pthread_create for each of the channels created using
    \sa bcm2835_software_pwm_start_all_channels
    Note that this action must be called after all of your desired channels are created
  extern void bcm2835_software_pwm_start_all_channels();

Close

  Closes the software pwm library, stopping all threads and deallocating any allocated memory
    Note that this should be called before any final \sa bcm2835_gpio_write writes so no conflicts in 
    state from multi-threading occur
  extern void bcm2835_software_pwm_close();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.