PDA

View Full Version : PCA9685PW Coding



Scampy
- 14th May 2014, 21:12
I'm hoping to use a PCA9685PW (16 channel PWM LED driver chip) to control some aquarium light I've made. Basically I want to use 4 channels of the chip so I can independently turn on and dim 4 sets of LEDS.

I've got a PCA9685PW chip on a breakout board, opened up the datasheet ( http://www.nxp.com/documents/data_sheet/PCA9685.pdf ) and it went completely over my head.. Can someone advise on the basics, like how to set the address (I think its set by grounding / supplying 6 pins ?).

In PicBASIC PRO I use the following to read the hours minutes and seconds from the DS1307 RTC chip



I2CREAD SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]


The first part is straight forward, and I guess I need to use a different address than $D0,$00 so as not to clash with the RTC chip, but what would I need to do to send the PWM variable to the correct LED channel etc on the PCA chip. I currently use two variables B_PWM and W_PWM which currently has a value of between 0 and 254. It's simple enough to change that to from a byte to word variable as the PCA chip has 4095 steps, but other than that I'm lost ! Any help with interpreting the datasheet would be welcolm

richard
- 15th May 2014, 12:14
if you connect a5 to vcc and a4-a0 to gnd the slave address should be $C0
a quick google of this device found 0 results for example code for any language whatsoever.
(might be natures way of saying "good luck with that")
good luck with that

Scampy
- 15th May 2014, 21:36
Well for reference this works. Its fairly easy to modify the code to use a variables for the value for the pulse width which should be 0 - 4095



i2cControl var BYTE

i2cAddress var BYTE
pcaAddress var BYTE
pcaAddress = $40

i2cAddress = pcaAddress << 1

;Reset
;PCA9685_MODE1 0x0
i2cControl = 0
I2CWRITE SDApin,SCLpin,i2cAddress,i2cControl,[0]

;Set PWM to 500Hz
;Prescaler = 11
;Calculate prescaler by:
;floor((((25000000/4096)/requiredFreqInHertz)-1)+0.5)
;For lack of float support or floor function the value can be calculated and then hard-coded

;Get old mode
oldMode var BYTE
;PCA9685_MODE1 0x0
i2cControl = 0
I2CREAD SDApin,SCLpin,i2cAddress,i2cControl,[oldMode]
newMode var BYTE
;MODE1 Sleep
newMode = (oldMode & $7F) | $10
;Set MODE1 Sleep
;PCA9685_MODE1 0x0
i2cControl = 0
I2CWRITE SDApin,SCLpin,i2cAddress,i2cControl,[newMode]
;Set Prescaler
;PCA9685_PRESCALE $FE
;Prescaler is 11
i2cControl = $FE
I2CWRITE SDApin,SCLpin,i2cAddress,i2cControl,[11]
;Set old mode
;PCA9685_MODE1 0x0
i2cControl = 0
I2CWRITE SDApin,SCLpin,i2cAddress,i2cControl,[oldMode]
Pause 5
;Set MODE1 AutoIncrementOn
;PCA9685_MODE1 0x0
i2cControl = 0
I2CWRITE SDApin,SCLpin,i2cAddress,i2cControl,[oldMode | $A1]


;;Set a PWM channel
;;
pcaChannel var BYTE
pcaPwmValue var BYTE

pcaChannel = 0
pcaPwmValue = 4095
;LED0_ON_L 0x6
i2cControl = $6 + 4*pcaChannel
I2CWRITE SDApin,SCLpin,i2cAddress,i2cControl,[0,0,pcaPwmValue,pcaPwmValue >> 8]

pcaChannel = 1
pcaPwmValue = 1024
;LED0_ON_L 0x6
i2cControl = $6 + 4*pcaChannel
I2CWRITE SDApin,SCLpin,i2cAddress,i2cControl,[0,0,pcaPwmValue,pcaPwmValue >> 8]