Closed edlins closed 6 years ago
unsigned char mode1val = 0x00 | _PCA9685_AUTOINCBIT;
works. Note that MODE1
is read as 20
and written as 20
.
pi@raspberrypi:~/src/libPCA9685/examples $ ./PCA9685demo
PCA9685_openI2C(): opened /dev/i2c-1 as fd 3
_PCA9685_readI2CReg(): 40:00:46 20 04 e2 e4 e8 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 04 e2 e4 e8 e0
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
_PCA9685_readI2CReg(): 40:fa:05 00 00 00 00 1e
00 00 00 00 1e
_PCA9685_writeI2CRaw: 00: 06
PCA9685_setPWMVal(): reg fa, on 00, off 00
_PCA9685_writeI2CReg(): 40:fa:01 00
_PCA9685_writeI2CRaw: 40: fa 00
_PCA9685_writeI2CReg(): 40:fb:01 00
_PCA9685_writeI2CRaw: 40: fb 00
_PCA9685_writeI2CReg(): 40:fc:01 00
_PCA9685_writeI2CRaw: 40: fc 00
_PCA9685_writeI2CReg(): 40:fd:01 00
_PCA9685_writeI2CRaw: 40: fd 00
_PCA9685_readI2CReg(): 40:00:01 11
_PCA9685_writeI2CReg(): 40:00:01 11
_PCA9685_writeI2CRaw: 40: 00 11
_PCA9685_writeI2CReg(): 40:fe:01 1e
_PCA9685_writeI2CRaw: 40: fe 1e
_PCA9685_writeI2CReg(): 40:00:01 01
_PCA9685_writeI2CRaw: 40: 00 01
_PCA9685_writeI2CReg(): 40:00:01 81
_PCA9685_writeI2CRaw: 40: 00 81
_PCA9685_writeI2CReg(): 40:00:01 20
_PCA9685_writeI2CRaw: 40: 00 20
_PCA9685_readI2CReg(): 40:00:46 20 04 e2 e4 e8 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 04 e2 e4 e8 e0
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
_PCA9685_readI2CReg(): 40:fa:05 00 00 00 00 1e
00 00 00 00 1e
frames bits ms avg Hz avg kbps avg
unsigned char mode1val = 0x00 | _PCA9685_AUTOINCBIT | _PCA9685_ALLCALLBIT;
also works. Note that MODE1
is read as 20
and written as 21
.
pi@raspberrypi:~/src/libPCA9685/examples $ ./PCA9685demo
PCA9685_openI2C(): opened /dev/i2c-1 as fd 3
_PCA9685_readI2CReg(): 40:00:46 20 04 e2 e4 e8 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 04 e2 e4 e8 e0
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
_PCA9685_readI2CReg(): 40:fa:05 00 00 00 00 1e
00 00 00 00 1e
_PCA9685_writeI2CRaw: 00: 06
PCA9685_setPWMVal(): reg fa, on 00, off 00
_PCA9685_writeI2CReg(): 40:fa:01 00
_PCA9685_writeI2CRaw: 40: fa 00
_PCA9685_writeI2CReg(): 40:fb:01 00
_PCA9685_writeI2CRaw: 40: fb 00
_PCA9685_writeI2CReg(): 40:fc:01 00
_PCA9685_writeI2CRaw: 40: fc 00
_PCA9685_writeI2CReg(): 40:fd:01 00
_PCA9685_writeI2CRaw: 40: fd 00
_PCA9685_readI2CReg(): 40:00:01 11
_PCA9685_writeI2CReg(): 40:00:01 11
_PCA9685_writeI2CRaw: 40: 00 11
_PCA9685_writeI2CReg(): 40:fe:01 1e
_PCA9685_writeI2CRaw: 40: fe 1e
_PCA9685_writeI2CReg(): 40:00:01 01
_PCA9685_writeI2CRaw: 40: 00 01
_PCA9685_writeI2CReg(): 40:00:01 81
_PCA9685_writeI2CRaw: 40: 00 81
_PCA9685_writeI2CReg(): 40:00:01 21
_PCA9685_writeI2CRaw: 40: 00 21
_PCA9685_readI2CReg(): 40:00:46 21 04 e2 e4 e8 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
21 04 e2 e4 e8 e0
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
_PCA9685_readI2CReg(): 40:fa:05 00 00 00 00 1e
00 00 00 00 1e
frames bits ms avg Hz avg kbps avg
unsigned char mode1val = 0x00 | _PCA9685_AUTOINCBIT;
again works as well. Note that MODE1
is read as 21
and written as 20
.
pi@raspberrypi:~/src/libPCA9685/examples $ ./PCA9685demo
PCA9685_openI2C(): opened /dev/i2c-1 as fd 3
_PCA9685_readI2CReg(): 40:00:46 21 04 e2 e4 e8 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
21 04 e2 e4 e8 e0
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
_PCA9685_readI2CReg(): 40:fa:05 00 00 00 00 1e
00 00 00 00 1e
_PCA9685_writeI2CRaw: 00: 06
PCA9685_setPWMVal(): reg fa, on 00, off 00
_PCA9685_writeI2CReg(): 40:fa:01 00
_PCA9685_writeI2CRaw: 40: fa 00
_PCA9685_writeI2CReg(): 40:fb:01 00
_PCA9685_writeI2CRaw: 40: fb 00
_PCA9685_writeI2CReg(): 40:fc:01 00
_PCA9685_writeI2CRaw: 40: fc 00
_PCA9685_writeI2CReg(): 40:fd:01 00
_PCA9685_writeI2CRaw: 40: fd 00
_PCA9685_readI2CReg(): 40:00:01 11
_PCA9685_writeI2CReg(): 40:00:01 11
_PCA9685_writeI2CRaw: 40: 00 11
_PCA9685_writeI2CReg(): 40:fe:01 1e
_PCA9685_writeI2CRaw: 40: fe 1e
_PCA9685_writeI2CReg(): 40:00:01 01
_PCA9685_writeI2CRaw: 40: 00 01
_PCA9685_writeI2CReg(): 40:00:01 81
_PCA9685_writeI2CRaw: 40: 00 81
_PCA9685_writeI2CReg(): 40:00:01 20
_PCA9685_writeI2CRaw: 40: 00 20
_PCA9685_readI2CReg(): 40:00:46 20 04 e2 e4 e8 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 04 e2 e4 e8 e0
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
_PCA9685_readI2CReg(): 40:fa:05 00 00 00 00 1e
00 00 00 00 1e
frames bits ms avg Hz avg kbps avg
I can't think of any reason why ALLCALL
= 0 would cause your chip to freeze. There must be something else hidden that we can tease out.
Also, if you want to whip up a trivial test app that locks up your chip, I can test that on my system. You could just do an init with ALLCALL
, set the PWMs, re-init without ALLCALL
, and set the PWMs again. Just put in a PR against develop
and I can fetch the branch without merging.
Eventually, I'd like a suite of test cases and those might be easiest with tiny unit test apps that generate stdout that I can compare to expected stdout.
Just pushed another PR to develop
for the demo that uses command line options instead of compiler constants. This allows you to enable debug, validate, and ncurses from the command line without recompiling. Just add -d
, -v
, and/or -n
to the command line. Right now you still have to use #define
in the lib source.
One more PR... :smiley: Should be done for the day. Now debugging output for the demo AND the lib are controlled by -d
passed to the demo. It sets a debug flag in the app and the debug flag _PCA9685_DEBUG
in the lib at runtime. No more recompiling to add/remove debugging!
Really good stuff - exactly what I wanted and I got it without asking!
It's a "hardware night" for me, so I may not even get to any testing, then over the weekend I install some of this hardware on the boat... Once it's installed I need to get the software working right, so I'll be sure to work on it though the week next week.
(PS: Amazing what happens with an old project when someone else gets interested in it and gives you a bump, huh? :D )
Update: I think that this whole thing may have been a combination of bad luck and lack of understanding on my behalf...
Here's the scoop: My Pi Zero W shows address 0x40 as "UU" - which as I recall means unusable, but when my latest batch of PCA9685 devices come up they seem to have ALLCALL enabled by default (I'm quite certain this wasn't the case with an older batch and I will test this). The ALLCALL address is 0x70, and I was using this address thinking that I had simply mixed up setting my address bit and set the MSB rather than the LSB
So, I was actually accessing the device with ALLCALL address when I was testing this lib, and this perfectly explains why it didn't work for me unless it kept the bit set when the device was reset, as that address would have went away.
For reference, here's one of my new boards with address 0x42 set:
root@raspberrypi:/usr/local/src/edlins/libPCA9685/examples/PCA9685demo # i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: UU -- 42 -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --
Note that it shows two addresses, which makes perfect sense (and should have been obvious earlier).
I will confirm this to be 100% certain, but it seems like it's pretty clear.
Cool, thanks for the update! Makes sense, I was thrown by the MSB/LSB address issue also. If you confirm this 100% I'll roll back the ALLCALL mod.
Yes, that was definitely what was happening, and it completely explains everything I saw happen. Sorry about all the bother! Learning experience though - I now understand perfectly how the ALLCALL works and that will be handy for me.
Also, an option to enable ALLCALL address might be nice... we'll see how my evening goes and I may look into it
Sounds good. I'll close this and open a new issue for enabling options such as ALLCALL.
Follow-up issue to investigate why having the
ALLCALL
bit inMODE1
set to zero causes a lockup for @pvint but not on my Adafruit board. Please enable#define DEBUG
in both the library and the demo and include the output here. Also please disable//#define VALIDATE
and//#define NCMODE
in the demo.