|
| 1 | +--- |
| 2 | +title: Communication Protocol - I2C |
| 3 | +description: Learn how to use I2C on Micropython |
| 4 | +author: Pedro Sousa Lima |
| 5 | +--- |
| 6 | + |
| 7 | +#### Introduction |
| 8 | +Inter-Integrated Circuit, or **I2C**, is one of the most widely used serial communication protocols, especially in the Arduino ecosystem. It enables multiple devices to communicate over just two wires, making it both efficient and versatile as you can easily add new modules more easily as the connections all happen across the same bus and standetizes them across manufacturers (and product lines). |
| 9 | + |
| 10 | + |
| 11 | +#### How I2C Works |
| 12 | +I2C communication relies on two wires: |
| 13 | +- **SDA (Serial Data):** Transfers data between devices. |
| 14 | +- **SCL (Serial Clock):** Synchronizes data transmission. |
| 15 | + |
| 16 | +Each device on an I2C bus has a unique address, allowing the controller to communicate directly with a specific device. This capability makes it possible to connect up to 128 devices on the same two wires (128 is the maximum number of different adresses you can have as the adress is a 7 bit value and you can only express 128 unique values using 7 bits). |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | + |
| 21 | +#### Key Features of I2C |
| 22 | +1. **Two-Wire Simplicity:** Reduces hardware complexity. |
| 23 | +2. **Address-Based Communication:** Each device has a unique address. |
| 24 | +3. **Bidirectional Communication:** Enables data transfer in both directions. |
| 25 | + |
| 26 | + |
| 27 | +#### Example: Reading Sensor Data Using I2C |
| 28 | +In this example, we will connect an **LIS3DHTR accelerometer** to an Arduino and read its data via I2C. |
| 29 | + |
| 30 | +**Circuit Diagram:** |
| 31 | + |
| 32 | + |
| 33 | +**Setup Instructions:** |
| 34 | +1. Connect the LIS3DHTR to your board as shown in the circuit diagram. |
| 35 | +2. Install the required `lis3dh` module by running the following command: |
| 36 | + |
| 37 | + ```python |
| 38 | + mip.install("https://raw.githubusercontent.com/tinypico/tinypico-micropython/master/lis3dh%20library/lis3dh.py") |
| 39 | + ``` |
| 40 | + |
| 41 | +3. Copy the following code to your `main.py` file and run it. |
| 42 | + |
| 43 | +**Code:** |
| 44 | +```python |
| 45 | +import lis3dh, time, math |
| 46 | +from machine import Pin, I2C |
| 47 | + |
| 48 | +i2c = I2C(sda=Pin(8), scl=Pin(9)) |
| 49 | +imu = lis3dh.LIS3DH_I2C(i2c, address=0x19) |
| 50 | + |
| 51 | +last_convert_time = 0 |
| 52 | +convert_interval = 100 #ms |
| 53 | +pitch = 0 |
| 54 | +roll = 0 |
| 55 | + |
| 56 | +# Convert acceleration to Pitch and Roll |
| 57 | +def convert_accell_rotation( vec ): |
| 58 | + x_Buff = vec[0] # x |
| 59 | + y_Buff = vec[1] # y |
| 60 | + z_Buff = vec[2] # z |
| 61 | + |
| 62 | + global last_convert_time, convert_interval, roll, pitch |
| 63 | + |
| 64 | + # We only want to re-process the values every 100 ms |
| 65 | + if last_convert_time < time.ticks_ms(): |
| 66 | + last_convert_time = time.ticks_ms() + convert_interval |
| 67 | + |
| 68 | + roll = math.atan2(y_Buff , z_Buff) * 57.3 |
| 69 | + pitch = math.atan2((- x_Buff) , math.sqrt(y_Buff * y_Buff + z_Buff * z_Buff)) * 57.3 |
| 70 | + |
| 71 | + # Return the current values in roll and pitch |
| 72 | + return ( roll, pitch ) |
| 73 | + |
| 74 | +# If we have found the LIS3DH |
| 75 | +if imu.device_check(): |
| 76 | + # Set range of accelerometer (can be RANGE_2_G, RANGE_4_G, RANGE_8_G or RANGE_16_G). |
| 77 | + imu.range = lis3dh.RANGE_2_G |
| 78 | + |
| 79 | + # Loop forever printing values |
| 80 | + while True: |
| 81 | + # Read accelerometer values (in m / s ^ 2). Returns a 3-tuple of x, y, |
| 82 | + # z axis values. Divide them by 9.806 to convert to Gs. |
| 83 | + x, y, z = [value / lis3dh.STANDARD_GRAVITY for value in imu.acceleration] |
| 84 | + print("x = %0.3f G, y = %0.3f G, z = %0.3f G" % (x, y, z)) |
| 85 | + |
| 86 | + # Convert acceleration to Pitch and Roll and print values |
| 87 | + p, r = convert_accell_rotation( imu.acceleration ) |
| 88 | + print("pitch = %0.2f, roll = %0.2f" % (p,r)) |
| 89 | + |
| 90 | + # Small delay to keep things responsive but give time for interrupt processing. |
| 91 | + time.sleep(0.1) |
| 92 | +``` |
| 93 | + |
| 94 | +**Expected Output:** |
| 95 | +In the REPL terminal, you will see accelerometer data displayed every second. For example: |
| 96 | + |
| 97 | + |
| 98 | +``` |
| 99 | +x = 0.001 G, y = -0.002 G, z = 1.000 G |
| 100 | +pitch = -0.12, roll = 0.04 |
| 101 | +``` |
| 102 | + |
| 103 | + |
| 104 | +#### Summary |
| 105 | +I2C is a highly efficient protocol that enables multiple devices to communicate on just two wires. In this example, we demonstrated how to read data from an I2C-connected sensor, opening the door to integrating even more devices into your Arduino projects. |
| 106 | + |
0 commit comments