I use a PCA9685 chip in several projects to control lighting. This gives me 16 channels (or 16 individual lights) which can have their brightness set in 4095 steps.
Variables used for the PCA chip
Code:
i2cControl var BYTE 'Used for PCA chip control
i2cReadAddress var BYTE
i2cWriteAddress var BYTE
pcaAddress var BYTE
oldMode var BYTE
newMode var BYTE
pcaChannel var BYTE
This code sets the chip up
Code:
'*******************************************************************************
'Initialize the PCA9685
i2cReadAddress = pcaAddress << 1
i2cWriteAddress = i2cReadAddress | 1
i2cControl = $0 ;Reset
I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[$0] ;PCA9685_MODE1 $0
i2cControl = $0 'PCA9685_MODE1 $0
I2CREAD SDApin,SCLpin,i2cReadAddress,i2cControl,[oldMode] ;Get old mode
newMode = (oldMode & $7F) | $10 ;MODE1 Sleep
i2cControl = $0
I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[newMode] ;PCA9685_MODE1 $0
i2cControl = $FE ;PCA9685_PRESCALE $FE
I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[6] ;Prescaler is now 6 was 11
i2cControl = $0 ;PCA9685_MODE1 $0
I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[oldMode] ;Set old mode
i2cControl = $0 ;PCA9685_MODE1 $0
I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[oldMode | $A1 ] ;Set MODE1 AutoIncrementOn | $A1
I then have routines that check for on/off times and preset brightness (CHx_PWM) and then the values are written to the PCA chip
Code:
if (CH1_PWM <> PCA1_PWM) then ' check to see if the value has changed, and if it has
PCA1_PWM = CH1_PWM ' match the values in each variable and then write to the PCA chip
pcaChannel = 0
i2cControl = $6 + 4*pcaChannel
I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,CH1_PWM.lowbyte,CH1_PWM.highbyte]
endif
The above is repeated for each channel, but I'm sure you could have some FOR / NEXT loop to write the 16 values to the chip.
It might be clunky code, but it's been controlling the lighting in my wife's 12th scale dolls house for over a year now with no issues. I don't want to post up the full code as I may look at marketing my boards at some point in the future. The good thing about the PCA's outputs is that it can directly drive Meanwell LDD range of LED drivers, making it ideal for use in aquarium lighting, or with the use of a couple of resistors, FETs each channel can be used to switch high current 12v supplies on or off.
Using a PCA chip is a lot simpler than trying to wire up all the ports on a PIC for direct outputs. You could use more than each with a different address if you have multiple external boxes
Hope that helps
Bookmarks