Skip to content

Commit

Permalink
add output enable functions (#19)
Browse files Browse the repository at this point in the history
- add OutputEnable control functions.
- add example **PCA9685_OE_control.ino**
- update unit test.
- **configure()** now returns error state
- add I2C_SoftwareReset()
- moved code from .h to .cpp
- update readme.md
- update GitHub actions
- update license 2023
- minor edits
  • Loading branch information
RobTillaart authored Mar 14, 2023
1 parent 7275a7f commit 8398c23
Show file tree
Hide file tree
Showing 9 changed files with 340 additions and 65 deletions.
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.4.2] - 2023-03-14
- add OutputEnable control functions.
- add example **PCA9685_OE_control.ino**
- update unit test.
- **configure()** now returns error state
- add I2C_SoftwareReset()
- moved code from .h to .cpp
- update readme.md
- update GitHub actions
- update license 2023
- minor edits


## [0.4.1] - 2022-11-19
- add RP2040 in build-CI
- add changelog.md


## [0.4.0] - 2022-06-09
- breaking changes (sync with pca9634)
- rename reset() to configure()
Expand Down
125 changes: 113 additions & 12 deletions PCA9685.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// FILE: PCA9685.cpp
// AUTHOR: Rob Tillaart
// DATE: 24-apr-2016
// VERSION: 0.4.1
// PURPOSE: Arduino library for I2C PCA9685 16 channel PWM
// VERSION: 0.4.2
// PURPOSE: Arduino library for I2C PCA9685 16 channel PWM
// URL: https://github.com/RobTillaart/PCA9685_RT


Expand All @@ -16,10 +16,11 @@
//
PCA9685::PCA9685(const uint8_t deviceAddress, TwoWire *wire)
{
_address = deviceAddress;
_wire = wire;
_channelCount = 16;
_error = PCA9685_OK;
_address = deviceAddress;
_wire = wire;
_channelCount = 16;
_error = PCA9685_OK;
_OutputEnablePin = 255;
}


Expand Down Expand Up @@ -49,6 +50,21 @@ bool PCA9685::begin(uint8_t mode1_mask, uint8_t mode2_mask)
}


uint8_t PCA9685::configure(uint8_t mode1_mask, uint8_t mode2_mask)
{
_error = PCA9685_OK;

uint8_t r1 = setMode1(mode1_mask);
uint8_t r2 = setMode2(mode2_mask);

if ((r1 != PCA9685_OK) || (r2 != PCA9685_OK))
{
return PCA9685_ERROR;
}
return _error;
}


bool PCA9685::isConnected()
{
_wire->beginTransmission(_address);
Expand All @@ -57,12 +73,9 @@ bool PCA9685::isConnected()
}


void PCA9685::configure(uint8_t mode1_mask, uint8_t mode2_mask)
uint8_t PCA9685::channelCount()
{
_error = PCA9685_OK;

setMode1(mode1_mask);
setMode2(mode2_mask);
return _channelCount;
}


Expand Down Expand Up @@ -91,6 +104,30 @@ uint8_t PCA9685::readMode(uint8_t reg)
}


uint8_t PCA9685::setMode1(uint8_t value)
{
return writeMode(PCA9685_MODE1, value);
}


uint8_t PCA9685::setMode2(uint8_t value)
{
return writeMode(PCA9685_MODE2, value);
}


uint8_t PCA9685::getMode1()
{
return readMode(PCA9685_MODE1);
}


uint8_t PCA9685::getMode2()
{
return readMode(PCA9685_MODE2);
}


// write value to single PWM channel
void PCA9685::setPWM(uint8_t channel, uint16_t onTime, uint16_t offTime)
{
Expand Down Expand Up @@ -173,7 +210,7 @@ int PCA9685::getFrequency(bool cache)
}


// datasheet P.18 - fig. 9:
// datasheet P.18 - fig. 9:
// Note: bit[11-0] ON should NOT equal timer OFF in ON mode
// in OFF mode it doesn't matter.
void PCA9685::digitalWrite(uint8_t channel, uint8_t mode)
Expand Down Expand Up @@ -304,6 +341,70 @@ uint8_t PCA9685::getAllCallAddress()
}


/////////////////////////////////////////////////////
//
// OE - Output Enable control
//
// active LOW see datasheet
//
bool PCA9685::setOutputEnablePin(uint8_t pin)
{
_OutputEnablePin = pin;
if (_OutputEnablePin != 255)
{
pinMode(_OutputEnablePin, OUTPUT);
digitalWrite(_OutputEnablePin, HIGH);
return true;
}
// must it be set to HIGH now?
return false;
}


bool PCA9685::setOutputEnable(bool on)
{
if (_OutputEnablePin != 255)
{
digitalWrite(_OutputEnablePin, on ? LOW : HIGH);
return true;
}
return false;
}


uint8_t PCA9685::getOutputEnable()
{
if (_OutputEnablePin != 255)
{
return digitalRead(_OutputEnablePin);
}
return HIGH;
}


//////////////////////////////////////////////////////
//
// EXPERIMENTAL
//
int PCA9685::I2C_SoftwareReset(uint8_t method)
{
// only support 0 and 1
if (method > 1) return -999;
if (method == 1)
{
// from https://github.com/RobTillaart/PCA9634/issues/10#issuecomment-1206326417
const uint8_t SW_RESET = 0x03;
_wire->beginTransmission(SW_RESET);
_wire->write(0xA5);
_wire->write(0x5A);
return _wire->endTransmission(true);
}

// default - based upon NXP specification - UM10204.pdf - page 16
_wire->beginTransmission(0x00);
_wire->write(0x06);
return _wire->endTransmission(true);
}


//////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit 8398c23

Please sign in to comment.