I2C Programming & Scope Detection


Recently I have been working with various sensors such as a magnetometer, gyroscope and accelerometer for use in navigational systems (Ref.1). All these sensors are accessed using the I2C protocol. Over the past several years I have worked with various HF synthesizers that were also programmed via I2C. I used a Tektronix TDS210 digital scope to monitor the SDA/SCL programming bus. This time I used my newer Picoscope 3205D which has I2C serial decoding which makes monitoring particularly easy.

UM10204 I2C Bus Specification

Philips Semiconductor (now NXP) developed the Inter-Integrated Circuit 2 wire serial bus to interconnect ICs in 1982. Bus speed was 100Kbps. Since then there have been many improvements and increased bus speeds. The latest specification is UM10204 (Ref.2). Figures 1-5 summarize the important characteristics of the specification. These can be seen in detail with the scope captures.

Fig.1 Data & Clock Relationship
Fig.2 Start & Stop Conditions
Fig.3 Data Transfer to Slave Address
Fig.4 Master to Slave 7bit address
Fig.5 Master Reads a Slave

I2C Connection

In order to experiment with the HMC5883L magnetometer, I used the RaspberryPi3B with the Pi-Top. The GPIO bus is extended to a protoboard which makes monitoring by scope leads very easy. Figure 6 shows the setup and Figure 7 shows the wiring. SDA is connected to Channel A and SCL is connected to Channel B. Since the I2C data is aperiodic, single shot trigger mode is used. Scope settings are:
ChA/ChB: +/- 5V DC Coupling
Time Base = 100usec/div (Zoom afterwards)
Trigger = Single Shot Falling Edge (Fig.2 Trigger on SCL Start)

Fig.6 I2C Connection HMC5883L to RaspberryPi GPIO & Picoscope 3205D
Fig.7 Picoscope 3205 Probe Wiring

Scope I2C Capture

To test the setup I ran a Python program as discussed in my previous blogpost (Ref.1) using the Thonny IDE. The following I2C statements are from smbus for Python:
bus.write_byte_data(0x1E, 0x00, 0x60)
bus.write_byte_data(0x1E, 0x02, 0x00)
The first statement writes to Address $1E (HMC5883L) and sends two bytes of data $00, then $60.
The second statement writes to Address $1E (HMC5883L) and sends two bytes of data $02, then $00.

Fig.8 I2C Packets Recorded from Program Statements
Fig.9 Picoscope I2C Decoding of SDA & SCL
Fig.10 Expanded View Picoscope I2C Decoding of SDA & SCL
Fig.11 I2C Serial Decode

Deconstructing the packet we have the following details. Both SDA & SCL are 3.3VDC “High” on idle. The “Start” of the packet happens when the SDA goes low while the SCL is “High” (Figure 2 & 10). The next 7 SCL clock pulses read MSB first: 0 0 1 1 1 1 0 = 7bit Slave Address = $1E (Pico Orange). Then there is a data direction bit (R/Winv) which is 0 = Write (Pico Green). Following this is a 0 = ACK from Slave (Pico Yellow). Then we have 8 SCL clock pulses and 8 data bits = 0 0 0 0 0 0 0 0 = $00 (Pico Blue). Next a 0 = ACK from Slave (Pico Yellow) and another data packet = 0 1 1 0 0 0 0 0 = $60 followed by 0 = ACK and a “Stop Pulse”. In an exactly similar fashion the next packet from Master to Slave is sent with data = $02 & $00. Figure 11 shows an expanded view of the packet, the SCL clock rate is 10usecs = 100Kbps.

Fig.12 YouTube Video I2C Programming & Scope Detection

Please send your comments, questions and suggestions to:

YouTube Channel
YouTube Channel


#1. – “Magnetic Navigation”, Blog Post

#2. – “UM10204 I2C Bus Specification”, Rev.6 April 2014, NXP Semi

#3. – “HMC5883L Data Sheet”, Rev. C 2012, Farnell

By Jeremy Clark

Jeremy Clark is a Senior Telecommunications Engineer and Advanced Amateur Radio Operator VE3PKC. He is the author of E-Books on Telecommunications, Navigation & Electronics.