1# I2C Tools Example
2
3(See the README.md file in the upper level 'examples' directory for more information about examples.)
4
5## Overview
6
7[I2C Tools](https://i2c.wiki.kernel.org/index.php/I2C_Tools) is a simple but very useful tool for developing I2C related applications, which is also famous in Linux platform. This example just implements some of basic features of [I2C Tools](https://i2c.wiki.kernel.org/index.php/I2C_Tools) based on [esp32 console component](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/console.html). As follows, this example supports five command-line tools:
8
91. `i2cconfig`: It will configure the I2C bus with specific GPIO number, port number and frequency.
102. `i2cdetect`: It will scan an I2C bus for devices and output a table with the list of detected devices on the bus.
113. `i2cget`: It will read registers visible through the I2C bus.
124. `i2cset`: It will set registers visible through the I2C bus.
135. `i2cdump`: It will examine registers visible through the I2C bus.
14
15If you have some trouble in developing I2C related applications, or just want to test some functions of one I2C device, you can play with this example first.
16
17## How to use example
18
19### Hardware Required
20
21To run this example, you should have any ESP32, ESP32-S and ESP32-C based development board. For test purpose, you should have a kind of device with I2C interface as well. Here we will take the CCS811 sensor as an example to show how to test the function of this sensor without writing any code (just use the command-line tools supported by this example). For more information about CCS811, you can consult the [online datasheet](http://ams.com/ccs811).
22
23#### Pin Assignment:
24
25**Note:** The following pin assignments are used by default, you can change them with `i2cconfig` command at any time.
26
27|                     | SDA    | SCL    | GND  | Other | VCC  |
28| ------------------- | ------ | ------ | ---- | ----- | ---- |
29| ESP32 I2C Master    | GPIO18 | GPIO19 | GND  | GND   | 3.3V |
30| ESP32-S2 I2C Master | GPIO18 | GPIO19 | GND  | GND   | 3.3V |
31| ESP32-S3 I2C Master | GPIO1  | GPIO2  | GND  | GND   | 3.3V |
32| ESP32-C3 I2C Master | GPIO5  | GPIO6  | GND  | GND   | 3.3V |
33| Sensor              | SDA    | SCL    | GND  | WAK   | VCC  |
34
35**Note: ** There’s no need to add an external pull-up resistors for SDA/SCL pin, because the driver will enable the internal pull-up resistors itself.
36
37### Configure the project
38
39Open the project configuration menu (`idf.py menuconfig`). Then go into `Example Configuration` menu.
40
41- You can choose whether or not to save command history into flash in `Store command history in flash` option.
42
43### Build and Flash
44
45Run `idf.py -p PORT flash monitor` to build and flash the project..
46
47(To exit the serial monitor, type ``Ctrl-]``.)
48
49See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
50
51## Example Output
52
53### Check all supported commands and their usages
54
55```bash
56 ==============================================================
57 |       Steps to Use i2c-tools on ESP32                      |
58 |                                                            |
59 |  1. Try 'help', check all supported commands               |
60 |  2. Try 'i2cconfig' to configure your I2C bus              |
61 |  3. Try 'i2cdetect' to scan devices on the bus             |
62 |  4. Try 'i2cget' to get the content of specific register   |
63 |  5. Try 'i2cset' to set the value of specific register     |
64 |  6. Try 'i2cdump' to dump all the register (Experiment)    |
65 |                                                            |
66 ==============================================================
67
68i2c-tools> help
69help
70  Print the list of registered commands
71
72i2cconfig  [--port=<0|1>] [--freq=<Hz>] --sda=<gpio> --scl=<gpio>
73  Config I2C bus
74  --port=<0|1>  Set the I2C bus port number
75   --freq=<Hz>  Set the frequency(Hz) of I2C bus
76  --sda=<gpio>  Set the gpio for I2C SDA
77  --scl=<gpio>  Set the gpio for I2C SCL
78
79i2cdetect
80  Scan I2C bus for devices
81
82i2cget  -c <chip_addr> [-r <register_addr>] [-l <length>]
83  Read registers visible through the I2C bus
84  -c, --chip=<chip_addr>  Specify the address of the chip on that bus
85  -r, --register=<register_addr>  Specify the address on that chip to read from
86  -l, --length=<length>  Specify the length to read from that data address
87
88i2cset  -c <chip_addr> [-r <register_addr>] [<data>]...
89  Set registers visible through the I2C bus
90  -c, --chip=<chip_addr>  Specify the address of the chip on that bus
91  -r, --register=<register_addr>  Specify the address on that chip to read from
92        <data>  Specify the data to write to that data address
93
94i2cdump  -c <chip_addr> [-s <size>]
95  Examine registers visible through the I2C bus
96  -c, --chip=<chip_addr>  Specify the address of the chip on that bus
97  -s, --size=<size>  Specify the size of each read
98
99free
100  Get the current size of free heap memory
101
102heap
103  Get minimum size of free heap memory that was available during program execu
104  tion
105
106version
107  Get version of chip and SDK
108
109restart
110  Software reset of the chip
111
112deep_sleep  [-t <t>] [--io=<n>] [--io_level=<0|1>]
113  Enter deep sleep mode. Two wakeup modes are supported: timer and GPIO. If no
114  wakeup option is specified, will sleep indefinitely.
115  -t, --time=<t>  Wake up time, ms
116      --io=<n>  If specified, wakeup using GPIO with given number
117  --io_level=<0|1>  GPIO level to trigger wakeup
118
119light_sleep  [-t <t>] [--io=<n>]... [--io_level=<0|1>]...
120  Enter light sleep mode. Two wakeup modes are supported: timer and GPIO. Mult
121  iple GPIO pins can be specified using pairs of 'io' and 'io_level' arguments
122  . Will also wake up on UART input.
123  -t, --time=<t>  Wake up time, ms
124      --io=<n>  If specified, wakeup using GPIO with given number
125  --io_level=<0|1>  GPIO level to trigger wakeup
126
127tasks
128  Get information about running tasks
129```
130
131### Configure the I2C bus
132
133```bash
134esp32> i2cconfig --port=0 --sda=18 --scl=19 --freq=100000
135```
136
137* `--port` option to specify the port of I2C, here we choose port 0 for test.
138* `--sda` and `--scl` options to specify the gpio number used by I2C bus, here we choose GPIO18 as the SDA and GPIO19 as the SCL.
139* `--freq` option to specify the frequency of I2C bus, here we set to 100KHz.
140
141### Check the I2C address (7 bits) on the I2C bus
142
143```bash
144esp32> i2cdetect
145     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
14600: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
14710: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
14820: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
14930: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
15040: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
15150: -- -- -- -- -- -- -- -- -- -- -- 5b -- -- -- --
15260: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
15370: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
154```
155
156* Here we found the address of CCS811 is 0x5b.
157
158### Get the value of status register
159
160```bash
161esp32> i2cget -c 0x5b -r 0x00 -l 1
1620x10
163```
164
165* `-c` option to specify the address of I2C device (acquired from `i2cdetect` command).
166* `-r` option to specify the register address you want to inspect.
167* `-l` option to specify the length of the content.
168* Here the returned value 0x10 means that the sensor is just in the boot mode and is ready to go into application mode. For more information about CCS811 you should consult the [official website](http://ams.com/ccs811).
169
170### Change the working mode
171
172```bash
173esp32> i2cset -c 0x5b -r 0xF4
174I (734717) cmd_i2ctools: Write OK
175esp32> i2cset -c 0x5b -r 0x01 0x10
176I (1072047) cmd_i2ctools: Write OK
177esp32> i2cget -c 0x5b -r 0x00 -l 1
1780x98
179```
180
181* Here we change the mode from boot to application and set a proper measure mode (by writing 0x10 to register 0x01)
182* Now the status value of the sensor is 0x98, which means a valid data is ready to read
183
184### Read the sensor data
185
186```bash
187esp32> i2cget -c 0x5b -r 0x02 -l 8
1880x01 0xb0 0x00 0x04 0x98 0x00 0x19 0x8f
189```
190
191* The register 0x02 will output 8 bytes result, mainly including value of eCO~2~、TVOC and there raw value. So the value of eCO~2~ is 0x01b0 ppm and value of TVOC is 0x04 ppb.
192
193## Troubleshooting
194
195* I don’t find any available address when running `i2cdetect` command.
196  * Make sure your wiring connection is right.
197  * Some sensor will have a “wake up” pin, via which user can put the sensor into a sleep mode. So make sure your sensor in **not** in the sleep state.
198  * Reset you I2C device, and then run `i2cdetect` again.
199* I can’t get the right content when running `i2cdump` command.
200  * Currently the `i2cdump` only support those who have the same content length of registers inside the I2C device. For example, if a device have three register addresses, and the content length at these address are 1 byte, 2 bytes and 4 bytes. In this case you should not expect this command to dump the register correctly.
201
202
203(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.)
204
205