Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.6.1] - 2025-05-08
- fix #34, Sync PCA9634 / 32
- rename setLedDriverMode() => setLedDriverModeAll()
- add **writeAll(arr)**
- add **allOff()**
- remove old defines, all are now PCA963X_xxxx
- update readme.md
- update examples
- minor edits

## [0.6.0] - 2024-01-18
- fix #32, setLedDriverMode(uint8_t mode)
- minor edits (examples)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2016-2024 Rob Tillaart
Copyright (c) 2016-2025 Rob Tillaart

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
128 changes: 78 additions & 50 deletions PCA9635.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// FILE: PCA9635.cpp
// AUTHOR: Rob Tillaart
// DATE: 23-apr-2016
// VERSION: 0.6.0
// VERSION: 0.6.1
// PURPOSE: Arduino library for PCA9635 I2C LED driver, 16 channel PWM, 8 bit
// URL: https://github.com/RobTillaart/PCA9635

Expand Down Expand Up @@ -75,6 +75,33 @@ uint8_t PCA9635::channelCount()
//
// LED DRIVER MODE
//
uint8_t PCA9635::setLedDriverModeAll(uint8_t mode)
{
if (mode > 3) return PCA963X_ERR_MODE;
uint8_t mask = 0b00000000;
switch(mode)
{
case PCA963X_LEDGRPPWM:
mask = 0b11111111;
break;
case PCA963X_LEDPWM:
mask = 0b10101010;
break;
case PCA963X_LEDON:
mask = 0b01010101;
break;
default:
mask = 0b00000000;
break;
}
for (int reg = 0; reg < 4; reg++)
{
writeLedOut(reg, mask);
}
return PCA963X_OK;
}


uint8_t PCA9635::setLedDriverMode(uint8_t channel, uint8_t mode)
{
if (channel >= _channelCount)
Expand All @@ -93,8 +120,8 @@ uint8_t PCA9635::setLedDriverMode(uint8_t channel, uint8_t mode)
uint8_t shift = (channel & 0x03) * 2; // 0,2,4,6 places
uint8_t setmask = mode << shift;
uint8_t clrmask = ~(0x03 << shift);
uint8_t value = (readReg(reg) & clrmask) | setmask;
writeReg(reg, value);
uint8_t value = (readRegister(reg) & clrmask) | setmask;
writeRegister(reg, value);
_error = PCA963X_OK;
return _error;
}
Expand All @@ -111,7 +138,7 @@ uint8_t PCA9635::getLedDriverMode(uint8_t channel)

uint8_t reg = PCA963X_LEDOUT_BASE + (channel >> 2);
uint8_t shift = (channel & 0x03) * 2; // 0, 2, 4, 6 places
uint8_t value = (readReg(reg) >> shift ) & 0x03;
uint8_t value = (readRegister(reg) >> shift ) & 0x03;
_error = PCA963X_OK;
return value;
}
Expand All @@ -125,7 +152,7 @@ uint8_t PCA9635::writeMode(uint8_t reg, uint8_t value)
{
if ((reg == PCA963X_MODE1) || (reg == PCA963X_MODE2))
{
writeReg(reg, value);
writeRegister(reg, value);
return PCA963X_OK;
}
_error = PCA963X_ERR_REG;
Expand All @@ -139,7 +166,7 @@ uint8_t PCA9635::readMode(uint8_t reg)
if ((reg == PCA963X_MODE1) || (reg == PCA963X_MODE2))
{
_error = PCA963X_OK;
uint8_t value = readReg(reg);
uint8_t value = readRegister(reg);
return value;
}
_error = PCA963X_ERR_REG;
Expand All @@ -149,53 +176,55 @@ uint8_t PCA9635::readMode(uint8_t reg)

uint8_t PCA9635::setMode1(uint8_t value)
{
return writeMode(PCA963X_MODE1, value);
writeRegister(PCA963X_MODE1, value);
return PCA963X_OK;
}


uint8_t PCA9635::setMode2(uint8_t value)
{
return writeMode(PCA963X_MODE2, value);
writeRegister(PCA963X_MODE2, value);
return PCA963X_OK;
}


uint8_t PCA9635::getMode1()
{
return readMode(PCA963X_MODE1);
return readRegister(PCA963X_MODE1);
}


uint8_t PCA9635::getMode2()
{
return readMode(PCA963X_MODE2);
return readRegister(PCA963X_MODE2);
}


/////////////////////////////////////////////////////
//
// GROUP PWM
// GROUP REGISTERS
//
void PCA9635::setGroupPWM(uint8_t value)
uint8_t PCA9635::setGroupPWM(uint8_t value)
{
writeReg(PCA963X_GRPPWM, value);
return writeRegister(PCA963X_GRPPWM, value);
}


uint8_t PCA9635::getGroupPWM()
{
return readReg(PCA963X_GRPPWM);
return readRegister(PCA963X_GRPPWM);
}


void PCA9635::setGroupFREQ(uint8_t value)
uint8_t PCA9635::setGroupFREQ(uint8_t value)
{
writeReg(PCA963X_GRPFREQ, value);
return writeRegister(PCA963X_GRPFREQ, value);
}


uint8_t PCA9635::getGroupFREQ()
{
return readReg(PCA963X_GRPFREQ);
return readRegister(PCA963X_GRPFREQ);
}


Expand Down Expand Up @@ -246,6 +275,19 @@ uint8_t PCA9635::writeN(uint8_t channel, uint8_t* arr, uint8_t count)
}


