diff --git a/CHANGELOG.md b/CHANGELOG.md index 7440cc613..2c9543344 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - New ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events - WS2812 and Light Art-Net DMX control over UDP port 6454 (#17059) - Command ``SwitchMode 16`` sending only MQTT message on inverted switch change (#17028) +- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn (#17069) ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 8bc75e96b..06b3968aa 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -120,6 +120,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Support for Plantower PMSx003T AQI models with temperature and humidity [#16971](https://github.com/arendst/Tasmota/issues/16971) - Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011) - Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032) +- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn [#17069](https://github.com/arendst/Tasmota/issues/17069) - WS2812 and Light Art-Net DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059) - Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892) - Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977) diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index bde60e52f..d00ee6295 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -322,16 +322,16 @@ enum WifiConfigOptions {WIFI_RESTART, EX_WIFI_SMARTCONFIG, WIFI_MANAGER, EX_WIFI enum WifiTestOptions {WIFI_NOT_TESTING, WIFI_TESTING, WIFI_TEST_FINISHED, WIFI_TEST_FINISHED_BAD}; -enum SwitchModeOptions {TOGGLE, - FOLLOW, FOLLOW_INV, - PUSHBUTTON, PUSHBUTTON_INV, - PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, - PUSHBUTTON_TOGGLE, - TOGGLEMULTI, - FOLLOWMULTI, FOLLOWMULTI_INV, - PUSHHOLDMULTI, PUSHHOLDMULTI_INV, - PUSHON, PUSHON_INV, - PUSH_IGNORE, PUSH_IGNORE_INV, // 15, 16 +enum SwitchModeOptions {TOGGLE, // 0 + FOLLOW, FOLLOW_INV, // 1, 2 - Follow switch state + PUSHBUTTON, PUSHBUTTON_INV, // 3, 4 - Pushbutton (default 1, 0 = toggle) + PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, // 5, 6 - Pushbutton with hold (default 1, 0 = toggle, Hold = hold) + PUSHBUTTON_TOGGLE, // 7 - = 0 + TOGGLEMULTI, // 8 - = 0 with multi toggle + FOLLOWMULTI, FOLLOWMULTI_INV, // 9, 10 - Multi change follow (0 = off, 1 = on, 2x change = hold) + PUSHHOLDMULTI, PUSHHOLDMULTI_INV, // 11, 12 - Pushbutton with dimmer mode + PUSHON, PUSHON_INV, // 13, 14 - Pushon mode (1 = on, switch off using PulseTime) + PUSH_IGNORE, PUSH_IGNORE_INV, // 15, 16 - Send only MQTT message on switch change MAX_SWITCH_OPTION}; enum LedStateOptions {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION}; diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 23415f8fd..58e6bb30b 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -691,7 +691,7 @@ // #define USE_HYT // [I2CDriver68] Enable HYTxxx temperature and humidity sensor (I2C address 0x28) (+0k5 code) // #define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code) // #define USE_QMC5883L // [I2CDriver71] Enable QMC5883L magnetic induction sensor (I2C address 0x0D) (+0k8 code) -// #define USE_HMC5883L // [I2CDriver73] Enable HMC5883L magnetic induction sensor (I2C address 0x1E) +// #define USE_HMC5883L // [I2CDriver73] Enable HMC5883L magnetic induction sensor (I2C address 0x1E) (+1k3 code) // #define QMC5883L_TEMP_SHIFT 23 // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet) // #define USE_INA3221 // [I2CDriver72] Enable INA3221 3-channel DC voltage and current sensor (I2C address 0x40-0x44) (+3.2k code) // #define INA3221_ADDRESS1 // allow to change the 1st address to search for INA3221 to 0x41..0x43 diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino index f61e15e14..e337b2a90 100644 --- a/tasmota/tasmota_support/support_features.ino +++ b/tasmota/tasmota_support/support_features.ino @@ -852,7 +852,9 @@ void ResponseAppendFeatures(void) #ifdef USE_DINGTIAN_RELAY feature9 |= 0x00000100; // xdrv_90_dingtian_relay.ino #endif -// feature9 |= 0x00000200; +#if defined(USE_I2C) && defined(USE_HMC5883L) + feature9 |= 0x00000200; // xsns_101_hmc5883l.ino +#endif // feature9 |= 0x00000400; // feature9 |= 0x00000800; diff --git a/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino index 56a311354..a800a8998 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino @@ -1,7 +1,7 @@ /* xsns_101_hmc5883l.ino - HMC5883L 3-Axis Digital Compass sensor support for Tasmota - (inspired by Helge Scheunemann) - Copyright (C) 2022 Andreas Achtzehn + + Copyright (C) 2022 Andreas Achtzehn (inspired by Helge Scheunemann) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,8 +27,8 @@ \*********************************************************************************************/ // Define driver ID -#define XSNS_101 101 -#define XI2C_73 73 // See I2CDEVICES.md +#define XSNS_101 101 +#define XI2C_73 73 // See I2CDEVICES.md /* The default I2C address of this chip */ #define HMC5883L_ADDR 0x1E @@ -45,8 +45,8 @@ #define HMC5883L_CONFIG_B 0x01 #define HMC5883L_MODE 0x02 #define HMC5883L_CHIP_ID_A 0x0A -#define HMC5883L_CHIP_ID_B 0x0B -#define HMC5883L_CHIP_ID_C 0x0C +#define HMC5883L_CHIP_ID_B 0x0B +#define HMC5883L_CHIP_ID_C 0x0C /* Bit values for the STATUS register */ const uint8_t HMC5883L_STATUS_RDY = 0b00000001; @@ -104,25 +104,26 @@ bool HMC5883L_SetConfig() { uint8_t cfgB = (( (HMC5883L->gain ) << HMC5883L_CONFIG_B_GAIN_SHIFT ) & HMC5883L_CONFIG_B_GAIN_MASK ); - AddLog(LOG_LEVEL_INFO,"HMC5883L: CONFIG A: %#X CONFIG B: %#X MODE: %#X",cfgA, cfgB, HMC5883L->mode); + AddLog(LOG_LEVEL_INFO,"HMC: CONFIG A: %#X CONFIG B: %#X MODE: %#X", cfgA, cfgB, HMC5883L->mode); - if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_A, cfgA ) == false) { - AddLog(LOG_LEVEL_INFO,"HMC5883L: Setting CONFIG A failed."); - return false; + if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_A, cfgA ) == false) { + AddLog(LOG_LEVEL_INFO,"HMC: Setting CONFIG A failed"); + return false; } - if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_B, cfgB ) == false) { - AddLog(LOG_LEVEL_INFO,"HMC5883L: Setting CONFIG B failed."); - return false; + if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_B, cfgB ) == false) { + AddLog(LOG_LEVEL_INFO,"HMC: Setting CONFIG B failed"); + return false; } if (HMC5883L->mode == HMC5883L_MODE_CONT) { - if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_CONT ) == false) - { AddLog(LOG_LEVEL_INFO,"HMC5883L: Setting continuous mode failed."); - return false; } + if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_CONT ) == false) { + AddLog(LOG_LEVEL_INFO,"HMC: Setting continuous mode failed"); + return false; + } } return true; } -// Initialize the device +// Initialize the device void HMC5883L_Init() { if (!I2cSetDevice(HMC5883L_ADDR)) { return; } @@ -142,11 +143,13 @@ void HMC5883L_Init() { //Read the magnetic data void HMC5883L_ReadData(void) { if (HMC5883L->mode == HMC5883L_MODE_SINGLE) { - if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_SINGLE ) == false) - { return; } + if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_SINGLE ) == false) { return; } + } + + uint32_t timeout = millis() + 20; + while (!(I2cRead8(HMC5883L_ADDR, HMC5883L_STATUS) & HMC5883L_STATUS_RDY)) { + if (millis() > timeout) { return; } // Chip not yet ready, next round try again } - - while (!(I2cRead8(HMC5883L_ADDR, HMC5883L_STATUS) & HMC5883L_STATUS_RDY)) { } // Chip not yet ready, next round try again HMC5883L->MX = I2cReadS16(HMC5883L_ADDR, HMC5883L_X_MSB); // Select starting with MSB register HMC5883L->MY = I2cReadS16(HMC5883L_ADDR, HMC5883L_Y_MSB); @@ -184,32 +187,32 @@ bool HMC5883L_Command() { bool commandKnown = false; char cmd[20]; char ss2[20]; - + subStr(cmd, XdrvMailbox.data, ",", 1); int8_t value = atoi(subStr(ss2, XdrvMailbox.data, ",", 2)); - if (strcmp(cmd,"GAIN")) { + if (strcmp(cmd,"GAIN")) { HMC5883L->gain = value; - commandKnown = true; - } - if (strcmp(cmd,"AVG")) { - HMC5883L->average_mode = value; commandKnown = true; } - if (strcmp(cmd,"RATE")) { - HMC5883L->data_rate = value; + if (strcmp(cmd,"AVG")) { + HMC5883L->average_mode = value; commandKnown = true; } - if (strcmp(cmd,"MMODE")) { - HMC5883L->measurement_mode = value; + if (strcmp(cmd,"RATE")) { + HMC5883L->data_rate = value; commandKnown = true; } - - //AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC5883L: cmd: (%s) value: %d cmdKnown: %d"), cmd, value,commandKnown); + if (strcmp(cmd,"MMODE")) { + HMC5883L->measurement_mode = value; + commandKnown = true; + } + + //AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC: cmd: (%s) value: %d cmdKnown: %d"), cmd, value,commandKnown); if (commandKnown == false) { return false; } - - AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC5883L: Reconfiguring.")); + + AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC: Reconfiguring.")); return HMC5883L_SetConfig(); } @@ -227,8 +230,9 @@ bool Xsns101(uint32_t function) { else if (HMC5883L != nullptr) { switch (function) { case FUNC_COMMAND_SENSOR: - if (XSNS_101 == XdrvMailbox.index) - return HMC5883L_Command(); // Return true on success + if (XSNS_101 == XdrvMailbox.index) { + return HMC5883L_Command(); // Return true on success + } break; case FUNC_JSON_APPEND: HMC5883L_Show(1); diff --git a/tools/decode-status.py b/tools/decode-status.py index 8a8324025..5780173b3 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -288,7 +288,7 @@ a_features = [[ ],[ "USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L", "USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ", - "USE_DINGTIAN_RELAY","","","", + "USE_DINGTIAN_RELAY","USE_HMC5883L","","", "","","","", "","","","", "","","","",