i2c and A/D

Hi,
I use the attached code to realise a VU-Meter with 11 LEDs connected to a TLC59116 LED-driver.
The TLC59116 is connected to the ARDUINO via i2c. I switched the i2c bus to 400kHz frquency (by replacing "#define TWI_FREQ 100000L" with "#define TWI_FREQ 400000L" in "twi.h").
The strange thing is that the higher the values are that i choose for "BRIGHTNESS" (which sets the PWM-brightness of the LEDs and is sent via i2c) the worse are the analog-values ("sample") that I get!
If I activate the "delay(10);" (it has to be at least a 10ms delay) after "Set_LED_NUM_PWM(s, BRIGHTNESS);" this behaviour is gone (and the A/D-values are good)! So it seems that the i2c bus transfer affects the a/d-converter although the Atmega doc says that i2c transfer should not affect the a/d-values!?

#define BRIGHTNESS 50
#define ZERO 500
#define MAXAVG 250
#define NUMSAM 100
.
.
int i, s, sample;
unsigned long sum;
.
.
void loop()
{
  sum = 0;
  for (i = 0; i < NUMSAM; i++)
  {
    sample = analogRead(A0);
    if (sample > ZERO) sample -= ZERO;
    else sample = ZERO - sample;
    sum += sample;
  }
  s = sum / NUMSAM * 11 / MAXAVG;
  if (s > 11) s = 11;
  Set_LED_NUM_PWM(s, BRIGHTNESS);//delay(10);
}
//--------------------------------------------------------------
void Set_LED_NUM_PWM(byte LED, byte PWM)
{
  Wire.begin();      // I2C-Start
  Wire.beginTransmission(B1100000);    // TLC59116 Slave Adress ->C0 hex
  Wire.write((byte)0x82);     // Startregister 02h 
  for (i = 1; i <= LED; i++) Wire.write(PWM);    //set LEDs 1 to x to BRIGHTNESS
  for (; i < 12; i++) Wire.write((byte)0);    //switch off LEDs x+1 to 11
  Wire.endTransmission();    // I2C-Stop
}
.
.

Please edit your post, select the code, and put it between [code] ... [/code] tags.

You can do that by hitting the # button above the posting area.


To change the speed all you have to do is this:

Wire.begin ();
TWBR = 12;

Just do Wire.begin once (in setup), not like this:

void Set_LED_NUM_PWM(byte LED, byte PWM)
{
  Wire.begin();      // I2C-Start

I switched the i2c bus to 400kHz frquency ...

Doesn't seem to be much point if you have to throw in a 10 mS delay. But I suppose that's what the question is about.

In any case, isn't that over-egging the pudding? For a VU-meter, your eyes don't need the extra speed do they?


So it seems that the i2c bus transfer affects the a/d-converter although the Atmega doc says that i2c transfer should not affect the a/d-values!?

Well, it's not is it? You are really saying that if you send one number it works, and if you send a different number it doesn't? This sounds electrical to me. Like, the higher brightness is consuming too much power, and reducing the operation of something else.

Doesn't seem to be much point if you have to throw in a 10 mS delay. But I suppose that's what the question is about.

In any case, isn't that over-egging the pudding? For a VU-meter, your eyes don't need the extra speed do they?

You are right, but I'm just interested why I/one need(s) the delay!

Well, it's not is it? You are really saying that if you send one number it works, and if you send a different number it doesn't? This sounds electrical to me. Like, the higher brightness is consuming too much power, and reducing the operation of something else.

You might be right, I will check this!

-Thanks!

...You are really saying that if you send one number it works, and if you send a different number it doesn't? This sounds electrical to me. Like, the higher brightness is consuming too much power, and reducing the operation of something else.

You are right! I previously connected the complete electronics (TLC59116 + lm386 as main components) to the USB-Powered ARDUINO. Now I connected the ARDUINO to a 2,2A power supply and everything works fine, even without delay! Should have come to the reason for the problems by myself!

hey someone can helpme please?

i dont understand in this line
Wire.write((byte)0);

especify why add "((byte) 0)"
what does when i add "(byte)"?

The compiler gets confused by the number 0, which might be a pointer or it might be a number. Putting (byte) there is a typecast which tells it which "version" of zero to use.

i see
thanks a lot.
greetings.

Nick- where is this documented?
I've recently posted a question in another forum about how to change the I2C bus speed.

Here:

But I suppose you mean the "real" documentation?

Datasheet, page 241:

TWBR – TWI Bit Rate Register

TWBR selects the division factor for the bit rate generator. The bit rate generator is a frequency divider which generates the SCL clock frequency in the Master modes.

In twi.c is this:

 TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;

Where in twi.h is:

  #define TWI_FREQ 100000L

Now normally for a CPU speed of 16000000 that will give:

TWBR =  ((16000000 / 100000) - 16) / 2 = 72

And from the datasheet:

SCL frequency = CPU_FREQUENCY / (16 + 2(TWBR) * (PrescalerValue))

Where the prescaler happens to be 1 in this case.

So substituting, we get the SCL frequency:

 16000000 / (16 + 2 * 72) = 100000

But if we change TWBR to 12 we get:

 16000000 / (16 + 2 * 12) = 400000

Thus, TWBR of 12 gives a clock four times as fast (400000 / 100000) compared to the default.

Thank you for all of that info.

What I am looking for is- what values need to be written to TBR to select the three I2C transfer modes.
You've answered that.

I wonder why the Wire library wasn't written with a simple method to select the transfer mode.
If I wanted to modify Wire to add such a method, where would I go to find out what the procedure is,
such that my changes will be evaluated to be included on upcoming releases?

Who is/are the maintainer(s) of Wire?

Wire is a core module - I suppose the Arduino team at GitHub would do that. However you might want to check out:

I haven't used it, but I believe it adds extra features.

Hi,

I found something interesting when using the TLC59116. In the code above (1st post), the following line is given:

Wire.beginTransmission(B1100000);    // TLC59116 Slave Adress ->C0 hex

However, the B1100000 is only 7 bits. If we make it 8 bits (B11000000), the TLC does not respond. Why is this?

What do you mean "make it 8 bits?"

The address is shifted left one by the Wire library.

I2C doesn't use the LSB for addressing, it's the R/W bit. Therefore the wire library takes your supplied address and left shifts it 1 bit, eg

address_used = your_addr << 1;

So B1100000 becomes B11000000 or B11000001 depending of it it's a read or write operation.

Similarly your B11000000 becomes B10000000 or B10000001 and you lose the upper bit.


Rob

@Graynomad, @Nick Gammon - Thanks! That clears things up.