edlins / libPCA9685

superfast PCA9685 library for Debian platforms. developed on Raspbian on a Pi B+.
MIT License
13 stars 8 forks source link

Running the example code locks up my PCA9685 #1

Closed pvint closed 6 years ago

pvint commented 6 years ago

Hi! First off - I was very glad to find this! This is exactly what I wanted... I've been using and modifying the Adafruit Python libs for this, and while it works fine I find that it's pretty bloated and slow, and you have saved me the bother of writing this in C. Thanks!

When I try to run the PCA9685demo in examples it's locking up my device and i2cdetect -y 1 doesn't even see it after running this. A power cycle of my board clears it up, and my Python scripts then work again.

I'm about out of time to try to debug this right now, and I am really just adding this issue for my own records and I will look at it more.

Here is what I see on the console when I run ./PCA9685demo with #define DEBUG set:


PCA9685_openI2C(): opened /dev/i2c-1 as fd 3
_PCA9685_readI2CReg(): 70:00:46 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 
_PCA9685_readI2CReg(): 70:fa:05 00 00 00 00 00
00 00 00 00 00 
_PCA9685_writeI2CRaw: 00: 06
PCA9685_setPWMVal(): reg fa, on 00, off 00
_PCA9685_writeI2CReg(): 70:fa:01 00
_PCA9685_writeI2CRaw: 70: fa 00
_PCA9685_writeI2CReg(): 70:fb:01 00
_PCA9685_writeI2CRaw: 70: fb 00
_PCA9685_writeI2CReg(): 70:fc:01 00
_PCA9685_writeI2CRaw: 70: fc 00
_PCA9685_writeI2CReg(): 70:fd:01 00
_PCA9685_writeI2CRaw: 70: fd 00
_PCA9685_readI2CReg(): 70:00:01 11
_PCA9685_writeI2CReg(): 70:00:01 11
_PCA9685_writeI2CRaw: 70: 00 11
_PCA9685_writeI2CReg(): 70:fe:01 1e
_PCA9685_writeI2CRaw: 70: fe 1e
_PCA9685_writeI2CReg(): 70:00:01 01
_PCA9685_writeI2CRaw: 70: 00 01
_PCA9685_writeI2CReg(): 70:00:01 81
_PCA9685_writeI2CRaw: 70: 00 81
_PCA9685_writeI2CReg(): 70:00:01 20
_PCA9685_writeI2CRaw: 70: 00 20
_PCA9685_readI2CReg(): ioctl() returned -1 on addr 70 start 00
PCA9685_dumpAllRegs(): _PCA9685_readI2CReg() returned -1
initHardware(): PCA9685_dumpAllRegs() returned -1
PCA9685_setPWMVal(): reg fa, on 00, off 00
_PCA9685_writeI2CReg(): 70:fa:01 00
_PCA9685_writeI2CRaw: 70: fa 00
_PCA9685_writeI2CRaw(): ioctl() returned -1 on addr 70
_PCA9685_writeI2CRaw(): len = 2, buf = fa 00 
_PCA9685_writeI2CReg(): _PCA9685_writeI2CRaw() returned -1 on addr 70 reg fa
PCA9685_setPWMVal(): _PCA9685_writeI2CReg() returned -1 on addr 70 reg fa val 00
PCA9685_setAllPWM(): PCA9685_setPWMVal() returned -1
main(): initHardware() returned -1 for adpt 1 at addr 70
root@raspberrypi:/usr/local/src/libPCA9685/examples # ```

After that I can no longer see the device on my I²C bus until I power cycle it. Note that this is a board of my own design, so it's conceivable that there's a hardware issue, however I have been using it a lot with the Python scripts and have never run into an issue.

I will look at this more (and the debugging output is nice, btw), but if I cannot figure out anything from the software side I will put my scope on the bus and do some tests to see if I can see what might be different.

Thanks again! 
Paul
edlins commented 6 years ago

Hi there! Glad this appears to be of possible use to you. I haven't debugged this in about two years, but I might be able to fire up my B+ and test my homebrew RGB LED array that this was written for. In the meantime, are you using this on a RPi and if so which one? Also, per the README what is this value?

dtparam=i2c_arm_baudrate

Try cutting that way down when debugging. Also, are you sinking or sourcing current on the pins? Could your board power supply rail be dipping too low? Are you using two different power supplies? One guess is that running at much higher speed causes power to your system board to dip too low. You may also need some I2C snubbers. I recall needing one or two decoupling caps on the PCA9685 power. A good scope and good scope skills would really help. I wished I'd had one..

pvint commented 6 years ago

Thanks for the quick response - I'm looking at this now, but a couple quick answers to your questions:

1 - Tried with baudrate set as per README, also with it unset, and with it set to 100000 and no difference (and the device always works with the python script) 2 - Power supply: I doubt this is an issue since it works fine with another library (but I am not excluding the possibility!).

  1. I2C and decoupling: As above, I think I'm ok there since it works well with the other lib
  2. I'm sourcing current to a BJT (<5mA)

