## PWM Expansion Python Module

The Onion PWM Expansion Python module, pwmExp is based on the C PWM Expansion Library. Using this module, you will be able to control the PWM Expansion from within your Python program.

### Programming Flow

After each power-cycle, the chip that controls the PWM Expansion must be programmed with an initialization sequence to enable the on-board oscillator so that PWM signals can be generated.

After the initialization, the other functions can be used to generate PWM signals on specific channels or to change the PWM signal frequency.

Additionally, it is possible to disable to the oscillator, disabling the generation of all PWM signals at once. Before generating new PWM signals, the initialization sequence must be run again.

### PWM Signal Refresher

Pulse Width Modulated signals can be described with duty cycle percentages and frequencies/periods:

The duty cycle indicates what percentage of time a signal is on or high voltage.

The frequency determines the overall period of the pulse.

For a more detailed explanation, see the guide on using the Servo Expansion.

#### Channels on the Expansion

The PWM Expansion has 16 channels that can generate distinct PWM signals. Note that they will all be running on the same frequency.

### The Python Module

The pwmExp Python module in the OmegaExpansion package provides a wrapper around the C library functions. The functions are largely the same as their C counterparts, including the arguments and return values. Any differences from the C library will be explicitly mentioned below.

#### Source Code

The source code can be found in the Onion i2c-exp-driver GitHub Repo.

#### Installing the Module

To install the Python module, run the following commands:

opkg update
opkg install python-light pyPwmExp

This will install the module to /usr/lib/python2.7/OmegaExpansion/

This only needs to be done once.

To add the Onion PWM Expansion Module to your Python program, include the following in your code:

from OmegaExpansion import pwmExp

#### Example Code

Example code that uses the pwmExp module can be found here, in the i2c-exp-driver Onion GitHub Repo.

#### Return Values

All functions follow the same pattern with return values:

If the function operation is successful, the return value will be 0.

If the function operation is not successful, the function will return 1.

### Functions

Function Prototype
Initialization Function driverInit()
Check for Initialization checkInit()
Generate a PWM Signal setupDriver(channel, duty, delay)
Set PWM Signal Frequency setFrequency(frequency)
Disabling the Oscillator disableChip()

### Initialization Function - driverInit()

This function programs the initialization sequence on the Servo Expansion, after this step is completed, the functions to generate PWM signals or change the signal frequency can be used with success:

pwmExp.driverInit()

#### Examples

Initialize the PWM Expansion:

status  = pwmExp.driverInit();

### Check for Initialization - checkInit()

This function performs several reads to determine if the Servo Expansion has been initialized and the oscillator is running:

pwmExp.checkInit()

The return value of the function indicates the Initialization Status:

Return Value Initialization Status
0 Not Initialized
1 Initialized

#### Example

Check if the PWM Expansion is initialized:

bInit   = pwmExp.checkInit()

if (bInit == 0):
print 'The Servo Expansion needs to be initialized\n'
else:
print 'The Servo Expansion is up and running!'
}

### Generate a PWM Signal - setupDriver()

This function is used to generate a PWM singal on a specified channel:

pwmExp.setupDriver(channel, duty, delay)

#### Arguments

The channel argument determines on which channel to generate the PWM signal. * 0 to 15 will select a specific channel * -1 will generate the same signal on all channels

The duty argument specifies duty cycle percentage for the PWM signal. Accepted values are 0 to 100. Decimal values are allowed.

The delay argument specifies the percentage delay before the PWM signal goes high. Accepted values are 0 to 100 with decimal values being allowed. In normal use with servos this should be set to 0.

#### Example

Set channel 7 to 6.55% duty cycle:

status = pwmExp.setupDriver(7, 6.55, 0)

Set channel 14 to always on:

status = pwmExp.setupDriver(14, 100, 0)

Set all channels to 66.66% duty with a 9% delay:

status = pwmExp.setupDriver(-1, 66.66, 9)

### Set PWM Signal Frequency - setFrequency()

The oscillator can be reprogrammed to generate a variety of different frequencies:

pwmExp.setFrequency(frequency)

This will change the frequency of the PWM signals generated on all of the channels. The oscillator can generate frequencies between 24 Hz and 1526 Hz, the default value is 50 Hz.

#### Arguments

The freq argument is a floating point number that specifies the frequency. The function will accept any input but the programmed frequency will be clamped between 24 Hz and 1526 Hz.

#### Example

Change the frequency to 60 Hz:

status = pwmExp.setFrequency(60)

Change the frequency to 92.23 Hz:

status = pwmExp.setFrequency(92.23)

### Disabling the Oscillator - disableChip()

The oscillator can also be disabled, automatically stopping all PWM signal generation:

pwmExp.disableChip()

This might be useful for disabling PWM signal-driven devices while not powering off the Omega. The initialization function will have to be run before new PWM signals can be generated.

#### Example

Disable the oscillator:

status  = pwmExp.disableChip()