Word Variable and I2C


Closed Thread
Results 1 to 9 of 9
  1. #1
    Join Date
    Oct 2009
    Posts
    583

    Default Word Variable and I2C

    Hi,

    I had a system that used a byte variable to store the PWM value to fade up and down some leds. It worked well, but having 0-255 the resolution was very noticeable, especially at low values. I now have a chip that communicates over I2C and can drive 12 PWM outputs with a resolution of 4096 steps. The problem is that with a word variable in a similar situation is 0 - 65335 and the device ignores the first 4 bits according to the datasheet ( http://www.nxp.com/documents/data_sheet/PCA9685.pdf )

    Can anyone advise how I can get the resolution to cover the 12bit word range and write this to the chip. I've tried
    Code:
    I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,pcaPwmValue.highbyte,pcaPwmValue.lowbyte >> 8]
    But that doesn't work.

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: Word Variable and I2C

    Hi,
    The likely reason for it not to work the way you have it is because you take the low byte of the word variable and shift it 8 bits to the right, "pushing" the actual value out. Just remove the >> 8 part of it and see if it works.

    On the other hand, the manual says:
    If a word- or long-sized Value is specified, the bytes are sent highest byte first,
    followed by the lower byte(s).
    Which is exactly what you're trying to do so you could simply specify the word size variable, no highbyte/lowbyte stuff needed if I understand correctly.

    /Henrik.

  3. #3
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: Word Variable and I2C

    Although the registers are described as 12 bit they do have 8 bit and 4 bit portions that are accessible separately.

    7.3.3 LED output and PWM control
    The turn-on time of each LED driver output and the duty cycle of PWM can be controlled
    independently using the LEDn_ON and LEDn_OFF registers.
    There will be two 12-bit registers per LED output. These registers will be programmed by
    the user. Both registers will hold a value from 0 to 4095. One 12-bit register will hold a
    value for the ON time and the other 12-bit register will hold the value for the OFF time. The
    ON and OFF times are compared with the value of a 12-bit counter that will be running
    continuously from 0000h to 0FFFh (0 to 4095 decimal).
    Update on ACK requires all 4 PWM channel registers to be loaded before outputs will
    change on the last ACK

    Example 1: (assumes that the LED0 output is used and
    (delay time) + (PWM duty cycle) ≤ 100 %)
    Delay time = 10 %; PWM duty cycle = 20 % (LED on time = 20 %; LED off time = 80 %).
    Delay time = 10 % = 409.6 ~ 410 counts = 19Ah.
    Since the counter starts at 0 and ends at 4095, we will subtract 1, so delay time = 199h
    counts.
    LED0_ON_H = 1h; LED0_ON_L = 99h
    LED on time = 20 % = 819.2 ~ 819 counts.
    Off time = 4CCh (decimal 410 + 819 − 1 = 1228)
    LED0_OFF_H = 4h; LED0_OFF_L = CCh

    I read this to mean that you need four i2c write statements
    led0_on_h = 1h
    led0_on_l =99h
    led0_off_h = 4h
    led0_off_l =cch

    but maybe the registers will auto increment and only one i2c write statement is required.

    I could be wrong and I have no way to test my interpretation.
    Last edited by EarlyBird2; - 20th May 2014 at 06:51. Reason: More thoughts

  4. #4
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Word Variable and I2C

    many thanks for the comments, a lot of which went over my head

    After I posted I re-read the data sheet again and noted that you can define the "start" position and the "end" position of each post. I therefore tried the following, which again didn't work
    I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,1,pcaPwmValue >> 8]

    I've also tried the highbyte / lowbyte option, but again that didn't work, with the values jumping up in tens *ie 4050, 4060, after it passed 255.

    there is an auto increment option, but I'm not sure if this runs but default or needs setting using a register.

  5. #5
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Word Variable and I2C

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    Just remove the >> 8 part of it and see if it works.


    /Henrik.
    Henrik,

    I just tried that with the the following:
    Code:
    pcaChannel = 0                                              ;Set a PWM channel
    pcaPwmValue = B_PWM                                         ;Send current value
    lcdout $FE,$D4+0,"PWM ",dec pcaPwmValue
    i2cControl = $6 + 4*pcaChannel                              ;LED0_ON_L $6
    I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,1,pcaPwmValue]
    I've run a test and that seems to work in as far as the LED on channel 0 fades up. What I did notice though was that the LCD continued to count up past 4095. Notice I placed a 1 as the value for the "ON" setting following Steve's comments. I'm hoping that is correct ?

    I'm re-running the test as I missed the point where the LED on channel one went off. I'm hoping that it was when the value was close or exactly 4095, as at least that would prove the range that is being accepted. Just need to figure out how to specify the size of the variable as you suggest - any pointers ?

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: Word Variable and I2C

    Hi,
    I've run a test and that seems to work in as far as the LED on channel 0 fades up. What I did notice though was that the LCD continued to count up past 4095. Notice I placed a 1 as the value for the "ON" setting following Steve's comments. I'm hoping that is correct ?
    I don't know, I haven't read the datasheet for the device you're using, I only commented on the use of I2CWRITE from a general perspective.

    Just need to figure out how to specify the size of the variable as you suggest - any pointers ?
    Not sure I understand... I've never used I2C but I'm pretty sure that, unlike SHIFTOUT, the transactions are always in bytes. In other words all transactions are in multiple of 8bits. If the device you're talking to is actually USING 1 or 7 or 12 or 14 bits out of the 8 or 16 you send is completely up to that device. However, if the device specify a range from 0 to 4095 then actually SENDING it value outside that range would/could result in unexpected things. Again, I haven't read the datasheet for the device in question.

    As the documentation for I2CWRITE says, specifying a BYTE variable will send a byte variable, specifying a WORD variable will send a WORD variable (two bytes, high byte first).

    If you want to prevent the value you're sending from ever going above 4095 you can, for example, AND it with 4095.

    /Henrik.

  7. #7
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Word Variable and I2C

    Henrik, thanks again for the reply.

    Using the code in my last post (#5) the LED on channel 1 of the PCA chip fades up, all the way until pcaPwmValue reached 4096. At 4097 it went off, and as it increased (now at 6745) the LED on channel 1 has lit up but not on full brightness. What I can't understand is I have a B_MAX variable which has a value of 4095, with an "If B_PWM=B_MAX then doe something else statement which seems to be ignored. I was reading up on the variable statement and the manual comments that there is a size statement, with the use of additional modifiers, but I couldn't find any decent examples. Is there a way of simply limiting the word to 4095 something like B_PWM VAR Word size 4095 ??

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: Word Variable and I2C

    Hi,
    Is there a way of simply limiting the word to 4095 something like B_PWM VAR Word size 4095 ??
    Two ways that I can Think of right now, your way which you've somehow implemented wrong and the way I tried to explain in my previous post.

    Code:
    IF pcaPwmValue >= 4095 THEN pcaPwmValue = 4095   ' Clamp value at 4095
    LCDOUT $FE,$D4+0,"PWM ",dec pcaPwmValue
    Or....

    Code:
    pcaPwmValue = (B_PWM & 4095)    ' Roll over value at 4095
    LCDOUT $FE,$D4+0,"PWM ",dec pcaPwmValue
    By your explaination it sounds as if the PCA chip is basically doing what the second approach above does, ie start over at 4096 and again at 8192 and again 12288 and so on.

    /Henrik.

  9. #9
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: Word Variable and I2C

    Quote Originally Posted by Scampy View Post
    Henrik,

    I just tried that with the the following:
    Code:
    pcaChannel = 0                                              ;Set a PWM channel
    pcaPwmValue = B_PWM                                         ;Send current value
    lcdout $FE,$D4+0,"PWM ",dec pcaPwmValue
    i2cControl = $6 + 4*pcaChannel                              ;LED0_ON_L $6
    I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,1,pcaPwmValue]
    I've run a test and that seems to work in as far as the LED on channel 0 fades up. What I did notice though was that the LCD continued to count up past 4095. Notice I placed a 1 as the value for the "ON" setting following Steve's comments. I'm hoping that is correct ?

    I'm re-running the test as I missed the point where the LED on channel one went off. I'm hoping that it was when the value was close or exactly 4095, as at least that would prove the range that is being accepted. Just need to figure out how to specify the size of the variable as you suggest - any pointers ?
    You are missing some of the detail contained in the user manual.

    If you have not set Auto Increment on your i2cwrite is sending 0 then 0 then 1 then pcaPwmValue to $6.
    To test this change your code to

    I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[pcaPwmValue]

    If I am correct in my interpretation it is also possible that you are only changing the first 8 bits as the 4 upper bits are address $7.

Similar Threads

  1. Stumped with word variable
    By Scampy in forum mel PIC BASIC Pro
    Replies: 30
    Last Post: - 11th November 2013, 13:11
  2. Word variable and storing correct value
    By Scampy in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 28th December 2012, 12:04
  3. SEROUT WORD variable problem
    By Tobias in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 19th April 2009, 11:20
  4. adding new word variable ?
    By iugmoh in forum General
    Replies: 4
    Last Post: - 21st February 2008, 00:26
  5. word variable to 25lc640
    By TONIGALEA in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 6th July 2004, 19:59

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