I'll get back later after some troubleshooting.

For reference and curiosity's sake, here's my schematic and the board:

sable25 img_20180416_182055

pvint commented 6 years ago

Oh yeah - I'm using a Pi Zero Wireless

edlins commented 6 years ago

Okay, so different board and different Pi. Here's the board I'm using at Adafruit. Datasheets should be the same.

Here's my read of the debug output:

PCA9685_openI2C() successfully calls open() and ioctl with I2C_SLAVE to set the address, but neither of these actually accesses the I2C device. That's just setup for access.

_PCA9685_readI2CReg(): 70:00:46 succeeded reading from addr 0x70, start register 0x00, length 46 to dump all led registers (all were 0x01).

_PCA9685_readI2CReg(): 70:fa:05 also succeeded reading from addr 0x70, start register 0xfa, length 5 (all 0x00) to dump all status registers (all were 0x00).

Then we get into PCA9685_initPWM which first calls _PCA9685_writeI2CRaw: 00: 06 which successfully wrote 0x06 to register 0x00 to send a software reset.

Next in init was PCA9685_setPWMVal(): reg fa, on 00, off 00 which turned all led's off. You can see that in the subsequent calls like _PCA9685_writeI2CReg(): 70:fa:01 00 on 0xfa through 0xfd.

Next in init was _PCA9685_setPWMFreq. You can see that in the subsequent _PCA9685_readI2CReg(): 70:00:01 11 (chip is in mode 0x11 at this point) and update the mode to 0x11 (same mode) with _PCA9685_writeI2CReg(): 70:00:01 11.

Next in Freq inside init was write the prescale with _PCA9685_writeI2CReg(): 70:fe:01 1e.

Next in Freq was _PCA9685_writeI2CReg(): 70:00:01 01 which is the wakeup. Then there is a silent 500us delay to allow the oscillator to stabilize. Then there was a reset with _PCA9685_writeI2CReg(): 70:00:01 81. Now Freq is done.

Last in init was the final _PCA9685_writeI2CReg(): 70:00:01 20.

After init next in initHardware was PCA9685_dumpAllRegs which failed on the first register read.

If I had to guess, I'd say the 500us delay did not work correctly but you should especially check the writes to the mode1 register (0x00) to make sure the proper initialization procedure is being followed. Maybe use a different method to sleep or increase the length of the sleep.

pvint commented 6 years ago

I played with delays to no avail, but some further reading on the datasheet led me to believe that the mode1 register setting was amiss, and it was!

Enabling the SUB1 SUB2 SUB3 and ALLCALL bits cleared the issue and it works great now!

I went ahead and submitted a PR #2

Thanks so much, time for actually trying to use this now!

pvint commented 6 years ago
edlins commented 6 years ago

Please try my #3 as I'm trying to get master up to date with what I did a while ago.

edlins commented 6 years ago

My setup: img_20180418_142822

edlins commented 6 years ago

Your master branch changes had no (detrimental) effect on my update branch so I went ahead and merged into master and update. Could still use a quick test of my update branch if you don't mind.

pvint commented 6 years ago

Aha! That's pretty neat! I can see that more than a couple hours disappeared in the making of that ;) The lexan case is a cool idea.

I saw the merge and the updates - cool. I'm busy for a bit, but in a couple hours I will test everything out. Lots to do tonight... my new PCBs arrive tomorrow so lots of soldering, assembling and testing tomorrow night and hoping to call this one the "final" design and install on my boat on the weekend, and I plan to use this code so I'll also need to create a rudimentary CLI program too...

edlins commented 6 years ago

I went ahead and rebased and merged everything since it looks good on my side. Make sure you try "automatic" mode in the demo. Does a nice slow color cycling. Or go "manual" and adjust each channel individually. Let me know if the current master branch has any issues for you.

pvint commented 6 years ago

I only tried manual just now... works great! (pulled from master after you merged #3 ) I have to fix a sink... back for more tests after that. ;)

edlins commented 6 years ago

Cool! master is now completely up to date. I created "develop" (identical to master) for future PRs. Please develop against "develop" and submit PRs against "develop" (not master). That way I can manage version numbers when I merge "develop" into master.

edlins commented 6 years ago

If this issue is resolved, I would be honored for you to officially close #1. Would also love to see any of your examples added to the examples folder!

pvint commented 6 years ago

Sounds perfect on the branches. I was thinking the same for the "examples", and it would be helpful for me as well since I am really just a hardware guy living in a software world (wasn't that a Madonna song?) and any comments on my coding is appreciated.

Thanks again @edlins !

Issue resolved.

pvint commented 6 years ago

Turns out this was a result of my hardware (Pi Zero Wireless) blocking address 0x40, but the ALLCALL address (0x70) was enabled by default on my device (and a misunderstanding on my behalf thinking 0x70 was the "real" address)

See https://github.com/edlins/libPCA9685/issues/11#issuecomment-383775262 for more details.