Pages: [1]   Go Down
Author Topic: i2c and A/D  (Read 3861 times)
0 Members and 1 Guest are viewing this topic.
cologne, germany
Offline Offline
Jr. Member
**
Karma: 1
Posts: 73
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
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18768
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


cologne, germany
Offline Offline
Jr. Member
**
Karma: 1
Posts: 73
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: 73
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
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18768
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


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
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18768
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


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
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18768
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


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
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18768
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


nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8517
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: