0
\$\begingroup\$

I am new to electronics, circuits, etc. Currently I am reading I2C and synchronous serial communications. As I understand, two devices must be connected to the same CLOCK wire so that the slave knows at which rate to interpret data because it might not have an internal clock. Now, I wanted to see how fast SCL pin on Arduino Uno oscillates by connecting a LED to it and GND and expected the LED to blink fast. Of course, as I believe, I attenuated the frequency to 1 by using Wire.h library and calling

Wire.setClock(1);

as it is said here. The LED still didn't blink as I expected - once a second. What is wrong? How does SCL behave actually? Does it oscillate from 0V to 5V periodically or I must manually do this in the code?

EDIT

The complete sketch was as follows

#include <Wire.h>


void setup() {
  // put your setup code here, to run once:
  Wire.setClock(1);
}

void loop() {
  // put your main code here, to run repeatedly:

}

EDIT 2

I built a circuit. The LED is turned on but it doesn't blink. I also tried changing the frequency in the code from 1 to different values up to 100000.

Arduino with a LED connected to SCL pin through pull up resistors

EDIT 3

It blinks! But I am not sure is it actually SCL making it blink. I added Wire.begin() in setup() and started together with ending a transmission in the loop(). But it doesn't react to changes in setClock(frequency). Also I tried to put a delay or send long random text with Wire.write() between Wire.beginTransmission(0xA3) and Wire.endTransmission(). Then it just blinks once (maybe multiple times but fast) in the beginning and then stops blinking just being on. The complete code is

#include <Wire.h>


void setup() {
    // put your setup code here, to run once:
    Wire.setClock(32000);
    Wire.begin();
}

void loop() {
    // put your main code here, to run repeatedly:
    Wire.beginTransmission(0xA3); //arbitrary address
    Wire.endTransmission();
}
\$\endgroup\$
4
  • 2
    \$\begingroup\$ It's uncertain that the I2C system would support a rate as low as 1 Hz, but even if it did, SCL is only active during an (attempted) i2c transaction, and you have not triggered one. Typically you need an oscilloscope or something like a CY7C68013A-based USB logic analyzer to see something like this - slowing it down to eyeball speed isn't necessarily going to be supported. \$\endgroup\$ Jul 21, 2018 at 16:55
  • \$\begingroup\$ @ChrisStratton, yep, this is the sure reason for not seeing anything. \$\endgroup\$ Jul 21, 2018 at 17:13
  • 2
    \$\begingroup\$ The fundamental lesson is that this just not something you're going to be able to see by eye without drastically changing it (using a slowed bit-bang implementation etc). In many situations like this you need test equipment, fortunately today that can be inexpensive - a CY7C68013a board to use as a logic analyzer will only cost you around $15 and you can run it with free software like sigrok and pulseview. \$\endgroup\$ Jul 21, 2018 at 17:43
  • 1
    \$\begingroup\$ @ChrisStratton "a CY7C68013a board to use as a logic analyzer will only cost you around $15" ... that's actually exactly what this commonly available Chinese device is, for somewhat less money. Details here \$\endgroup\$
    – Jules
    Jul 21, 2018 at 21:29

3 Answers 3

2
\$\begingroup\$

The minimum frequency your I2C clock is capable of running at (see end for details) is far higher than you will be able to see - your eyes physically cannot see it blinking at >30[kHz]. At most you'll see the LED being slightly dimmer than expected as data is being sent - might look like a single blink for the entire I2C packet.

Additionally if you have wired up your LED from the pin to GND, you will also see nothing as I2C is open-drain. That means it can only sink current. You would have to connect the LED with anode to +5V (via resistor), and cathode to the SCL pin. But again you wouldn't be able to see anything. I see it is not from your picture.

Furthermore, the I2C clock is not constantly running. The clock output is produced only when you send data. As your code never sends an I2C packet (the loop() function is empty), the I2C core will never generate a clock.

Once you start generating packets, you still wont see the clock blinking at its actual frequency. You might see it "blink", but the duration of the blink will actually contain multiple I2C packets. This is exactly the same as how you can make an LED dimmer by using PWM - you see the dip in brightness, but you cannot see the actual PWM frequency.

