PCA9685 control


Closed Thread
Results 1 to 11 of 11

Thread: PCA9685 control

  1. #1
    Join Date
    Oct 2009
    Posts
    583

    Default PCA9685 control

    Hi,

    I've used the above chip in several projects before, but have noticed a small issue with a current project as the code is writing to the PCA chip each time in the loop and I think it's causing the flicker in the LEDs on the output pins of the PCA chip.

    I have the following section of code repeated for each of the 16 channels

    Code:
    If Counter1 => CH1_on_Time and counter1 < CH1_off_time then                     ' check to see if the time in minutes since midnight matches the Channel on time
    CH1_PWM  = fadeset1                                                             ' and of so set the PWM value (0 to 4095) to match the fadeset value (also 0 - 4095)
    endif                                                                           
    If Counter1 => CH1_off_Time or Counter1 < CH1_on_time then                      ' check to see if the time in minutes since midnight matches the channel off time
    CH1_PWM  =0                                                                     ' and if it does, then set the PWM value to 0, this turning the channel off
    endif
    The comments are self explanatory. At the end of the main program loop I have a gosub to a subroutine that writes to the chip

    Code:
    pcaChannel = 0                                            
    i2cControl = $6 + 4*pcaChannel                            
    I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,CH1_PWM.lowbyte,CH1_PWM.highbyte]

    Now typically once the brightness (fadeset1, fadeset2, etc) has been set, and the condition is met to output the PWM value there would be no need to alter it whilst it's ON/OFF condition is met, and as the PCA chip maintains the value it only needs to be written to once at the start of the condition. However there is a need for the program to loop, and thus check for any of the on/off times are met and if so write the value of its corresponding fadeset variable, so how best to prevent the loop from writing to the PCA chip on each cycle.

    Any ideas ?

  2. #2
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: PCA9685 control

    Have you thought of using a Flag variable?
    During your checking routine, set a Flag if you need to write to the PCA.
    Check the Flag to determine if you need to do the gosub to write to the PCA chip.
    Regards,
    TABSoft

  3. #3
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: PCA9685 control

    Uhmmm - it only really seems noticeable when all the LEDs are on... I might need to do further investigation...

  4. #4
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: PCA9685 control

    Tabsoft, thanks for the suggestion,

    It seem to dim for a split second only when all outputs are high, if only 15 are lit there is no distinguishing flicker.

    Well it's not a power issue as I've just used a 5v supply rather than the 5v from the development board and it still dims very slightly when it the data is written to the PCA chip but only when all 16 channels are outputting a value

    Belay that... its actually is noticeable with less than 15
    Last edited by Scampy; - 25th March 2016 at 22:34.

  5. #5
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: PCA9685 control

    Quote Originally Posted by Tabsoft View Post
    Have you thought of using a Flag variable?
    During your checking routine, set a Flag if you need to write to the PCA.
    Check the Flag to determine if you need to do the gosub to write to the PCA chip.
    Can't get my head round it, at least because the condition at which the PCA get written to will be true.

    I thought of
    Code:
    If Counter1 => CH1_on_Time and counter1 < CH1_off_time then                     ' check to see if the time in minutes since midnight matches the Channel on time
    CH1_PWM  = fadeset1
    flag=1  
    endif
    with a IF Flag=1 then gosub update... but that would still cause the update subroutine to be updated on each pass of the loop...

  6. #6
    Join Date
    Aug 2011
    Posts
    412


    Did you find this post helpful? Yes | No

    Post Re: PCA9685 control

    Instead of just setting a flag, keep a copy of the last thing written to the PCA and only call the sub if it's different from CH1_PWM

    Code:
    If Counter1 => CH1_on_Time and counter1 < CH1_off_time then                     ' check to see if the time in minutes since midnight matches the Channel on time
    CH1_PWM  = fadeset1                                                             ' and of so set the PWM value (0 to 4095) to match the fadeset value (also 0 - 4095)
    endif                                                                           
    If Counter1 => CH1_off_Time or Counter1 < CH1_on_time then                      ' check to see if the time in minutes since midnight matches the channel off time
    CH1_PWM  =0                                                                     ' and if it does, then set the PWM value to 0, this turning the channel off
    endif
    ...
    ' check to see if CH1_PWM is different from last programmed value
    if (CH1_PWM <> PCA_PWM) then
        gosub SetPCA
    endif
    
    
    
    SetPCA:
        PCA_PWM = CH1_PWM
        pcaChannel = 0                                            
        i2cControl = $6 + 4*pcaChannel                            
        I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,PCA_PWM.lowbyte,PCA_PWM.highbyte]
        return

  7. #7
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: PCA9685 control

    Quote Originally Posted by tumbleweed View Post
    Instead of just setting a flag, keep a copy of the last thing written to the PCA and only call the sub if it's different from CH1_PWM

    Code:
    If Counter1 => CH1_on_Time and counter1 < CH1_off_time then                     ' check to see if the time in minutes since midnight matches the Channel on time
    CH1_PWM  = fadeset1                                                             ' and of so set the PWM value (0 to 4095) to match the fadeset value (also 0 - 4095)
    endif                                                                           
    If Counter1 => CH1_off_Time or Counter1 < CH1_on_time then                      ' check to see if the time in minutes since midnight matches the channel off time
    CH1_PWM  =0                                                                     ' and if it does, then set the PWM value to 0, this turning the channel off
    endif
    ...
    ' check to see if CH1_PWM is different from last programmed value
    if (CH1_PWM <> PCA_PWM) then
        gosub SetPCA
    endif
    
    
    
    SetPCA:
        PCA_PWM = CH1_PWM
        pcaChannel = 0                                            
        i2cControl = $6 + 4*pcaChannel                            
        I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,PCA_PWM.lowbyte,PCA_PWM.highbyte]
        return
    thanks, that seems logical as the only change will be if the ON or OFF condition is met. Thanks, I'll give that a try

  8. #8
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: PCA9685 control

    It must be something to do with the internals of the PCA chip as the modified code that includes Tumbleweed's suggestion has the same effect, even though the PIC code isn't running the subroutine (I have a led that is lit whilst the sub routine is being accessed and that pulses once when the lights come on, and once again when the lights go off)

    Would there be anything to gain if the code in the SetPCA: section above is placed in the check section like this

    Code:
    If Counter1 => CH1_on_Time and counter1 < CH1_off_time then                     ' check to see if the time in minutes since midnight matches the Channel on time
    CH1_PWM  = fadeset1                                                             ' and of so set the PWM value (0 to 4095) to match the fadeset value (also 0 - 4095)
    endif                                                                           
    If Counter1 => CH1_off_Time or Counter1 < CH1_on_time then                      ' check to see if the time in minutes since midnight matches the channel off time
    CH1_PWM  =0                                                                     ' and if it does, then set the PWM value to 0, this turning the channel off
    endif
    ...
    ' check to see if CH1_PWM is different from last programmed value
    if (CH1_PWM <> PCA_PWM) then
    PCA_PWM = CH1_PWM
        pcaChannel = 0                                            
        i2cControl = $6 + 4*pcaChannel                            
        I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,PCA_PWM.lowbyte,PCA_PWM.highbyte]    
    endif

  9. #9
    Join Date
    Aug 2011
    Posts
    412


    Did you find this post helpful? Yes | No

    Default Re: PCA9685 control

    Would there be anything to gain if the code in the SetPCA: section above is placed in the check section like this
    It'll save you the call/return (so slightly less time/code), but it won't really change the timing much in the grand scheme of things.

    If the flicker is caused by writing too often to the PCA it won't change that at all.

  10. #10
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: PCA9685 control

    I took delivery of a logic analyser today and thought I would test it to see what the outputs are like at different brightnesses. I've got some really strange traces and wondered if anyone has any ideas as to why the PCA chip is behaving like this.

    I set the brightness to 10%, and did a scan and this was the result



    I was expecting to see eight traces the same as channel 7 at the bottom, but the other channels seems to have a strange artefact, so I zoomed in to see if it was just something to do with the way the traces were being displayed on the screen, but this was the result



    The "normal" pulse was itself split up into a series of multiple pulses, so I zoomed in again and took a measurement



    I have no idea what's happening, and I still can't find any evidence of the chip refreshing momentarily once a second which would tie in with the regular 1sec flicker that is noticeable to the eye

  11. #11
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: PCA9685 control

    I think I've sorted it... possible ground loop, removed the GND wires between the LA and breadboard and now all seems fine

Similar Threads

  1. Diseqc control anyone ?
    By RFsolution in forum mel PIC BASIC Pro
    Replies: 11
    Last Post: - 10th August 2016, 06:42
  2. Control de puertos PIC16F877A / Port Control PIC16F877A
    By martintorres in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 4th October 2013, 03:49
  3. Version Control
    By btaylor in forum mel PIC BASIC Pro
    Replies: 33
    Last Post: - 16th October 2011, 17:12
  4. How do I give a radio control car autonomous control
    By Kenjones1935 in forum General
    Replies: 190
    Last Post: - 17th January 2010, 15:40
  5. Control RC servo via Parallax Servo Control
    By cibotsan in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 17th September 2005, 08:18

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts