diff --git a/CMakeLists.txt b/CMakeLists.txt index 39e41a5..8ad49cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,4 +5,9 @@ cmake_minimum_required(VERSION 3.16) set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/components") include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(bme680_esp8266) +project(bme680_esp8266 C) + + +# Force the app to link as C (prevents pulling libstdc++) +idf_build_get_property(APP_TARGET EXECUTABLE) # provided by IDF's CMake +set_target_properties(${APP_TARGET} PROPERTIES LINKER_LANGUAGE C) diff --git a/Makefile b/Makefile index d19ebda..1b2ce4f 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,14 @@ +.DEFAULT_GOAL := build + clean: idf.py fullclean rm -rf ./main/build rm -rf ./components/bme68x/build rm -rf ./build +build: +# idf.py reconfigure +# idf.py defconfig + idf.py build diff --git a/main/bme680_esp8266.c b/main/bme680_esp8266.c index 1348a5a..12724f4 100644 --- a/main/bme680_esp8266.c +++ b/main/bme680_esp8266.c @@ -1,126 +1,145 @@ -// #include - -// void app_main(void) -// { - -// } - - #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/i2c.h" -#include "bme680.h" +#include "bme68x.h" +/* ----- I2C pins (ESP-01S: SDA=GPIO0, SCL=GPIO2) ----- */ #define I2C_PORT I2C_NUM_0 -#define I2C_SDA_PIN 0 // GPIO0 -#define I2C_SCL_PIN 2 // GPIO2 -#define I2C_FREQ_HZ 100000 -#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // 0x76 (SDO=GND) -// #define BME680_ADDR BME680_I2C_ADDR_SECONDARY // 0x77 (SDO=VCC) +#define I2C_SDA_PIN 0 +#define I2C_SCL_PIN 2 +#define I2C_TIMEOUT_MS 1000 -// --- I2C helpers (ESP-IDF style) --- -static int8_t i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len) { - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, (dev_id << 1) | I2C_MASTER_WRITE, true); - i2c_master_write_byte(cmd, reg_addr, true); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, (dev_id << 1) | I2C_MASTER_READ, true); - if (len > 1) { - i2c_master_read(cmd, data, len - 1, I2C_MASTER_ACK); - } - i2c_master_read_byte(cmd, data + len - 1, I2C_MASTER_NACK); - i2c_master_stop(cmd); - esp_err_t ret = i2c_master_cmd_begin(I2C_PORT, cmd, pdMS_TO_TICKS(1000)); - i2c_cmd_link_delete(cmd); - return (ret == ESP_OK) ? BME680_OK : BME680_E_COM_FAIL; -} +/* BME68x address: SDO=GND -> LOW(0x76), SDO=VCC -> HIGH(0x77) */ +#define BME68X_ADDR BME68X_I2C_ADDR_LOW -static int8_t i2c_write(uint8_t dev_id, uint8_t reg_addr, const uint8_t *data, uint16_t len) { - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, (dev_id << 1) | I2C_MASTER_WRITE, true); - i2c_master_write_byte(cmd, reg_addr, true); - i2c_master_write(cmd, (uint8_t*)data, len, true); - i2c_master_stop(cmd); - esp_err_t ret = i2c_master_cmd_begin(I2C_PORT, cmd, pdMS_TO_TICKS(1000)); - i2c_cmd_link_delete(cmd); - return (ret == ESP_OK) ? BME680_OK : BME680_E_COM_FAIL; -} - -static void delay_ms(uint32_t period_ms) { vTaskDelay(pdMS_TO_TICKS(period_ms)); } - -static void i2c_init(void) { +/* --------- ESP8266 I2C init (note: clk_stretch_tick field) --------- */ +static void i2c_init(void) +{ i2c_config_t conf = { .mode = I2C_MODE_MASTER, .sda_io_num = I2C_SDA_PIN, .scl_io_num = I2C_SCL_PIN, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, - .master.clk_speed = I2C_FREQ_HZ, + .clk_stretch_tick = 300, // reasonable default on ESP8266 }; i2c_param_config(I2C_PORT, &conf); - i2c_driver_install(I2C_PORT, conf.mode, 0, 0, 0); + i2c_driver_install(I2C_PORT, conf.mode); // ESP8266 signature: (port, mode) } -void app_main(void) { +/* ------------- BME68x I2C read/write helpers ------------- */ +static int8_t bme68x_i2c_read(uint8_t reg, uint8_t *data, uint32_t len, void *intf_ptr) +{ + uint8_t addr = *(uint8_t *)intf_ptr; // 7-bit address + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg, true); + + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_READ, true); + if (len > 1) i2c_master_read(cmd, data, len - 1, I2C_MASTER_ACK); + i2c_master_read_byte(cmd, data + len - 1, I2C_MASTER_NACK); + i2c_master_stop(cmd); + + esp_err_t ret = i2c_master_cmd_begin(I2C_PORT, cmd, I2C_TIMEOUT_MS / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + return (ret == ESP_OK) ? BME68X_OK : BME68X_E_COM_FAIL; +} + +static int8_t bme68x_i2c_write(uint8_t reg, const uint8_t *data, uint32_t len, void *intf_ptr) +{ + uint8_t addr = *(uint8_t *)intf_ptr; + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg, true); + i2c_master_write(cmd, (uint8_t*)data, len, true); + i2c_master_stop(cmd); + + esp_err_t ret = i2c_master_cmd_begin(I2C_PORT, cmd, I2C_TIMEOUT_MS / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + return (ret == ESP_OK) ? BME68X_OK : BME68X_E_COM_FAIL; +} + +static void bme68x_delay_us(uint32_t period_us, void *intf_ptr) +{ + (void)intf_ptr; + /* Delay granularity is ms on FreeRTOS; round up */ + vTaskDelay((period_us + 999) / 1000 / portTICK_PERIOD_MS); +} + +/* ----------------------- App ----------------------- */ +void app_main(void) +{ i2c_init(); - struct bme680_dev dev = {0}; - dev.dev_id = BME680_ADDR; - dev.intf = BME680_I2C_INTF; - dev.read = i2c_read; - dev.write = i2c_write; - dev.delay_ms = delay_ms; + struct bme68x_dev dev = {0}; + uint8_t i2c_addr = BME68X_ADDR; - if (bme680_init(&dev) != BME680_OK) { - printf("BME680 init failed\n"); + dev.intf = BME68X_I2C_INTF; + dev.read = bme68x_i2c_read; + dev.write = bme68x_i2c_write; + dev.delay_us = bme68x_delay_us; + dev.intf_ptr = &i2c_addr; + + if (bme68x_init(&dev) != BME68X_OK) { + printf("BME68x init failed\n"); return; } - // Oversampling / filter - dev.tph_sett.os_hum = BME680_OS_2X; - dev.tph_sett.os_pres = BME680_OS_4X; - dev.tph_sett.os_temp = BME680_OS_8X; - dev.tph_sett.filter = BME680_FILTER_SIZE_3; + /* Oversampling + filter */ + struct bme68x_conf conf = { + .os_hum = BME68X_OS_2X, + .os_temp = BME68X_OS_8X, + .os_pres = BME68X_OS_4X, + .filter = BME68X_FILTER_SIZE_3, + .odr = BME68X_ODR_NONE + }; + if (bme68x_set_conf(&conf, &dev) != BME68X_OK) { + printf("set_conf failed\n"); + return; + } - // Gas sensor - dev.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS; - dev.gas_sett.heatr_temp = 320; // °C - dev.gas_sett.heatr_dur = 150; // ms - - uint8_t set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | - BME680_OSH_SEL | BME680_FILTER_SEL | - BME680_GAS_SENSOR_SEL; - - if (bme680_set_sensor_settings(set_required_settings, &dev) != BME680_OK) { - printf("Sensor settings failed\n"); + /* Gas heater config for one-shot */ + struct bme68x_heatr_conf hconf = { + .enable = BME68X_ENABLE, + .heatr_temp = 320, // °C + .heatr_dur = 150 // ms + }; + if (bme68x_set_heatr_conf(BME68X_FORCED_MODE, &hconf, &dev) != BME68X_OK) { + printf("set_heatr_conf failed\n"); return; } while (1) { - // Force mode, one-shot - if (bme680_set_sensor_mode(&dev) != BME680_OK) { - printf("Set mode failed\n"); + if (bme68x_set_op_mode(BME68X_FORCED_MODE, &dev) != BME68X_OK) { + printf("set_op_mode failed\n"); vTaskDelay(pdMS_TO_TICKS(1000)); continue; } - // Wait for measurement time - uint16_t meas_period; - bme680_get_profile_dur(&meas_period, &dev); - vTaskDelay(pdMS_TO_TICKS(meas_period)); + /* Calculate measurement duration and wait */ + uint32_t dur_us = bme68x_get_meas_dur(BME68X_FORCED_MODE, &conf, &dev) + (hconf.heatr_dur * 1000); + bme68x_delay_us(dur_us, NULL); + + struct bme68x_data data; + uint8_t n_fields = 0; + + if (bme68x_get_data(BME68X_FORCED_MODE, &data, &n_fields, &dev) == BME68X_OK && n_fields > 0) { + /* Note: API returns fixed-point values; divide per defs */ + float temp_c = data.temperature / 100.0f; // °C + float press_hpa = data.pressure / 100.0f; // hPa + float hum_pct = data.humidity / 1000.0f; // %RH + float gas_kohm = data.gas_resistance / 1000.0f; - struct bme680_field_data data; - if (bme680_get_sensor_data(&data, &dev) == BME680_OK) { printf("T=%.2f °C RH=%.2f %% P=%.2f hPa Gas=%.2f kΩ\n", - data.temperature / 100.0f, - data.humidity / 1000.0f, - data.pressure / 100.0f, - data.gas_resistance / 1000.0f); + temp_c, hum_pct, press_hpa, gas_kohm); } else { - printf("Read failed\n"); + printf("read failed\n"); } vTaskDelay(pdMS_TO_TICKS(2000)); diff --git a/sdkconfig b/sdkconfig index ef16411..f34b80c 100644 --- a/sdkconfig +++ b/sdkconfig @@ -31,12 +31,12 @@ CONFIG_ESPTOOLPY_BAUD_115200B=y CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 CONFIG_ESPTOOLPY_BAUD=115200 CONFIG_ESPTOOLPY_COMPRESSED=y -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASHMODE="dio" -CONFIG_SPI_FLASH_MODE=0x2 +CONFIG_SPI_FLASH_MODE=0x0 # CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set CONFIG_ESPTOOLPY_FLASHFREQ_40M=y # CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set @@ -147,17 +147,17 @@ CONFIG_ESP8266_PHY_MAX_WIFI_TX_POWER=20 # CONFIG_ESP8266_HSPI_HIGH_THROUGHPUT is not set CONFIG_ESP_ERR_TO_NAME_LOOKUP=y CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2048 CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 CONFIG_ESP_CONSOLE_UART_DEFAULT=y # CONFIG_ESP_CONSOLE_UART_CUSTOM is not set # CONFIG_ESP_CONSOLE_UART_NONE is not set CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=74880 # CONFIG_ESP_UART0_SWAP_IO is not set CONFIG_ESP_TASK_WDT=y -# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_PANIC=y # CONFIG_ESP_TASK_WDT_TIMEOUT_13N is not set # CONFIG_ESP_TASK_WDT_TIMEOUT_14N is not set CONFIG_ESP_TASK_WDT_TIMEOUT_15N=y @@ -167,7 +167,7 @@ CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set CONFIG_HTTP_BUF_SIZE=512 -CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_OTA_BUF_SIZE=256 # CONFIG_OTA_ALLOW_HTTP is not set @@ -225,8 +225,8 @@ CONFIG_FREERTOS_UNICORE=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_HZ=100 CONFIG_FREERTOS_MAX_HOOK=2 -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_ISR_STACKSIZE=512 # CONFIG_FREERTOS_EXTENED_HOOKS is not set CONFIG_FREERTOS_GLOBAL_DATA_LINK_IRAM=y # CONFIG_FREERTOS_CODE_LINK_TO_IRAM is not set @@ -236,7 +236,7 @@ CONFIG_TASK_SWITCH_FASTER=y # CONFIG_ENABLE_FREERTOS_SLEEP is not set # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y # CONFIG_HEAP_DISABLE_IRAM is not set # CONFIG_HEAP_TRACING is not set CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y @@ -247,7 +247,7 @@ CONFIG_LOG_DEFAULT_LEVEL_INFO=y # CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_LOG_DEFAULT_LEVEL=3 -# CONFIG_LOG_COLORS is not set +CONFIG_LOG_COLORS=y # CONFIG_LOG_SET_LEVEL is not set CONFIG_LWIP_LOCAL_HOSTNAME="espressif" CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y @@ -282,11 +282,11 @@ CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 CONFIG_LWIP_MAX_ACTIVE_TCP=16 CONFIG_LWIP_MAX_LISTENING_TCP=16 CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=6 CONFIG_LWIP_TCP_MSS=1440 CONFIG_LWIP_TCP_TMR_INTERVAL=250 CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=2880 CONFIG_LWIP_TCP_WND_DEFAULT=5760 CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y @@ -295,10 +295,10 @@ CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set # CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_TCP_RTO_TIME=3000 CONFIG_LWIP_MAX_UDP_PCBS=16 CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=2048 CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF @@ -308,7 +308,7 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # CONFIG_LWIP_MULTICAST_PING is not set # CONFIG_LWIP_BROADCAST_PING is not set CONFIG_LWIP_MAX_RAW_PCBS=16 -CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6 is not set CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_ESP_LWIP_ASSERT=y @@ -395,7 +395,7 @@ CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set # CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_NANO_FORMAT=y # CONFIG_OPENSSL_DEBUG is not set CONFIG_OPENSSL_ASSERT_DO_NOTHING=y # CONFIG_OPENSSL_ASSERT_EXIT is not set @@ -443,9 +443,9 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # Deprecated options for backward compatibility CONFIG_TARGET_PLATFORM="esp8266" CONFIG_TOOLPREFIX="xtensa-lx106-elf-" -# CONFIG_FLASHMODE_QIO is not set +CONFIG_FLASHMODE_QIO=y # CONFIG_FLASHMODE_QOUT is not set -CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DIO is not set # CONFIG_FLASHMODE_DOUT is not set # CONFIG_MONITOR_BAUD_9600B is not set # CONFIG_MONITOR_BAUD_57600B is not set @@ -474,10 +474,10 @@ CONFIG_CONSOLE_UART_DEFAULT=y # CONFIG_CONSOLE_UART_CUSTOM is not set # CONFIG_CONSOLE_UART_NONE is not set CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_CONSOLE_UART_BAUDRATE=74880 # CONFIG_UART0_SWAP_IO is not set CONFIG_TASK_WDT=y -# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_PANIC=y CONFIG_TASK_WDT_TIMEOUT_S=15 CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 @@ -499,10 +499,10 @@ CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 CONFIG_TCPIP_RECVMBOX_SIZE=32 CONFIG_TCP_MAXRTX=12 -CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_SYNMAXRTX=6 CONFIG_TCP_MSS=1440 CONFIG_TCP_MSL=60000 -CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_SND_BUF_DEFAULT=2880 CONFIG_TCP_WND_DEFAULT=5760 CONFIG_TCP_RECVMBOX_SIZE=6 CONFIG_TCP_QUEUE_OOSEQ=y @@ -511,7 +511,7 @@ CONFIG_TCP_OVERSIZE_MSS=y # CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set # CONFIG_TCP_OVERSIZE_DISABLE is not set CONFIG_UDP_RECVMBOX_SIZE=6 -CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_STACK_SIZE=2048 CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF