Reading the I2C Bus on an Oscilloscope - LEKULE

Breaking

23 Sept 2016

Reading the I2C Bus on an Oscilloscope

Oscilloscopes offer a variety of tools to help diagnose troublesome circuits. In this tutorial, we will use the oscilloscope to read an I²C serial bus.

Getting a Scope

For more information on how to obtain an oscilloscope, please refer to Part 1.

Project Overview

I will use the Tektronix Multi-Domain Oscilloscope 3104 to decode I²C data and determine the I²C address for a device by sequentially polling all addresses and looking for an acknowledge (ACK) signal. Any I²C device will do. I received an evaluation kit for the Infineon 3D Hall-Effect Sensor, and I will use this as my I²C device.

ProductCost (and Product Link)Other Information
Infineon 3D Magnetic Sensor 2 Go Kit$28Kit Manual | Sensor Manual | Sensor Product Brief
4 Position Header (0.100")$1Datasheet
Arduino Uno R3$15Product Information
Bi-Directional Logic Level Converter$3Datasheet
Jumper Wires$3
As mentioned above, any I²C-compatible sensor or display is acceptable here. You don't have to use the Magnetic Sensor 2 Go Kit.

Setting Up the Circuit

The Arduino board that I used operates with 5V logic. The 3D2GO evaluation kit is supplied by 3.3 V. That means a Bi-Directional Logic Level Converter (BD-LLC) must be inserted between the data lines of the Arduino and the evaluation kit.
To insert your BD-LLC between the Arduino and your I²C device, make the following connections:
  1. GND from the Arduino to GND on the BD-LLC
  2. GND from the BD-LLC to GND on the 3D2GO
  3. 3.3V from the Arduino to Low Voltage (LV) on the BD-LLC
  4. LV on the BD-LLC to 3.3V on the 3D2GO
  5. Arduino 5V to High Voltage (HV) on the BD-LLC
  6. Arduino SDA to HV1
  7. Arduino SCL to HV2
  8. BD-LLC LV1 to 3D2GO SDA
  9. BD-LLC LV2 to 3D2GO SCL



Setting up the Oscilloscope

Next, you'll need to set up your oscilloscope. To do that, follow these steps:
  1. Turn on the oscilloscope and wait until it completes its self-tests.
  2. Plug probes into Channel 1 and Channel 2.
  3. Connect the probe's ground clip to a ground point in the circuit (use a jumper wire if necessary).
  4. Connect Probe 1 to SDA and Probe 2 to SCL (use a jumper wire if necessary).
Now you can open the Arduino IDE and upload the following code to your board. This is an I²C scanner that will scan all addresses for devices and look for ACK responses.

                    //  I2C Scanner from Arduino.cc
//  Attribution to Krodal, Nick Gammon, Anonymous
 
#include 
 
void setup()
{
  Wire.begin();
 
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}
 
void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address <= 127; address++)
  {
    // The i2c_scanner uses the return value of
    // Wire.endTransmission to see if
    // a device acknowledged the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}
                  

 

Now, every 5 seconds, the Arduino will poll I²C addresses 1-127.  If a device exists at the address polled, it will send an acknowledge signal to the Arduino by pulling the SDA line low after the address byte has been transmitted.
We can now move on to using the oscilloscope to decode the I²C bus.
Use the following steps for a Tektronix MDO3000 or MDO4000 series oscilloscope, with generic instructions for any oscilloscope in parentheses.
  1. Press the Channel 1 button (turn on oscilloscope channel 1)
    1. Press "Label" (label your inputs if you are able to)
    2. Use Multipurpose b to scroll down to "DATA" (label channel 1 "Data")
    3. Select "Insert Preset Label"
    4. Use the Vertical Scale Knob below the Channel 1 button to set 2 volts per division (decrease the height of the signal so it fills less than half of your screen)
    5. Use the knob above the Channel 1 button to move the signal to the upper-middle part of the screen
  2. Press the "Down" arrow to move to "channel 2" (turn on oscilloscope channel 2)
    1. Use Multipurpose b to scroll down to "CLK" (label channel 2 "Clock")
    2. Select "Insert Preset Label"
  3. Push the Menu Off button
  4. Press the Channel 2 button
    1. Use the knob below the Channel 2 button to set 2 volts per division (decrease the height of the signal so it fills less than half your screen)
    2. Use the knob above the Channel 2 button to move the signal into the lower middle part of the screen (this separates the trace for the clock signal from the trace for the data signal)
  5. Press the B1 button (the scope's bus functionality allows you to interpret and display serial or parallel data; in this case, we are dealing with I²C data)
    1. Press "Bus B1" and use Multipurpose a to select "I2C" (tell the oscilloscope which type of data to expect)
    2. Select "Define Inputs"
      1. Use Multipurpose a to select "SCL" on Channel 2 (assign CLK channel to be SCL)
      2. Use Multipurpose b to select "SDA" on Channel 1 (assign DATA channel to be SDA)
      3. Set "Thresholds" to "1 V" on both SDA and SCL using Multipurpose a and Multipurpose b
      4. Set "Include R/W In Address" to "yes"
      5. Set "B1 Label" to "I2C" (just to keep track of things)
      6. Set "Bus Display" to "Bus and Waveform"
      7. Set "Hex"
  6. Press the Trigger Menu button
    1. Select "Bus"
    2. Select "Source B1-I2C"
    3. Select "Trigger on Start"
  7. Press Menu Off
  8. Use the Scale rotary knob to change the time-scale to 1.00 ms
  9. Press Single to capture a single waveform
  10. Use the Wave Inspector rotary knobs to Zoom into any portion of the I²C transaction that you want to inspect more carefully.  In my case, an ACK was received after address 0x5E, because that is the address of the magnetic sensor chip.



The following video walks you through the steps required to decode an I²C bus.


How to Save Data from the Oscilloscope to Your Computer

Decoded data is stored in an event table. You can save it to a USB drive or to your computer.



Since plugging in a USB drive is a trivial example, we'll do it the hard way by remotely controlling the scope.  The steps below are specific to Microsoft Windows and the Tektronix MDO3000 and MDO4000 series of scopes.
On a side note, what we are about to do is a potential data security risk. Talk to your IT department before doing this at work.
My computer is at 192.168.0.18, and the oscilloscope is at 192.168.0.40. Make appropriate adjustments to your commands.
  1. Run CMD.EXE as an administrator and type the following to create a share:
    1. mkdir C:\Oscilloscope
    2. NET SHARE Scope=C:\Oscilloscope /remark:"TEK3104 Data" /grant:domain\user,FULL //     This creates a share named "Scope" on your main hard drive. You can change it to any location you like. Be certain to change domain\user to the name of the domain the computer is connected to, or the name of the PC followed by the username that you used to log on to Windows.
    3. ipconfig //     Note the Local Area Connection IPv4 Address. In my example, it is 192.168.0.18.
  2. Next, while still in CMD.EXE, use PuTTY or telnet to connect to the scope:
    1. TELNET -O 192.168.0.40 4000 //     Change 192.168.0.40 to the IP of your scope, displayed on the main screen at startup.
  3. You are now connected to the oscilloscope at its IP address on the default port 4000. Type the following:
    1. !d //     This clears the device.
    2. files:mount:list? //     This will show all mounted drives.
    3. files:mount:drive "H:;192.168.0.18;Scope;user;pass;" //     This creates a persistent drive on the machine at 192.168.0.18.
    4. files:mount:list?  //     This should cause a new drive to appear.
    5. files:mkdir "H:/NewArticles"  //     This makes a directory called "New Articles" on the computer.
    6. files:cwd "H:/NewArticles"    //     This changes focus to that directory.
    7. save:eventtable:B1 "eventtable.csv"  //     This (finally) saves the data to the computer.




 

Conclusion

In under 15 minutes, we decoded an I²C bus and, from across the room, saved the data to a computer for analysis.
And now that the shared folder is established, future work can be accomplished in just a few minutes. This automatic decoding process is much more effective than simply probing the signals and trying to manually interpret logic levels.

I used the scope and the procedures shown in this article to decode I²C bus data for several different modes of the 3D Magnetic Sensor 2 Go and determine which commands correspond to which power modes.

No comments: