Reset I2C
-
- Posts: 59
- Joined: Thu Jan 19, 2017 5:17 pm
Reset I2C
I'm working on a project using MCP23017's which are port expanders using the i2c protocol. Occasionally, the chips start returning the wrong readings. I use relays in my design, which I imagine is causing the problem. I hooked it up to a login analizer and got the following result.
Right now, when I detect a problem, I reset the esp32 with esp_restart(). This always fixes the issue. Is there a way to correct this without a reset? Is there some way to reset the i2c bus?
Thanks!
Right now, when I detect a problem, I reset the esp32 with esp_restart(). This always fixes the issue. Is there a way to correct this without a reset? Is there some way to reset the i2c bus?
Thanks!
Re: Reset I2C
Howdy there @gregstewart90,
Without more context, the I2C trace doesn't look "wrong".
What you seem to be showing is a clock rate at the top signal and a data trace at the bottom signal. It also looks like you are using the Saleae software for examining the trace. It has an I2C mode where you can ask it to decode the protocol into I2C values. Are these parsing correctly. My arithmetic may be off, but I think I'm seeing 8 clock pulses before repetition.
Without more context, the I2C trace doesn't look "wrong".
What you seem to be showing is a clock rate at the top signal and a data trace at the bottom signal. It also looks like you are using the Saleae software for examining the trace. It has an I2C mode where you can ask it to decode the protocol into I2C values. Are these parsing correctly. My arithmetic may be off, but I think I'm seeing 8 clock pulses before repetition.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
-
- Posts: 59
- Joined: Thu Jan 19, 2017 5:17 pm
Re: Reset I2C
That top is the clock. It is unable to parse the signal. The small segment I showed in the first picture repeats continuously. When it works normally, I only see it poll the mcp's a few times a second.
Re: Reset I2C
I think several people have noticed such problems but so far I could not find any solution rather than just reset the ESP32.
Also see:
- https://esp32.com/viewtopic.php?f=2&t=2 ... i2c#p10265
- https://github.com/espressif/esp-idf/issues/680
- https://github.com/espressif/arduino-esp32/issues/349
Maybe someone at espressif can shed some light on what is happening here.
Also see:
- https://esp32.com/viewtopic.php?f=2&t=2 ... i2c#p10265
- https://github.com/espressif/esp-idf/issues/680
- https://github.com/espressif/arduino-esp32/issues/349
Maybe someone at espressif can shed some light on what is happening here.
Re: Reset I2C
okgregstewart90 wrote:That top is the clock. It is unable to parse the signal. The small segment I showed in the first picture repeats continuously. When it works normally, I only see it poll the mcp's a few times a second.
we see the clk
we see the data
we see no start condition
we see no stop condition
can you post please the CS ( /CE or RST ) pin too?
or how you interference you the device you want to poll?
thank you
best wishes
rudi
Last edited by rudi ;-) on Mon Jun 19, 2017 2:12 pm, edited 2 times in total.
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
-
- Posts: 59
- Joined: Thu Jan 19, 2017 5:17 pm
Re: Reset I2C
With this being i2c, I only have the SCL and SDA lines. What is the CS ( /CE or RST ) pin?
Re: Reset I2C
gregstewart90 wrote:With this being i2c, I only have the SCL and SDA lines. What is the CS ( /CE or RST ) pin?
if you speak from MCP
there is a CE to select the device
or my second question was:
means then if you talk by address example.or how you interference you the device you want to poll?
how you set the 3 pins of MCP
A0
A1
A2
btw:
CE = Chip enable
CS = Chip select
RST = Reset
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
Re: Reset I2C
Hi, im also trying to make mcp23017 to work and those are my findings. During reading there are clock speed drops about 33%. In my test case from 100kHz to about 65kHz and from 200kHz to about 129kHz.
I have to say i dont have any issues with mpu6050 on the same i2c line.-
- Posts: 59
- Joined: Thu Jan 19, 2017 5:17 pm
Re: Reset I2C
I haven't checked for the slowing clock speed, but I got mine to work with the following code. It's nothing perfect, but I don't miss anything. Occasionally I still get stuck on the i2c line, but I just monitor that and reset as necessary.
Code: Select all
void initI2C() {
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = I2C_SDA;
conf.scl_io_num = I2C_SCL;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = 100000;
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_1, &conf));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, 0, 0, 0));
}
/**
* @brief Reads a register of a specified MCP32017
*/
void mcp23017_local_read(uint8_t MCP23017_ADDRESS, uint8_t* data_h){
i2c_cmd_handler = i2c_cmd_link_create();
i2c_master_start(i2c_cmd_handler);
i2c_master_write_byte(i2c_cmd_handler, MCP23017_ADDRESS << 1 | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(i2c_cmd_handler, data_h, NACK_VAL);
i2c_master_stop(i2c_cmd_handler);
int ret = i2c_master_cmd_begin(I2C_NUM_1, i2c_cmd_handler, 100 / portTICK_RATE_MS);
// printf("ret:%d-%d\n", ret, ESP_ERR_TIMEOUT);
i2c_cmd_link_delete(i2c_cmd_handler);
if (ret != 0) {
send_dump_write();
printf("ERROR\n");
}
}
/**
* @brief Write a value to a register of a specified MCP32017
*/
void mcp23017_local_write(uint8_t MCP23017_ADDRESS, uint8_t command){
vTaskDelay(30 / portTICK_RATE_MS);
i2c_cmd_handler = i2c_cmd_link_create();
i2c_master_start(i2c_cmd_handler);
i2c_master_write_byte(i2c_cmd_handler, MCP23017_ADDRESS << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(i2c_cmd_handler, command, ACK_CHECK_EN);// Access IODIRB
i2c_master_stop(i2c_cmd_handler);
int ret = i2c_master_cmd_begin(I2C_NUM_1, i2c_cmd_handler, 100 / portTICK_RATE_MS);
i2c_cmd_link_delete(i2c_cmd_handler);
if (ret == ESP_FAIL) {
printf("ERROR\n");
}
}
/**
* @brief Writes two values to a register of a specified MCP32017
*/
void mcp23017_duel_write(uint8_t MCP23017_ADDRESS, uint8_t command, uint8_t command2){
i2c_cmd_handler = i2c_cmd_link_create();
i2c_master_start(i2c_cmd_handler);
i2c_master_write_byte(i2c_cmd_handler, MCP23017_ADDRESS << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(i2c_cmd_handler, command, ACK_CHECK_EN);// Access IODIRB
i2c_master_write_byte(i2c_cmd_handler, command2, ACK_CHECK_EN);// Write Register
i2c_master_stop(i2c_cmd_handler);
int ret = i2c_master_cmd_begin(I2C_NUM_1, i2c_cmd_handler, 100 / portTICK_RATE_MS);
i2c_cmd_link_delete(i2c_cmd_handler);
if (ret == ESP_FAIL) {
printf("ERROR\n");
}
}
/**
* @brief Reads the value of the register of the specified MCP23017
*/
uint8_t mcp23017_read(uint8_t MCP23017_ADDRESS, uint8_t command){
uint8_t data_h;
mcp23017_local_write(MCP23017_ADDRESS, command);
vTaskDelay(30 / portTICK_RATE_MS);
mcp23017_local_read(MCP23017_ADDRESS, &data_h);
vTaskDelay(30 / portTICK_RATE_MS);
return data_h;
}
Who is online
Users browsing this forum: cdollar and 97 guests