# pca9685

Library for PCA9685 16 channel 12-bit PWM Controller

Author | Rob Jansen, Copyright © 2022..2022, all rights reserved.
Adapted-by |
Compiler | 2.5r6

Description

    Library for controlling the PCA9685 16 channel 12-bit PWM Controller.
                 The chip uses an IIC interface. In order to support multiple devices
                 connected to the same IIC bus, the IIC address is selectable.

Sources

    NXP Product data sheet, Rev. 4 — 16 April 2015

Notes

    This library supports the control of the PCA9685 via IIC.
           The default is hardware IIC control but this can be overruled using
           software IIC control by defining the following constant:
           -) const PCA9685_SOFTWARE_IIC = TRUE

Dependencies

No dependency found

## Summary

### Global variables/contants

- `const byte _PCA9685_MODE1_SUBADR3 = 0x02`
- `const byte _PCA9685_MODE1_ALLCALL = 0x01`
- `const byte _PCA9685_LED0_REG = 0x06`
- `var word _pca9685_pwm_frequency = PCA9685_PWM_DEFAULT_FREQUENCY`
- `const byte PCA9685_MIN_CHANNEL = 0`
- `const byte PCA9685_ALL_CHANNEL = PCA9685_NR_OF_CHANNELS`
- `const byte _PCA9685_MODE1_SLEEP = 0x10`
- `const byte _PCA9685_MODE1_REG = 0x00`
- `const byte _PCA9685_MODE2_INVRT = 0x10`
- `const byte _PCA9685_SUBADR2_REG = 0x03`
- `const word PCA9685_PWM_MAX_FREQUENCY = 1525`
- `const word PCA9685_PWM_MIN_TIME = 0`
- `const byte _PCA9685_SW_RESET = 0x06`
- `const byte _PCA9685_MODE1_AUTOINC = 0x20`
- `const byte _PCA9685_MODE2_OUTDRV_TPOLE = 0x04`
- `const byte _PCA9685_ALLLED_REG = 0xFA`
- `const byte _PCA9685_MODE2_OUTNE_HIGH = 0x01`
- `const byte PCA9685_NR_OF_CHANNELS = 16`
- `const dword _PCA9685_OSC_INTERNAL_FREQUENCY = 25_000_000`
- `const word PCA9685_PWM_MIN_FREQUENCY = 24`
- `const byte _PCA9685_MODE1_SUBADR2 = 0x04`
- `var dword _pca9685_oscillator_frequency = _PCA9685_OSC_INTERNAL_FREQUENCY`
- `const word PCA9685_PWM_DEFAULT_FREQUENCY = 200`
- `const byte _PCA9685_SUBADR3_REG = 0x04`
- `const byte _PCA9685_MODE1_SUBADR1 = 0x08`
- `var byte _pca9685_iic_address = PCA9685_IIC_ADDRESS`
- `const byte _PCA9685_MODE1_EXTCLK = 0x40`
- `const dword _PCA9685_OSC_MAX_FREQUENCY = 50_000_000`
- `const byte _PCA9685_PRESCALE_REG = 0xFE`
- `const byte _PCA9685_MODE2_OCH_ONACK = 0x08`
- `const byte _PCA9685_MODE1_RESTART = 0x80`
- `const word PCA9685_PWM_FULL_TIME = 0x1000`
- `const byte PCA9685_MAX_CHANNEL = PCA9685_NR_OF_CHANNELS - 1`
- `const word PCA9685_PWM_MAX_TIME = 4095`
- `const byte _PCA9685_ALLCALL_REG = 0x05`
- `const byte _PCA9685_SUBADR1_REG = 0x02`
- `const byte _PCA9685_MODE2_OUTNE_HIGHZ = 0x02`
- `const byte _PCA9685_MODE2_REG = 0x01`

### Procedures

