Add support for HMC5883L

Add support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn (#17069)
This commit is contained in:
Theo Arends 2022-11-15 11:11:32 +01:00
parent 5e61ee6086
commit 5f3d504c30
7 changed files with 58 additions and 50 deletions

View File

@ -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

View File

@ -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)

View File

@ -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};

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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","","",
"","","","",
"","","","",
"","","","",