The SHTC3 is an Adafruit module with 10k external pullups, powered from the esp32's 3.3v rail (pico-04 from digikey). This same hardware and circuit has been working for years with v5.1.4 and the old driver. It stopped working reliably with v5.2.3, so I wrote this code for the new driver using v5.5.2 and have not got it to work.
Any ideas?
Code: Select all
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include <sys/param.h>
#include "esp_log.h"
#include "esp_timer.h"
#include "driver/gpio.h"
#include "driver/i2c_master.h"
#define SHTC3_ADDR 0x70
#define PIN_SHTC3_POWER GPIO_NUM_19
#define PIN_SDA GPIO_NUM_21
#define PIN_SCL GPIO_NUM_22
uint32_t const appVersion = 2601232;
static uint8_t Shtc3_cmdSleep[] = {0xB0, 0x98};
static uint8_t Shtc3_cmdWake[] = {0x35, 0x17};
static uint8_t Shtc3_cmdReadClockStretched[] = {0x7C, 0xA2};
static esp_err_t i2cBusStart(i2c_master_bus_handle_t *bus) {
esp_log_write(ESP_LOG_INFO, "Airmon", "i2c_new_master_bus\n");
i2c_master_bus_config_t bus_cfg = {
.i2c_port = I2C_NUM_0,
.sda_io_num = PIN_SDA,
.scl_io_num = PIN_SCL,
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = false,
};
return i2c_new_master_bus(&bus_cfg, bus);
}
static esp_err_t addDevice(i2c_master_bus_handle_t bus, uint8_t addr, i2c_master_dev_handle_t *dev) {
esp_log_write(ESP_LOG_INFO, "Airmon", "i2c_master_bus_add_device\n");
i2c_device_config_t dev_cfg = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = addr,
.scl_speed_hz = 10000,
};
return i2c_master_bus_add_device(bus, &dev_cfg, dev);
}
static bool shtc3Sleep(i2c_master_dev_handle_t dev) {
esp_err_t err = i2c_master_transmit(dev, Shtc3_cmdSleep, sizeof(Shtc3_cmdSleep), pdMS_TO_TICKS(20));
esp_log_write(ESP_LOG_INFO, "Airmon", "i2c_master_transmit sleep=%d\n", err);
return err == ESP_OK;
}
static bool shtc3Cycle(i2c_master_dev_handle_t dev) {
esp_err_t err;
err = i2c_master_transmit(dev, Shtc3_cmdWake, sizeof(Shtc3_cmdWake), pdMS_TO_TICKS(20));
esp_log_write(ESP_LOG_INFO, "Airmon", "shtc3 wake err=%d\n", err);
if (err != ESP_OK) return false;
int64_t x = esp_timer_get_time();
while((esp_timer_get_time() - x) < 240);
uint8_t recvBuf[6];
err = i2c_master_transmit_receive(dev, Shtc3_cmdReadClockStretched, sizeof(Shtc3_cmdReadClockStretched), (uint8_t *)recvBuf, sizeof(recvBuf), pdMS_TO_TICKS(1000));
esp_log_write(ESP_LOG_INFO, "Airmon", "shtc3 read err=%d\n", err);
if (err != ESP_OK) return false;
err = i2c_master_transmit(dev, Shtc3_cmdSleep, sizeof(Shtc3_cmdSleep), pdMS_TO_TICKS(20));
esp_log_write(ESP_LOG_INFO, "Airmon", "shtc3 sleep err=%d\n", err);
return (err == ESP_OK);
}
void app_main(void) {
esp_log_write(ESP_LOG_INFO, "Airmon", "Airmon_v552c app_main start v%ld\n", appVersion);
esp_log_level_set("gpio", ESP_LOG_VERBOSE);
esp_log_level_set("i2c", ESP_LOG_VERBOSE);
vTaskDelay(pdMS_TO_TICKS(100));
i2c_master_bus_handle_t bus = NULL;
i2c_master_dev_handle_t shtc3 = NULL;
if (i2cBusStart(&bus) == ESP_OK) {
if (addDevice(bus, SHTC3_ADDR, &shtc3) == ESP_OK) {
if (shtc3Sleep(shtc3)) {
bool ok;
do {
vTaskDelay(pdMS_TO_TICKS(3000));
ok = shtc3Cycle(shtc3);
} while(ok);
esp_log_write(ESP_LOG_INFO, "Airmon", "shtc3Cycle failed\n");
} else {
esp_log_write(ESP_LOG_INFO, "Airmon", "initial sleep failed\n");
}
esp_log_write(ESP_LOG_INFO, "Airmon", "deleting shtc3\n");
if (i2c_master_bus_rm_device(shtc3) != ESP_OK) esp_log_write(ESP_LOG_INFO, "Airmon", "i2c_master_bus_rm_device failed\n");
} else {
esp_log_write(ESP_LOG_INFO, "Airmon", "addDevice failed\n");
}
esp_log_write(ESP_LOG_INFO, "Airmon", "stopping bus\n");
if (i2c_del_master_bus(bus) != ESP_OK) esp_log_write(ESP_LOG_INFO, "Airmon", "i2c_del_master_bus failed\n");
bus = NULL;
} else {
esp_log_write(ESP_LOG_INFO, "Airmon", "i2cBusStart failed\n");
}
}