- `pca9685_enable_sub_address_3()`
- `pca9685_enable_sub_address_2()`
- `pca9685_set_sub_address_1(byte in iic_address)`
- `pca9685_set_channel_off(byte in channel)`
- `pca9685_sleep()`
- `pca9685_set_sub_address_3(byte in iic_address)`
- `pca9685_set_output_inverted()`
- `pca9685_select_external_oscillator(dword in frequency)`
- `pca9685_set_all_call_address(byte in iic_address)`
- `pca9685_set_output_disable_high_impedance()`
- `pca9685_set_output_change_on_stop()`
- `pca9685_disable_sub_address_2()`
- `pca9685_set_output_change_on_ack()`
- `pca9685_set_channel_pwm_percent(byte in channel, byte in percent)`
- `pca9685_disable_sub_address_3()`
- `pca9685_set_output_open_drain()`
- `pca9685_set_output_not_inverted()`
- `pca9685_restart()`
- `pca9685_set_output_disable_high()`
- `pca9685_set_sub_address_2(byte in iic_address)`
- `pca9685_set_output_disable_low()`
- `pca9685_disable_all_call_address()`
- `pca9685_set_iic_address(byte in iic_address)`
- `pca9685_set_pwm_frequency(word in frequency)`
- `pca9685_enable_sub_address_1()`
- `pca9685_set_channel_on(byte in channel)`
- `pca9685_enable_all_call_address()`
- `pca9685_init()`
- `pca9685_reset()`
- `pca9685_set_output_totempole()`
- `pca9685_disable_sub_address_1()`

Private

- `_pca9685_write_register(byte in register, byte in data)`

### Functions

- `pca9685_get_sub_address_1() return byte`
- `pca9685_get_sub_address_2() return byte`
- `pca9685_get_pwm_frequency() return word`
- `pca9685_get_iic_address() return byte`
- `pca9685_get_all_call_address() return byte`
- `pca9685_get_oscillator_frequency() return dword`
- `pca9685_get_sub_address_3() return byte`

Private

- `_pca9685_read_register(byte in register) return byte`
- `_calculate_channel_register(byte in channel) return byte`

## API details

### Global variables/contants

- `const byte _PCA9685_MODE1_SUBADR3 = 0x02`

  No documentation found

- `const byte _PCA9685_MODE1_ALLCALL = 0x01`

  No documentation found

- `const byte _PCA9685_LED0_REG = 0x06`

  No documentation found

- `var word _pca9685_pwm_frequency = PCA9685_PWM_DEFAULT_FREQUENCY`

      Selected default PWM frequency.

- `const byte PCA9685_MIN_CHANNEL = 0`

  No documentation found

- `const byte PCA9685_ALL_CHANNEL = PCA9685_NR_OF_CHANNELS`

      Use a special value to write all channel values at once.

- `const byte _PCA9685_MODE1_SLEEP = 0x10`

  No documentation found

- `const byte _PCA9685_MODE1_REG = 0x00`

      Register addresses from data sheet.

- `const byte _PCA9685_MODE2_INVRT = 0x10`

  No documentation found

- `const byte _PCA9685_SUBADR2_REG = 0x03`

  No documentation found

- `const word PCA9685_PWM_MAX_FREQUENCY = 1525`

  No documentation found

- `const word PCA9685_PWM_MIN_TIME = 0`

      Min and max values of the PWM time. These are starting positions at which
      an output can be turned on and turned off.

- `const byte _PCA9685_SW_RESET = 0x06`

      Command sent to address 0x00 to reset all devices on the IIC bus.

- `const byte _PCA9685_MODE1_AUTOINC = 0x20`

  No documentation found

- `const byte _PCA9685_MODE2_OUTDRV_TPOLE = 0x04`

      Mode2 register values.

- `const byte _PCA9685_ALLLED_REG = 0xFA`

  No documentation found

- `const byte _PCA9685_MODE2_OUTNE_HIGH = 0x01`

  No documentation found

- `const byte PCA9685_NR_OF_CHANNELS = 16`

      Channel definitions.

- `const dword _PCA9685_OSC_INTERNAL_FREQUENCY = 25_000_000`

      Default internal oscillator frequency.