uint8_t PCA9635::writeAll(uint8_t * arr)
{
return writeN(0, arr, 16);
}


uint8_t PCA9635::allOff()
{
uint8_t arr[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
return writeN(0, arr, 16);
}


uint8_t PCA9635::writeN_noStop(uint8_t channel, uint8_t* arr, uint8_t count)
{
if (channel + count > _channelCount)
Expand Down Expand Up @@ -291,7 +333,7 @@ int PCA9635::lastError()

/////////////////////////////////////////////////////
//
// SUB CALL - ALL CALL
// SUB CALL
//
bool PCA9635::enableSubCall(uint8_t nr)
{
Expand Down Expand Up @@ -346,7 +388,7 @@ bool PCA9635::setSubCallAddress(uint8_t nr, uint8_t address)
// _error = ?? TODO
return false;
}
writeReg(PCA963X_SUBADR(nr), address);
writeRegister(PCA963X_SUBADR(nr), address);
return true;
}

Expand All @@ -358,11 +400,15 @@ uint8_t PCA9635::getSubCallAddress(uint8_t nr)
// _error = ?? TODO
return 0;
}
uint8_t address = readReg(PCA963X_SUBADR(nr));
uint8_t address = readRegister(PCA963X_SUBADR(nr));
return address;
}


/////////////////////////////////////////////////////
//
// ALL CALL
//
bool PCA9635::enableAllCall()
{
uint8_t prev = getMode1();
Expand Down Expand Up @@ -394,20 +440,20 @@ bool PCA9635::disableAllCall()
bool PCA9635::isEnabledAllCall()
{
uint8_t mask = getMode1();
return mask & PCA963X_MODE1_ALLCALL;
return (mask & PCA963X_MODE1_ALLCALL) > 0;
}


bool PCA9635::setAllCallAddress(uint8_t address)
{
writeReg(PCA963X_ALLCALLADR, address);
writeRegister(PCA963X_ALLCALLADR, address);
return true;
}


uint8_t PCA9635::getAllCallAddress()
{
uint8_t address = readReg(PCA963X_ALLCALLADR);
uint8_t address = readRegister(PCA963X_ALLCALLADR);
return address;
}

Expand Down Expand Up @@ -485,51 +531,33 @@ int PCA9635::I2C_SoftwareReset(uint8_t method)
uint8_t PCA9635::writeLedOut(uint8_t reg, uint8_t mask)
{
if (reg > 3) return PCA963X_ERROR;
writeReg(PCA963X_LEDOUT_BASE + reg, mask);
writeRegister(PCA963X_LEDOUT_BASE + reg, mask);
return PCA963X_OK;
}


uint8_t PCA9635::readLedOut(uint8_t reg)
{
if (reg > 3) return 0x00;
return readReg(PCA963X_LEDOUT_BASE + reg);
return readRegister(PCA963X_LEDOUT_BASE + reg);
}


// TODO move to right section after testing.
/////////////////////////////////////////////////////
//
// OBSOLETE
//
uint8_t PCA9635::setLedDriverMode(uint8_t mode)
{
if (mode > 3) return PCA963X_ERR_MODE;
uint8_t mask = 0b00000000;
switch(mode)
{
case PCA963X_LEDGRPPWM:
mask = 0b11111111;
break;
case PCA963X_LEDPWM:
mask = 0b10101010;
break;
case PCA963X_LEDON:
mask = 0b01010101;
break;
default:
mask = 0b00000000;
break;
}
for (int reg = 0; reg < 4; reg++)
{
writeLedOut(reg, mask);
}
return PCA963X_OK;
return setLedDriverModeAll(mode);
}


/////////////////////////////////////////////////////
//
// PRIVATE
//
uint8_t PCA9635::writeReg(uint8_t reg, uint8_t value)
uint8_t PCA9635::writeRegister(uint8_t reg, uint8_t value)
{
_wire->beginTransmission(_address);
_wire->write(reg);
Expand All @@ -542,7 +570,7 @@ uint8_t PCA9635::writeReg(uint8_t reg, uint8_t value)
}


uint8_t PCA9635::readReg(uint8_t reg)
uint8_t PCA9635::readRegister(uint8_t reg)
{
_wire->beginTransmission(_address);
_wire->write(reg);
Expand Down
Loading