#include <stdio.h>
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_err.h"
#include "driver/i2c_master.h"
#include "driver/gpio.h"
// Пины I2C
#define I2C_MASTER_SCL_IO GPIO_NUM_22
#define I2C_MASTER_SDA_IO GPIO_NUM_21
#define I2C_MASTER_FREQ_HZ 100000
#define I2C_TIMEOUT_MS 100
// Кнопка BOOT
#define BOOT_BUTTON_GPIO GPIO_NUM_0
// ------------------------------------------------------------
// Имитация функции из ESP-IoT-Solution: i2c_bus_scan()
// ------------------------------------------------------------
int simulate_i2c_bus_scan(i2c_master_bus_handle_t bus_handle, uint8_t *addresses, int max_count)
{
if (!addresses || max_count <= 0) return 0;
int count = 0;
for (uint8_t addr = 1; addr < 127; addr++) {
esp_err_t ret = i2c_master_probe(bus_handle, addr, I2C_TIMEOUT_MS);
if (ret == ESP_OK) {
if (count < max_count) {
addresses[count] = addr;
count++;
}
}
}
return count;
}
// ------------------------------------------------------------
// Вывод результатов в формате таблицы (как в задании)
// ------------------------------------------------------------
void print_scan_results(const uint8_t *addresses, int count)
{
printf("Scanning the bus...\r\n\r\n");
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
for (int i = 0; i < 128; i += 16) {
printf("%02x: ", i);
for (int j = 0; j < 16; j++) {
uint8_t target = i + j;
bool found = false;
for (int k = 0; k < count; k++) {
if (addresses[k] == target) {
printf("%02x ", target);
found = true;
break;
}
}
if (!found) {
printf("-- ");
}
}
printf("\r\n");
}
printf("\r\n");
}
// ------------------------------------------------------------
// Основная функция
// ------------------------------------------------------------
void app_main(void)
{
// Настройка кнопки BOOT (GPIO0)
gpio_config_t btn_cfg = {
.pin_bit_mask = (1ULL << BOOT_BUTTON_GPIO),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&btn_cfg);
// Инициализация I2C
i2c_master_bus_config_t i2c_mst_cfg = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = I2C_NUM_0,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_io_num = I2C_MASTER_SDA_IO,
.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_mst_cfg, &bus_handle));
printf("I2C Scanner (ESP-IoT-Solution style) ready!\n");
printf("Press BOOT button (GPIO0) to scan...\n");
uint8_t detected_addresses[127];
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_bus_scan()
int num_devices = simulate_i2c_bus_scan(bus_handle, detected_addresses, 127);
print_scan_results(detected_addresses, num_devices);
was_pressed = true;
}
}
} else {
was_pressed = false;
}
vTaskDelay(pdMS_TO_TICKS(20));
}
// Очистка (недостижима)
i2c_del_master_bus(bus_handle);
}