diff --git a/src/driver/drv_local.h b/src/driver/drv_local.h index 128fb13c4..6375efc4d 100644 --- a/src/driver/drv_local.h +++ b/src/driver/drv_local.h @@ -69,5 +69,10 @@ void CHT8305_OnEverySecond(); void CHT8305_AppendInformationToHTTPIndexPage(http_request_t* request); void CHT8305_OnChannelChanged(int ch, int value); +void SHT3X_Init(); +void SHT3X_OnEverySecond(); +void SHT3X_AppendInformationToHTTPIndexPage(http_request_t* request); +void SHT3X_OnChannelChanged(int ch, int value); void DRV_MAX72XX_Init(); + diff --git a/src/driver/drv_main.c b/src/driver/drv_main.c index 8aaf5c9dd..ff021fbe4 100644 --- a/src/driver/drv_main.c +++ b/src/driver/drv_main.c @@ -114,7 +114,9 @@ static driver_t g_drivers[] = { { "CHT8305", CHT8305_Init, CHT8305_OnEverySecond, CHT8305_AppendInformationToHTTPIndexPage, NULL, NULL, CHT8305_OnChannelChanged, false }, { "MAX72XX", DRV_MAX72XX_Init, NULL, NULL, NULL, NULL, NULL, false }, #endif - +#if defined(PLATFORM_BEKEN) || defined(WINDOWS) + { "SHT3X", SHT3X_Init, SHT3X_OnEverySecond, SHT3X_AppendInformationToHTTPIndexPage, NULL, NULL, SHT3X_OnChannelChanged, false }, +#endif }; static const int g_numDrivers = sizeof(g_drivers) / sizeof(g_drivers[0]); diff --git a/src/driver/drv_sht3x.c b/src/driver/drv_sht3x.c new file mode 100644 index 000000000..ed00c4cdb --- /dev/null +++ b/src/driver/drv_sht3x.c @@ -0,0 +1,239 @@ +#include "../new_common.h" +#include "../new_pins.h" +#include "../new_cfg.h" +// Commands register, execution API and cmd tokenizer +#include "../cmnds/cmd_public.h" +#include "../mqtt/new_mqtt.h" +#include "../logging/logging.h" +#include "drv_local.h" +#include "drv_uart.h" +#include "../httpserver/new_http.h" +#include "../hal/hal_pins.h" + +#include "drv_sht3x.h" + +// Some platforms have less pins than BK7231T. +// For example, BL602 doesn't have pin number 26. +// The pin code would crash BL602 while trying to access pin 26. +// This is why the default settings here a per-platform. +#if PLATFORM_BEKEN +static int g_pin_clk = 9; +static int g_pin_data = 14; +#else +static int g_pin_clk = 0; +static int g_pin_data = 1; +#endif + +#define SHT3X_I2C_ADDR (0x44 << 1) + +static byte channel_temp = 0, channel_humid = 0; +static float g_temp = 0.0, g_humid = 0.0; + +static void SHT3X_SetLow(uint8_t pin) { + HAL_PIN_Setup_Output(pin); + HAL_PIN_SetOutputValue(pin, 0); + } + +static void SHT3X_SetHigh(uint8_t pin) { + HAL_PIN_Setup_Input_Pullup(pin); + } + +static bool SHT3X_PreInit(void) { + HAL_PIN_SetOutputValue(g_pin_data, 0); + HAL_PIN_SetOutputValue(g_pin_clk, 0); + SHT3X_SetHigh(g_pin_data); + SHT3X_SetHigh(g_pin_clk); + return (!((HAL_PIN_ReadDigitalInput(g_pin_data) == 0 || HAL_PIN_ReadDigitalInput(g_pin_clk) == 0))); + } + +static bool SHT3X_WriteByte(uint8_t value) { + uint8_t curr; + uint8_t ack; + + for (curr = 0x80; curr != 0; curr >>= 1) + { + if (curr & value) + { + SHT3X_SetHigh(g_pin_data); + } + else + { + SHT3X_SetLow(g_pin_data); + } + SHT3X_SetHigh(g_pin_clk); + usleep(SHT3X_DELAY); + SHT3X_SetLow(g_pin_clk); + } + // get Ack or Nak + SHT3X_SetHigh(g_pin_data); + SHT3X_SetHigh(g_pin_clk); + usleep(SHT3X_DELAY / 2); + ack = HAL_PIN_ReadDigitalInput(g_pin_data); + SHT3X_SetLow(g_pin_clk); + usleep(SHT3X_DELAY / 2); + SHT3X_SetLow(g_pin_data); + return (0 == ack); + } + +static bool SHT3X_Start(uint8_t addr) { + SHT3X_SetLow(g_pin_data); + usleep(SHT3X_DELAY); + SHT3X_SetLow(g_pin_clk); + return SHT3X_WriteByte(addr); + } + +static void SHT3X_Stop(void) { + SHT3X_SetLow(g_pin_data); + usleep(SHT3X_DELAY); + SHT3X_SetHigh(g_pin_clk); + usleep(SHT3X_DELAY); + SHT3X_SetHigh(g_pin_data); + usleep(SHT3X_DELAY); + } + +static uint8_t SHT3X_ReadByte(bool nack) + { + uint8_t val = 0; + + SHT3X_SetHigh(g_pin_data); + for (int i = 0; i < 8; i++) + { + usleep(SHT3X_DELAY); + SHT3X_SetHigh(g_pin_clk); + val <<= 1; + if (HAL_PIN_ReadDigitalInput(g_pin_data)) + { + val |= 1; + } + SHT3X_SetLow(g_pin_clk); + } + if (nack) + { + SHT3X_SetHigh(g_pin_data); + } + else + { + SHT3X_SetLow(g_pin_data); + } + SHT3X_SetHigh(g_pin_clk); + usleep(SHT3X_DELAY); + SHT3X_SetLow(g_pin_clk); + usleep(SHT3X_DELAY); + SHT3X_SetLow(g_pin_data); + + return val; + } + + +static void SHT3X_ReadBytes(uint8_t* buf, int numOfBytes) + { + + for (int i = 0; i < numOfBytes - 1; i++) + { + + buf[i] = SHT3X_ReadByte(false); + + } + + buf[numOfBytes - 1] = SHT3X_ReadByte(true); //Give NACK on last byte read + } + + + +//static commandResult_t SHT3X_GETENV(const void* context, const char* cmd, const char* args, int flags){ +// const char* c = args; +// +// ADDLOG_DEBUG(LOG_FEATURE_CMD, "SHT3X_GETENV"); +// +// return CMD_RES_OK; +//} + +static void SHT3X_ReadEnv(float* temp, float* hum) + { + uint8_t buff[6]; + unsigned int th, tl, hh, hl; + + SHT3X_Start(SHT3X_I2C_ADDR); + // no clock stretching + SHT3X_WriteByte(0x24); + // medium repeteability + SHT3X_WriteByte(0x16); + SHT3X_Stop(); + + rtos_delay_milliseconds(20); //give the sensor time to do the conversion + + SHT3X_Start(SHT3X_I2C_ADDR | 1); + SHT3X_ReadBytes(buff, 6); + SHT3X_Stop(); + + // Reset the sensor + SHT3X_Start(SHT3X_I2C_ADDR); + SHT3X_WriteByte(0x30); + SHT3X_WriteByte(0xA2); + SHT3X_Stop(); + + th = buff[0]; + tl = buff[1]; + hh = buff[3]; + hl = buff[4]; + + (*temp) = 175 * ( (th * 256 + tl) / 65535.0 ) - 45.0; + + (*hum) = 100 * ((hh * 256 + hl) / 65535.0); + + } + +// startDriver SHT3X +void SHT3X_Init() { + + uint8_t status[2]; + + SHT3X_PreInit(); + + g_pin_clk = PIN_FindPinIndexForRole(IOR_SHT3X_CLK, g_pin_clk); + g_pin_data = PIN_FindPinIndexForRole(IOR_SHT3X_DAT, g_pin_data); + + SHT3X_Start(SHT3X_I2C_ADDR); + SHT3X_WriteByte(0x30); //Disable Heater + SHT3X_WriteByte(0x66); + SHT3X_Stop(); + + SHT3X_Start(SHT3X_I2C_ADDR); + SHT3X_WriteByte(0xf3); //Get Status + SHT3X_WriteByte(0x2d); + SHT3X_Stop(); + SHT3X_Start(SHT3X_I2C_ADDR | 1); + SHT3X_ReadBytes(status, 2); + SHT3X_Stop(); + + addLogAdv(LOG_INFO, LOG_FEATURE_SENSOR, "DRV_SHT3X_init: ID: %02X %02X\n", status[0], status[1]); + + + + } + +void SHT3X_OnChannelChanged(int ch, int value) { + } + +void SHT3X_OnEverySecond() { + + SHT3X_ReadEnv(&g_temp, &g_humid); + + channel_temp = g_cfg.pins.channels[g_pin_data]; + channel_humid = g_cfg.pins.channels2[g_pin_data]; + CHANNEL_SetType(channel_temp, CHANNEL_ParseChannelType("temperature_div10")); + CHANNEL_Set(channel_temp, (int)(g_temp * 10), 0); + CHANNEL_SetType(channel_humid, CHANNEL_ParseChannelType("humidity")); + CHANNEL_Set(channel_humid, (int)(g_humid), 0); + + addLogAdv(LOG_INFO, LOG_FEATURE_SENSOR, "DRV_SHT3X_readEnv: Temperature:%fC Humidity:%f%%\n", g_temp, g_humid); +} + +void SHT3X_AppendInformationToHTTPIndexPage(http_request_t* request) +{ + hprintf255(request, "

SHT3X Temperature=%f, Humidity=%f

", g_temp, g_humid); + if (channel_humid == channel_temp) { + hprintf255(request, "WARNING: You don't have configured target channels for temp and humid results, set the first and second channel index in Pins!"); + } +} + diff --git a/src/driver/drv_sht3x.h b/src/driver/drv_sht3x.h new file mode 100644 index 000000000..901e5f62a --- /dev/null +++ b/src/driver/drv_sht3x.h @@ -0,0 +1 @@ +#define SHT3X_DELAY 4 \ No newline at end of file diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c index 05fece121..e2e41b5eb 100644 --- a/src/httpserver/http_fns.c +++ b/src/httpserver/http_fns.c @@ -2678,7 +2678,7 @@ int http_fn_cfg_pins(http_request_t* request) { poststr(request, ""); // Primary linked channel // Some roles do not need any channels - if (si != IOR_CHT8305_CLK && si != IOR_Button_ToggleAll && si != IOR_Button_ToggleAll_n + if (si != IOR_SHT3X_CLK && si != IOR_CHT8305_CLK && si != IOR_Button_ToggleAll && si != IOR_Button_ToggleAll_n && si != IOR_BL0937_CF && si != IOR_BL0937_CF1 && si != IOR_BL0937_SEL && si != IOR_LED_WIFI && si != IOR_LED_WIFI_n && si != IOR_LED_WIFI_n && !(si >= IOR_IRRecv && si <= IOR_DHT11) @@ -2688,7 +2688,7 @@ int http_fn_cfg_pins(http_request_t* request) { } // Secondary linked channel // For button, is relay index to toggle on double click - if (si == IOR_Button || si == IOR_Button_n || IS_PIN_DHT_ROLE(si) || si == IOR_CHT8305_DAT) + if (si == IOR_Button || si == IOR_Button_n || IS_PIN_DHT_ROLE(si) || si == IOR_CHT8305_DAT || si == IOR_SHT3X_DAT ) { hprintf255(request, "", i, ch2); } diff --git a/src/httpserver/new_http.c b/src/httpserver/new_http.c index 5305b486e..32d279a7d 100644 --- a/src/httpserver/new_http.c +++ b/src/httpserver/new_http.c @@ -418,6 +418,8 @@ const char* htmlPinRoleNames[] = { "DHT22", "CHT8305_SDA", "CHT8305_SCK", + "SHT3X_SDA", + "SHT3X_SCK", "error", "error", "error", diff --git a/src/new_pins.c b/src/new_pins.c index adf2a8757..cbc6129e9 100644 --- a/src/new_pins.c +++ b/src/new_pins.c @@ -1099,7 +1099,7 @@ bool CHANNEL_HasRoleThatShouldBePublished(int ch) { if (role == IOR_Relay || role == IOR_Relay_n || role == IOR_LED || role == IOR_LED_n || role == IOR_ADC - || role == IOR_CHT8305_DAT + || role == IOR_CHT8305_DAT || role == IOR_SHT3X_DAT || role == IOR_DigitalInput || role == IOR_DigitalInput_n || IS_PIN_DHT_ROLE(role) || role == IOR_DigitalInput_NoPup || role == IOR_DigitalInput_NoPup_n) { @@ -1110,8 +1110,8 @@ bool CHANNEL_HasRoleThatShouldBePublished(int ch) { if (IS_PIN_DHT_ROLE(role)) { return true; } - // CHT8305 uses secondary channel for humidity - if (role == IOR_CHT8305_DAT) { + // CHT8305 and SHT3X uses secondary channel for humidity + if (role == IOR_CHT8305_DAT || role == IOR_SHT3X_DAT) { return true; } } diff --git a/src/new_pins.h b/src/new_pins.h index 0def0854b..5bbfc5260 100644 --- a/src/new_pins.h +++ b/src/new_pins.h @@ -72,6 +72,9 @@ enum IORole { IOR_CHT8305_DAT, IOR_CHT8305_CLK, + IOR_SHT3X_DAT, + IOR_SHT3X_CLK, + IOR_SOFT_SDA, IOR_SOFT_SCL,