- `const word PCA9685_PWM_MIN_FREQUENCY = 24`

      PWM frequencies in Hz based on using a 25 MHz clock as is generated by the
      internal oscillator. When using an external clock with a different frequency
      these values have to be recalculated accordingly.

- `const byte _PCA9685_MODE1_SUBADR2 = 0x04`

  No documentation found

- `var dword _pca9685_oscillator_frequency = _PCA9685_OSC_INTERNAL_FREQUENCY`

      Private variables. Preset some at the start of the program as in pca9685_reset().
      Selected default oscillator frequency.

- `const word PCA9685_PWM_DEFAULT_FREQUENCY = 200`

      Value after power up or reset.

- `const byte _PCA9685_SUBADR3_REG = 0x04`

  No documentation found

- `const byte _PCA9685_MODE1_SUBADR1 = 0x08`

  No documentation found

- `var byte _pca9685_iic_address = PCA9685_IIC_ADDRESS`

      Selected IIC address.

- `const byte _PCA9685_MODE1_EXTCLK = 0x40`

  No documentation found

- `const dword _PCA9685_OSC_MAX_FREQUENCY = 50_000_000`

      Maximun external oscillator frequency when using an external clock.

- `const byte _PCA9685_PRESCALE_REG = 0xFE`

  No documentation found

- `const byte _PCA9685_MODE2_OCH_ONACK = 0x08`

  No documentation found

- `const byte _PCA9685_MODE1_RESTART = 0x80`

      Mode1 register values.

- `const word PCA9685_PWM_FULL_TIME = 0x1000`

      Special value for PWM full on or full off. Full is bit 12 on (4096 decimal).

- `const byte PCA9685_MAX_CHANNEL = PCA9685_NR_OF_CHANNELS - 1`

  No documentation found

- `const word PCA9685_PWM_MAX_TIME = 4095`

  No documentation found

- `const byte _PCA9685_ALLCALL_REG = 0x05`

  No documentation found

- `const byte _PCA9685_SUBADR1_REG = 0x02`

  No documentation found

- `const byte _PCA9685_MODE2_OUTNE_HIGHZ = 0x02`

  No documentation found

- `const byte _PCA9685_MODE2_REG = 0x01`

  No documentation found

### Procedures

- `pca9685_enable_sub_address_3()`

      Enable IIC sub address 3.

- `pca9685_enable_sub_address_2()`

      Enable IIC sub address 2.

- `pca9685_set_sub_address_1(byte in iic_address)`

      Set IIC sub address 1. Default value is 0xE2.

- `pca9685_set_channel_off(byte in channel)`

      Set the given channel output to OFF. The given channel must be in range
      PCA9685_MIN_CHANNEL to PCA9685_MAX_CHANNEL. If the given channel equals
      PCA9685_ALL_CHANNEL then all channels are set to OFF.

- `pca9685_sleep()`

      Put the PCA9685 to sleep. This will activate the low power mode. Make sure
      to call pca9685_restart() to restore operation.

- `pca9685_set_sub_address_3(byte in iic_address)`

      Set IIC sub address 3. Default value is 0xE8.

- `pca9685_set_output_inverted()`

      Set the output to inverted mode (output must be enabled, that is OE=LOW).

- `pca9685_select_external_oscillator(dword in frequency)`

      Select the external oscillator with the given oscillator frequency. The
      freqency is given in Hz and must be <= 50 MHz. Switching back to the internal
      oscillator can only be achieved by a power cycle or a software reset.

- `pca9685_set_all_call_address(byte in iic_address)`

      Set the IIC all call address.

- `pca9685_set_output_disable_high_impedance()`

      Set the disabled output (output must be disabled, that is OE=HIGH) to high
      impedance.

- `pca9685_set_output_change_on_stop()`

      Set the PWM output to change on stop.

- `pca9685_disable_sub_address_2()`

      Disable IIC sub address 2.

- `pca9685_set_output_change_on_ack()`

      Set the PWM output to change on acknowledge.

