A PWM (Pulse-Width Modulator) is a component used for controlling power to inertial electrical devices. It generates a periodic waveform with positive width which can be controlled and thus, the waveform’s average value modified.

The average value of voltage fed to the load is controlled by turning the switch between the supply and the load on and off at a fast pace. The longer the switch is on compared to the off, the higher the power supplied to the load will be.

The ConnectCore 8M Mini has several PWM (Pulse Width Modulation) interfaces to manage devices such as servos and voltage regulators. In the ConnectCore 8M Mini Hardware Reference Manual you can find information about the available PWM channels.

Digi adds to Android an API to manage these PWM channels. You can configure the PWM duty cycle, the frequency, and the polarity among other things. In the Digi APIx javadoc you can find a complete list of the available methods in this API.

Unless noted, all PWM API methods require the com.digi.android.permission.PWM permission.

If your application does not have the com.digi.android.permission.PWM permission it will not have access to any PWM service feature.

First of all, a new PWMManager object must be instantiated by passing the Android Application Context.

Instantiating the PWMManager
import android.app.Activity;
import android.os.Bundle;

import com.digi.android.pwm.PWMManager;

public class PWMSampleActivity extends Activity {

    PWMManager pwmManager;

    [...]

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Instantiate the PWM manager object.
        pwmManager= new PWMManager(this);

        [...]
    }

    [...]
}

Instantiate a PWM channel

The PWMManager allows you to create a PWM object representing a physical module’s PWM channel. To create a PWM object you will need a PWMChip object and the PWM channel index. If you don’t know how many chips and channels are available in the device you can list them.

Method Description

listPWMChips()

Lists all available PWM chips in the device

PWMChip.listChannels()

Lists all available PWM channels in the PWMChip

createPWM(PWMChip, int)

Creates and returns a PWM object with the given PWMChip and channel index

The createPWM(PWMChip, int) method may fail if the provided chip or channel is not available, throwing a PWMException.

Getting PWM chips and channels
import com.digi.android.pwm.PWM;
import com.digi.android.pwm.PWMChip;
import com.digi.android.pwm.PWMManager;

[...]

PWMManager pwmManager = ...;

// Create a PWM object for each available PWM channel.
List<PWM> pwms = new ArrayList<>();
List<PWMChip> chips = pwmManager.listPWMChips();
for (PWMChip chip : chips) {
    List<Integer> channels = chip.listChannels();
    for (int channel : channels) {
        pwms.add(pwmManager.createPWM(chip, channel));
    }
}

[...]

Manage PWM period/frequency

You can get and set the PWM channel period or frequency using the following methods:

Method Description

getPeriod()

Returns the PWM channel period in nanoseconds

setPeriod(long)

Changes the period of the PWM channel to the given nanoseconds

getFrequency()

Returns the PWM channel frequency in Hz

setFrequency(long)

Changes the PWM channel frequency in Hz

These methods may fail if there is any error while reading or configuring the PWM period/frequency, throwing a PWMException.

Getting and setting the PWM period/frequency
import com.digi.android.pwm.PWM;
import com.digi.android.pwm.PWMChip;
import com.digi.android.pwm.PWMManager;

[...]

PWMManager pwmManager = ...;
PWM pwm = ...;

[...]

System.out.println("PWM chip: " + pwm.getChip());
System.out.println("PWM channel: " + pwm.getChannelIndex());
System.out.println("Period (ns): " + pwm.getPeriod());
System.out.println("Frequency (Hz): " + pwm.getFrequency());

// Set period to 500ms
pwm.setPeriod(500000000);
System.out.println("New period (ns): " + pwm.getPeriod());
// Set frequency to 1000Hz
pwm.setFrequency(1000);
System.out.println("New frequency (Hz): " + pwm.getFrequency());

[...]
Before you configure the period/frequency: * make sure the channel is disabled. * make sure the configured duty cycle is lower than the new period. If you attempt to configure a period lower than the configured duty cycle, or configure the period/frequency while the channel is enabled, the system will throw a PWMException.

Manage PWM duty cycle

You can get and set the PWM channel duty cycle using the following methods:

Method Description

getDutyCycleRaw()