If you want to view the clock signal, you will require some form of logic analyser.



Due to hardware limitations, the ATMega328 cannot run the I2C clock rate at 1Hz (using hardware I2C). Regardless of what the API you are using allows you to enter.

The formula for calculating baud rate is:

$$f_{SCL} [Hz] = \frac{f_{CPU}}{16 + 2\cdot TWBR\cdot Prescaler}$$

Where the \$TWBR\$ register is an 8-bit value. \$Prescaler\$ is at most 64, but in the case of Arduino is set to 1 (can be gathered from the source code calculation being used). This gives:

$$f_{SCL(min)} [Hz] = \frac{16[MHz]}{16 + 2\cdot 255\cdot 1} = 30.418 [kHz]$$

The setClock API is shockingly written as it provides no form of error checking. In your case when you try to set a value of 1, this will try to write a value of 7999992 to the 8-bit \$TWBR\$ register, causing an overflow that will actually set the I2C rate to 30.418kHz.

\$\endgroup\$
10
  • \$\begingroup\$ The hardware I2C can't run slower - vicatu's erroneous claim that it could does the asker a real dis-service. A software bit-bang I2C routine could, but it would be relatively pointless. \$\endgroup\$ Jul 21, 2018 at 17:23
  • \$\begingroup\$ I used Wire.write("here very long text goes"). Still the same result. LED is not blinking even just a little bit. But when I remove this line it is visible how it blinks very fast. \$\endgroup\$ Jul 21, 2018 at 17:34
  • \$\begingroup\$ @vicatcu but why do I see it with no data being sent? \$\endgroup\$ Jul 21, 2018 at 17:36
  • \$\begingroup\$ "At most you'll see the LED being slightly dimmer than expected as data is being sent" - yes! This is what I see without any data being sent. But when I add some data even that dimmer light disappears replaced by a constant light. Is it supoosed to be so? \$\endgroup\$ Jul 21, 2018 at 17:39
  • \$\begingroup\$ @vicatcu - the truth is that the poster is "doing it wrong" - and explaining that is the key to a useful answer. This is not something one is going to be able to see by eye, without changing it in very artificial ways (using a slowed bit-bang implementation). The fundamental, key lesson is that many situations require instrumentation, not eyeballs. Fortunately today that instrumentation is dirt cheap. \$\endgroup\$ Jul 21, 2018 at 17:39
0
\$\begingroup\$

You CANNOT drive the SCL at 1 Hz at normal MCU clock rates (16MHz).

Read the TWI setup information in the ATMega328P datasheet, see page 266

Since the TWBR is an 8 bit register the divisor in the bit rate formula is limited (also limited by the prescaler).

\$\endgroup\$
0
\$\begingroup\$

Others have addressed the problem of slowing the I2C transmission speed set by the Arduino bus-master.
Using a LED in an attempt to watch fast digital signals is a poor substitute for an oscilloscope, but we must sometimes use inadequate tools. May I suggest a slight change to your test circuit, to improve chances of seeing something useful....

Our eyes see pulses of light in a dark background much better than we see pulses of darkness in a light background. Near as I can tell from your photo, the LED probe you have constructed is wired as follows. R1 keeps the LED lit, until SCL pulses pull down toward ground, creating momentary darkness:

schematic

simulate this circuit – Schematic created using CircuitLab


The above circuit does work, but might work far better if SCL pulses actually lit up the LED - when no SCL pulses arrive (I2C bus is idle) the LED would then be dark.
The following circuit does exactly that, lighting up only when SCL pulses are active. Furthermore, it will be more likely that I2C devices attached to the bus will work properly:

schematic

simulate this circuit Note that there is no ground connection. The Arduino SCL pin actively pulls down to ground. Current flows from the +5V supply, through the LED, into the Arduino's SCL pin, and inside the chip finds its way to ground. When the I2C bus is idle, Arduino's SCL pin floats to logic high, and no current flows: the LED is dark.
You still may not actually see individual SCL pulses (your eyes blend together pulse rates faster than about twenty-per-second). But you'll have a somewhat better chance of seeing bus activity.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.