Further to the advice by hippy the datasheet Ali indicate there are no pull up resistors on the ports so I suggest they could be floating.
Therefore in addition to pulling the address pin A2 high it is recommended to pull all the other pins down to zero volts/low logic voltage level.
Hippy explained why 0x84 is the device address. If you have A1 set to 1, and the others (A0,A2-A5) set to zero, then the address is 10000100. The apparent address is shifted to the left to allow for bit 0 to be the read/write indicator. Make sure you have pulled A1 up and the others are pulled down. As Westaust says, any unconnected pins may be floating and so the address would be undefined.
I'm not sure what you are trying to write (I have not read the datasheet in detail), but the LED addresses start at x06 and then come in pairs (LO and HI),
so I would expect - if you are trying to light LEDs - to see something like
It will also be necessary to set the MODE1 register before the chip becomes active. When powered up the default appears to be that the chip will be in a low-power 'sleep' state and that will need to be cleared.
LED brightness control is achieved by writing four bytes per LED; it seems necessary to enable address auto-increment to allow multiple bytes to be sent with a single HI2COUT command.
It may also be necessary to set MODE2 register so the LED drives are set as appropriate and the external /OE is configured as required.
The PCA9685 is an I²C-bus controlled 16-channel LED controller optimized for Red/Green/Blue/Amber (RGBA) color backlighting applications. Each LED output has its own 12-bit resolution (4096 steps) fixed frequency individual PWM controller that operates at a programmable frequency from a typical of 24 Hz to 1526 Hz with a duty cycle that is adjustable from 0 % to 100 % to allow the LED to be set to a specific brightness value. All outputs are set to the same PWM frequency."
Though it's a LED controller I would guess that should work for controlling servos using a typical 50Hz / 20ms frame rate assuming a suitable rate can be selected. Servos usually require an accurate pulse length but are often more flexible with the frame frequency and rate.
The PCA9685 has a single 8-bit clock pre-scaler ( register $FE ) and, according to the datasheet, its value should be set as -
pre-scaler value = ( clock / ( 4096 * update frequency ) ) - 1
Note that the pre-scaler can only be written when in sleep mode, so it's probably the first register which needs to be set, or at least set before taking the chip out of sleep mode.
So, if a 'PWM value' of 0 to 4095 gives an on period of 0ms to 20ms it should then be a simple matter of converting a servo position of 50 to 250 into a suitable off times to write to the LED control values -
offTime = servoPosition * 4095 / 2000
Untested, but I would guess something like -
Symbol MODE1_REG = $00
Symbol MODE2_REG = $01
Symbol LED0_REG = $06
Symbol PRESCALE_REG = $FE
Symbol offTime = w0 ; 0 to 4095
Symbol offTime.lsb = b0
Symbol offTime.msb = b1
Symbol register = b2
Symbol servoNumber = b3 ; 0 to 15
Symbol servoPosition = b4 ; 50 to 250
HI2cSetup I2CMASTER, $84, I2CSLOW, I2CBYTE
Hi2COut MODE1_REG, ( %00110000 )
For servoNumber = 0 To 15
servoPosition = 150
Hi2COut PRESCALE_REG, ( 121 )
Hi2COut MODE2_REG, ( %00000100 )
Hi2COut MODE1_REG, ( %00100000 )
servoNumber = 0
For ServoPosition = 100 To 199
For ServoPosition = 200 To 101 Step -1
register = servoNumber * 4 + LED0_REG
servoPosition = servoPosition Min 50 Max 250
offTime = servoPosition * 2
offTime = servoPosition ** 3112 + offTime
HI2cOut register, ( 0,0, offTime.lsb,offTime.msb )
You are welcome, and I am sure everyone who helped is delighted with your success.
A good way to show appreciation, as well as helping others in future, is to post the code which you have got working. Having a 'reference design' of something known to work is always a good thing, better than guessing how it should be without knowing if that's right or not.
I have never used multiple servos but this looks like a good chip to use for that even though it was not intended for such a thing. It should be fairly easy to adjust the channel timing to have servo pulses sequentially rather than starting simultaneously if that is desirable. It may also have other uses beyond LED's or servos; multiple motor drives is one thing which springs to mind.
I'll be honest, I had never heard of the chip before you mentioned it, so thanks for doing so.
I missed this thread, but doubt I could have offered any help with it driving servos.
I have an Adafruit module utilizing this chip running a stepper motor on my greenhouse/cold frame project. It works well but was a brain bender to decipher the datasheet and ended up using Adafruit's example Arduino code to translate it into PICAXE BASIC. I'll post my code snippet in the finished projects section just in case someone else needs a little help making it work with steppers.
I use a PCA9685 (from Adafruit) to run the lighting effects on my fishing yak control system. If you have the patience to read through the Picaxe Basic code in the following link, there is everything you need to know to use the PCA9685 with any Picaxe that has I2C.
Note that the proc (aka subroutine) “LED.outputs_Set” shows how to set multiple PCA9685 channels with a single I2C write. All procs that control the PCA9685 begin with “LED.” You may also want to look at the proc init. Note that I only use the first 8 channels but the software would be easy to expand to all 16.
Note that when writing to multiple lights/servos there are 2 preceding zeros. This specifies an offset to keep multiple devices from bumping the power source at once (offsets not usually needed for servos, but for home lighting or electronic billboards may be an issue).
for example: (where AL AH are the low-byte hi-byte for the 0…4095 timing interval for the first channel, etc.)
Hi to everyone, thank you again, I will check this new info, I modify some lines in the program and works very well, I'm using this code to communicate to 6x6 robot, the robot has some ESC, servos, and lights and works awesome, my next issue is to communicate a PS2 (PlayStation 2) steering wheel controller and pedals to picaxe 18m2, I need many memory banks to make different routines and vibration function because has a lot of buttons. if somebody knows about it please help me because I'm really lost on it. I will show you some pictures of my project soon.
Something I forgot to mention in my previous post. You may wonder why my notes on servos in the attached .pdf Pwm1_rw2_sch.pdf use a 200 Hz update frequency on the servos instead of the typical 50 Hz. Well, on the PCA9685 the base frequency is used by all 16 channels. When controlling lights you need the 200 Hz to make sure there is no flicker at low PWM values (i.e. a very dimmed light). All servos I’ve used work just fine at 200 Hz (they are looking for the 1…2mS pulse, not a specific update period).
The net effect is that using a base frequency of 200 Hz, you could for example control 8 dimmable lights and 8 servos
using the same PCA9685. That way your robot can be stylish as well as functional (always wanted to say that).
Note that the PCA9685 is a set it and forget it device. You won’t need to update anything until you change a setpoint.
Looking forward to seeing your project. It sounds interesting. Best of luck!