Returns the duty cycle the PWM channel in nanoseconds

setDutyCycleRaw(long)

Changes the duty cycle of the PWM channel to the given nanoseconds

getDutyCyclePercentage()

Returns the duty cycle percentage of the PWM channel (0 to 100%)

setDutyCyclePercentage(int)

Changes the duty cycle percentage of the PWM channel

These methods may fail if there is any error while reading or configuring the PWM duty cycle, throwing a PWMException.

Getting and setting the PWM duty cycle
import com.digi.android.pwm.PWM;
import com.digi.android.pwm.PWMChip;
import com.digi.android.pwm.PWMManager;

[...]

PWMManager pwmManager = ...;
PWM pwm = ...;

[...]

System.out.println("PWM chip: " + pwm.getChip());
System.out.println("PWM channel: " + pwm.getChannelIndex());
System.out.println("Duty cycle (ns): " + pwm.getDutyCycleRaw());
System.out.println("Duty cycle (%): " + pwm.getDutyCyclePercentage());

// Set duty cycle to 50%
pwm.setDutyCyclePercentage(50);
System.out.println("New duty cycle (%): " + pwm.getDutyCyclePercentage());
long period = pwm.getPeriod();
pwm.setDutyCycleRaw(period/2);
System.out.println("New duty cycle (ns): " + pwm.getDutyCycleRaw());

[...]
Before you configure the duty cycle in raw mode, make sure the configured period is greater than the new duty cycle. If you attempt to configure a duty cycle greater than the configured period, the system will throw a PWMException.

Manage PWM polarity

You can get and set the PWM channel polarity using the PWMPolarity enumeration class and the following methods:

Method Description

getPolarity()

Returns the polarity of the PWM channel

setPolarity(PWMPolarity)

Changes the polarity of the PWM channel

These methods may fail if there is any error while reading or configuring the PWM polarity, throwing a PWMException.

Getting and setting the PWM polarity
import com.digi.android.pwm.PWM;
import com.digi.android.pwm.PWMChip;
import com.digi.android.pwm.PWMManager;
import com.digi.android.pwm.PWMPolarity;

[...]

PWMManager pwmManager = ...;
PWM pwm = ...;

[...]

System.out.println("PWM chip: " + pwm.getChip());
System.out.println("PWM channel: " + pwm.getChannelIndex());
System.out.println("Polarity: " + pwm.getPolarity());

// Change polarity.
pwm.setPolarity(PWMPolarity.NORMAL);
System.out.println("New polarity: " + pwm.getPolarity());
pwm.setPolarity(PWMPolarity.INVERSED);
System.out.println("New polarity: " + pwm.getPolarity());

[...]
Before you configure the polarity, make sure the period is greater than zero. If you attempt to configure the polarity when the period is zero, the system will throw a PWMException.

Manage PWM enable status

You can enable or disable the PWM channel using the following methods:

Method Description

isEnabled()

Returns true if the PWM channel is enabled, false otherwise

setEnabled(boolean)

Changes the enable status of the PWM channel

These methods may fail if there is any error while reading or configuring the PWM enable status, throwing a PWMException.

Getting and setting the PWM enable status
import com.digi.android.pwm.PWM;
import com.digi.android.pwm.PWMChip;
import com.digi.android.pwm.PWMManager;

[...]

PWMManager pwmManager = ...;
PWM pwm = ...;

[...]

System.out.println("PWM chip: " + pwm.getChip());
System.out.println("PWM channel: " + pwm.getChannelIndex());
System.out.println("Enabled: " + pwm.isEnabled());

// Change enable status.
pwm.setEnabled(false);
System.out.println("New enable status: " + pwm.isEnabled());
pwm.setEnabled(true);
System.out.println("New enable status: " + pwm.isEnabled());

[...]
Before you enable the channel, make sure the configured period is greater than zero. If you attempt to enable the channel when the period is zero, the system will throw a PWMException.

PWM example

The PWM Sample Application demonstrates the usage of the PWM API. In this example you can list all the available PWM chips and channels and configure the different PWM parameters.

You can import the example using Digi’s Android Studio plugin. For more information, see Import a Digi sample application. To look at the application source code, go to the GitHub repository.