FreeRTOS-ESP-IDF-I2C/proj5.c
SIMS IOT Devices a013d9e680
Update proj5.c
2022-10-16 09:51:21 +03:00

210 lines
5.0 KiB
C

// I2C BME280 sensor - Temperature read
// Tutorial: https://esp32tutorials.com/esp32-mqtt-publish-bme280-node-red-esp-idf/#more-2125
// Original example: https://github.com/ESP32Tutorials/esp32-esp-idf-mqtt-bme280/blob/main/main/main.c
// BME280 files: https://github.com/ESP32Tutorials/esp32-esp-idf-mqtt-bme280/tree/main/components/bme280
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "esp_err.h"
#include "bme280.h"
#define TAG_BME280 "BME280"
#define SDA_PIN GPIO_NUM_21
#define SCL_PIN GPIO_NUM_22
#define I2C_MASTER_ACK 0
#define I2C_MASTER_NACK 1
// Initialize I2C communication parameters
void i2c_master_init()
{
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = SDA_PIN,
.scl_io_num = SCL_PIN,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 1000000};
i2c_param_config(I2C_NUM_0, &i2c_config);
i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
}
// BME280 I2C write function
s8 BME280_I2C_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
{
s32 iError = BME280_INIT_VALUE;
esp_err_t espRc;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_write(cmd, reg_data, cnt, true);
i2c_master_stop(cmd);
espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
if (espRc == ESP_OK)
{
iError = SUCCESS;
}
else
{
iError = FAIL;
}
i2c_cmd_link_delete(cmd);
return (s8)iError;
}
// BME280 I2C read function
s8 BME280_I2C_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
{
s32 iError = BME280_INIT_VALUE;
esp_err_t espRc;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_READ, true);
if (cnt > 1)
{
i2c_master_read(cmd, reg_data, cnt - 1, I2C_MASTER_ACK);
}
i2c_master_read_byte(cmd, reg_data + cnt - 1, I2C_MASTER_NACK);
i2c_master_stop(cmd);
espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
if (espRc == ESP_OK)
{
iError = SUCCESS;
}
else
{
iError = FAIL;
}
i2c_cmd_link_delete(cmd);
return (s8)iError;
}
// BME280 I2C delay function
void BME280_delay_msek(u32 msek)
{
vTaskDelay(msek / portTICK_PERIOD_MS);
}
// BME280 I2C task
void Publisher_Task(void *params)
{
// BME280 I2C communication structure
struct bme280_t bme280 = {
.bus_write = BME280_I2C_bus_write,
.bus_read = BME280_I2C_bus_read,
.dev_addr = BME280_I2C_ADDRESS1,
.delay_msec = BME280_delay_msek};
s32 com_rslt;
s32 v_uncomp_pressure_s32;
s32 v_uncomp_temperature_s32;
s32 v_uncomp_humidity_s32;
// Initialize BME280 sensor and set internal parameters
com_rslt = bme280_init(&bme280);
printf("com_rslt %d\n", com_rslt);
com_rslt += bme280_set_oversamp_pressure(BME280_OVERSAMP_16X);
com_rslt += bme280_set_oversamp_temperature(BME280_OVERSAMP_2X);
com_rslt += bme280_set_oversamp_humidity(BME280_OVERSAMP_1X);
com_rslt += bme280_set_standby_durn(BME280_STANDBY_TIME_1_MS);
com_rslt += bme280_set_filter(BME280_FILTER_COEFF_16);
com_rslt += bme280_set_power_mode(BME280_NORMAL_MODE);
if (com_rslt == SUCCESS)
{
while (true)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
// Read BME280 data
com_rslt = bme280_read_uncomp_pressure_temperature_humidity(
&v_uncomp_pressure_s32, &v_uncomp_temperature_s32, &v_uncomp_humidity_s32);
double temp = bme280_compensate_temperature_double(v_uncomp_temperature_s32);
char temperature[12];
sprintf(temperature, "%.2f degC", temp);
double press = bme280_compensate_pressure_double(v_uncomp_pressure_s32) / 100; // Pa -> hPa
char pressure[10];
sprintf(pressure, "%.2f hPa", press);
double hum = bme280_compensate_humidity_double(v_uncomp_humidity_s32);
char humidity[10];
sprintf(humidity, "%.2f %%", hum);
// Print BME data
if (com_rslt == SUCCESS)
{
printf("Temperature %s\n",temperature);
}
else
{
ESP_LOGE(TAG_BME280, "measure error. code: %d", com_rslt);
}
}
}
else
{
ESP_LOGE(TAG_BME280, "init or setting error. code: %d", com_rslt);
}
}
void app_main(void)
{
// Initialize memory
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// Initialize I2C parameters
i2c_master_init();
// Read the data from BME280 sensor
xTaskCreate(Publisher_Task, "Publisher_Task", 1024 * 5, NULL, 5, NULL);
}