Pages: [1]   Go Down
Author Topic: i2c and A/D  (Read 4100 times)
0 Members and 1 Guest are viewing this topic.
cologne, germany
Offline Offline
Jr. Member
**
Karma: 1
Posts: 74
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!?
Code:
#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
}
.
.
« Last Edit: March 18, 2012, 07:04:02 am by Joegi » Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19358
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


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:

Code:
Wire.begin ();
TWBR = 12;



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

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



Quote
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?



Quote
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.
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

cologne, germany
Offline Offline
Jr. Member
**
Karma: 1
Posts: 74
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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!

Quote
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!
Logged

cologne, germany
Offline Offline
Jr. Member
**
Karma: 1
Posts: 74
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
...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!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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)"?
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19358
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 173
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote from: Nick Gammon
To change the speed all you have to do is this:

Code:
Wire.begin ();
TWBR = 12;


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

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19358
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here:

http://www.gammon.com.au/i2c

But I suppose you mean the "real" documentation?

Datasheet, page 241:

Quote
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:

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

Where in twi.h is:

Code:
  #define TWI_FREQ 100000L

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

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

And from the datasheet:

Quote
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:

Code:
16000000 / (16 + 2 * 72) = 100000

But if we change TWBR to 12 we get:

Code:
16000000 / (16 + 2 * 12) = 400000

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

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

0
Offline Offline
Full Member
***
Karma: 0
Posts: 173
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here:

http://www.gammon.com.au/i2c

But I suppose you mean the "real" documentation?

Datasheet, page 241:

Quote
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:

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

Where in twi.h is:

Code:
  #define TWI_FREQ 100000L

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

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

And from the datasheet:

Quote
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:

Code:
16000000 / (16 + 2 * 72) = 100000

But if we change TWBR to 12 we get:

Code:
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?

Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19358
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

http://dsscircuits.com/articles/arduino-i2c-master-library.html

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

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

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

Code:
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?
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19358
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What do you mean "make it 8 bits?"

The address is shifted left one by the Wire library.

http://www.gammon.com.au/i2c
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 130
Posts: 8621
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: