#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_err.h"
#include "driver/i2c_master.h"
#include "driver/gpio.h"
#define I2C_TIMEOUT_VALUE_MS (100)
#define BOOT_BUTTON_GPIO GPIO_NUM_0
// Функция сканирования шины
void i2c_scan(i2c_master_bus_handle_t bus_handle)
{
printf("\n Scanning I2C bus...\n");
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n");
for (int i = 0; i < 128; i += 16) {
printf("%02x: ", i);
for (int j = 0; j < 16; j++) {
uint8_t addr = i + j;
esp_err_t ret = i2c_master_probe(bus_handle, addr, I2C_TIMEOUT_VALUE_MS);
if (ret == ESP_OK) {
printf("%02x ", addr);
} else if (ret == ESP_ERR_TIMEOUT) {
printf("UU ");
} else {
printf("-- ");
}
}
printf("\n");
}
printf("\n Scan complete.\n\n");
}
void app_main(void)
{
// Настройка кнопки BOOT (GPIO0)
gpio_config_t btn_config = {
.pin_bit_mask = (1ULL << BOOT_BUTTON_GPIO),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE, // важна! без неё GPIO0 "плавает"
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&btn_config);
// Инициализация I²C
i2c_master_bus_config_t i2c_cfg = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = I2C_NUM_0,
.scl_io_num = GPIO_NUM_22,
.sda_io_num = GPIO_NUM_21,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = false, // pull-up на модуле есть
};
i2c_master_bus_handle_t bus_handle;
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_cfg, &bus_handle));
printf("I2C Scanner ready!\n");
printf("Press BOOT button (GPIO0) to scan...\n");
bool was_pressed = false;
while (1) {
int btn_state = gpio_get_level(BOOT_BUTTON_GPIO);
if (btn_state == 0) { // кнопка нажата (активный низкий)
if (!was_pressed) {
// Антидребезг
vTaskDelay(pdMS_TO_TICKS(50));
if (gpio_get_level(BOOT_BUTTON_GPIO) == 0) {
i2c_scan(bus_handle);
was_pressed = true;
}
}
} else {
was_pressed = false; // сброс при отпускании
}
vTaskDelay(pdMS_TO_TICKS(20)); // опрос кнопки каждые 20 мс
}
// Очистка (недостижима)
i2c_del_master_bus(bus_handle);
}