- `pca9685_set_channel_pwm_percent(byte in channel, byte in percent)`

      Set the channel PWM duty cycle in % of the on time where 0% is off and 100%
      is on. The given channel must be in range PCA9685_MIN_CHANNEL to
      PCA9685_MAX_CHANNEL. If the given channel equals PCA9685_ALL_CHANNEL then
      all channels will be set with the given percentage.

- `pca9685_disable_sub_address_3()`

      Disable IIC sub address 3.

- `pca9685_set_output_open_drain()`

      Set the output to open drain (output must be enabled, that is OE=LOW)

- `pca9685_set_output_not_inverted()`

      Set the output to not inverted mode (output must be enabled, that is OE=LOW).

- `pca9685_restart()`

      Restart the PCA9685 as to wakeup from sleep (must be sleeping to wakeup).

- `pca9685_set_output_disable_high()`

      Set the disabled output (output must be disabled, that is OE=1=HIGH) to high.
      Note the output is only high if the output was set to totem pole otherwise
      the output will be high-impedance.

- `pca9685_set_sub_address_2(byte in iic_address)`

      Set IIC sub address 2. Default value is 0xE4.

- `pca9685_set_output_disable_low()`

      Set the disabled output (output must be disabled, that is OE=HIGH) to Low.

- `pca9685_disable_all_call_address()`

      Disable the IIC all call address.

- `pca9685_set_iic_address(byte in iic_address)`

      Set the IIC address of the device to communicate with. Once set, all
      IIC communication is done to the device with this IIC address.
      Only needed when commmunicating needs to be done with multiple devices.

- `pca9685_set_pwm_frequency(word in frequency)`

      Set the PWM frequency. The frequency is given in Hz and must be
      >= PCA9685_PWM_MIN_FREQUENCY and <= PCA9685_PWM_MAX_FREQUENCY when using
      an oscillator frequency of 25 MHz (default internal oscillator frequency).

- `pca9685_enable_sub_address_1()`

      Enable IIC sub address 1.

- `pca9685_set_channel_on(byte in channel)`

      Set the given channel output to ON. The given channel must be in range
      PCA9685_MIN_CHANNEL to PCA9685_MAX_CHANNEL. If the given channel equals
      PCA9685_ALL_CHANNEL then all channels are set to ON.

- `pca9685_enable_all_call_address()`

      Enable the IIC all call address.

- `pca9685_init()`

      Intialize the PCA9685 by initializing the IIC interface and restart the
      device.
      Note: When using a second PCA9685 device you need to set the IIC address
      of that device first and call this init procedure again.

- `pca9685_reset()`

      Reset all PCA9685 devices connected to the IIC bus bringing them back to the
      default settings. Make sure to call pca9685_init() to restore operation.

- `pca9685_set_output_totempole()`

      Set the output to totem pole (output must be enabled, that is OE=LOW)

- `pca9685_disable_sub_address_1()`

      Disable IIC sub address 1.

Private

- `_pca9685_write_register(byte in register, byte in data)`

      Write the given data to the given register of the PCA9685.

### Functions

- `pca9685_get_sub_address_1() return byte`

      Get IIC sub address 1.

- `pca9685_get_sub_address_2() return byte`

      Get IIC sub address 2.

- `pca9685_get_pwm_frequency() return word`

      Get the currently set PWM frequency in Hz.

- `pca9685_get_iic_address() return byte`

      Get the currently set IIC address of the device we are communicating with.

- `pca9685_get_all_call_address() return byte`

      Get the currently set IIC all call address.

- `pca9685_get_oscillator_frequency() return dword`

      Get the currently set oscillator frequency.

- `pca9685_get_sub_address_3() return byte`

      Get IIC sub address 3.

Private

- `_pca9685_read_register(byte in register) return byte`

      Read a byte from the given register of the PCA9685 and return it.

- `_calculate_channel_register(byte in channel) return byte`

      Calculate the output channel register based on the given channel and return it.

## Related samples

Here are the list of samples which use this library:

16f1825 | 16f1825_pca9685_led.jal
16f1825 | 16f1825_pca9685_servo.jal
16f1825 | 16f1825_pca9685_servo_led.jal