mirror of https://github.com/arendst/Tasmota.git
Add support for QMC5883L magnetic induction sensor
Add support for QMC5883L magnetic induction sensor by Helge Scheunemann (#16714)
This commit is contained in:
parent
29a9197101
commit
da623701d7
|
@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
|
||||||
### Added
|
### Added
|
||||||
- Support for Shelly Plus 2PM using template ``{"NAME":"Shelly Plus 2PM PCB v0.1.9","GPIO":[320,0,0,0,32,192,0,0,225,224,0,0,0,0,193,0,0,0,0,0,0,608,640,3458,0,0,0,0,0,9472,0,4736,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}``
|
- Support for Shelly Plus 2PM using template ``{"NAME":"Shelly Plus 2PM PCB v0.1.9","GPIO":[320,0,0,0,32,192,0,0,225,224,0,0,0,0,193,0,0,0,0,0,0,608,640,3458,0,0,0,0,0,9472,0,4736,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}``
|
||||||
- Zigbee Alexa/Hue emulation, support multiple switches on separate endpoints
|
- Zigbee Alexa/Hue emulation, support multiple switches on separate endpoints
|
||||||
|
- Support for QMC5883L magnetic induction sensor by Helge Scheunemann (#16714)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
|
@ -116,9 +116,11 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||||
- Command ``UrlFetch <url>`` to download a file to filesystem
|
- Command ``UrlFetch <url>`` to download a file to filesystem
|
||||||
- Command ``DspSpeed 2..127`` to control message rotation speed on display of POWR3xxD and THR3xxD
|
- Command ``DspSpeed 2..127`` to control message rotation speed on display of POWR3xxD and THR3xxD
|
||||||
- Command ``DspLine<1|2> <index>,<unit>,<index>,<unit>,...`` to select message(s) on display of POWR3xxD and THR3xxD
|
- Command ``DspLine<1|2> <index>,<unit>,<index>,<unit>,...`` to select message(s) on display of POWR3xxD and THR3xxD
|
||||||
|
- Support for Shelly Plus 2PM
|
||||||
- Support for SGP40 gas and air quality sensor [#16341](https://github.com/arendst/Tasmota/issues/16341)
|
- Support for SGP40 gas and air quality sensor [#16341](https://github.com/arendst/Tasmota/issues/16341)
|
||||||
- Support for Modbus writing using ModbusBridge by JeroenSt [#16351](https://github.com/arendst/Tasmota/issues/16351)
|
- Support for Modbus writing using ModbusBridge by JeroenSt [#16351](https://github.com/arendst/Tasmota/issues/16351)
|
||||||
- Support for DFRobot SEN0390 V30B ambient light sensor [#16105](https://github.com/arendst/Tasmota/issues/16105)
|
- Support for DFRobot SEN0390 V30B ambient light sensor [#16105](https://github.com/arendst/Tasmota/issues/16105)
|
||||||
|
- Support for QMC5883L magnetic induction sensor by Helge Scheunemann [#16714](https://github.com/arendst/Tasmota/issues/16714)
|
||||||
- Zigbee device plugin mechanism with commands ``ZbLoad``, ``ZbUnload`` and ``ZbLoadDump`` [#16252](https://github.com/arendst/Tasmota/issues/16252)
|
- Zigbee device plugin mechanism with commands ``ZbLoad``, ``ZbUnload`` and ``ZbLoadDump`` [#16252](https://github.com/arendst/Tasmota/issues/16252)
|
||||||
- Zigbee basic support for Green Power [#16407](https://github.com/arendst/Tasmota/issues/16407)
|
- Zigbee basic support for Green Power [#16407](https://github.com/arendst/Tasmota/issues/16407)
|
||||||
- Zigbee friendly names per endpoint
|
- Zigbee friendly names per endpoint
|
||||||
|
|
|
@ -685,6 +685,8 @@
|
||||||
// #define USE_DS3502 // [I2CDriver67] Enable DS3502 digital potentiometer (I2C address 0x28 - 0x2B) (+0k4 code)
|
// #define USE_DS3502 // [I2CDriver67] Enable DS3502 digital potentiometer (I2C address 0x28 - 0x2B) (+0k4 code)
|
||||||
// #define USE_HYT // [I2CDriver68] Enable HYTxxx temperature and humidity sensor (I2C address 0x28) (+0k5 code)
|
// #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_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 QMC5883L_TEMP_SHIFT 23 // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
|
||||||
|
|
||||||
// #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
|
// #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
|
||||||
// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
|
// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
|
||||||
|
@ -715,8 +717,6 @@
|
||||||
// Reference: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-led-backpack.pdf
|
// Reference: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-led-backpack.pdf
|
||||||
// #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays
|
// #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays
|
||||||
// #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
|
// #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
|
||||||
// #define USE_QMC5883L // USE_QMC5883L magnetic induction sensor, (I2C address 0x0D)
|
|
||||||
// #define QMC5883L_TEMP_SHIFT 23 // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
|
|
||||||
#endif // USE_I2C
|
#endif // USE_I2C
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -834,8 +834,9 @@ void ResponseAppendFeatures(void)
|
||||||
#if defined(USE_SPI) && defined(USE_CANSNIFFER)
|
#if defined(USE_SPI) && defined(USE_CANSNIFFER)
|
||||||
feature9 |= 0x00000004; // xsns_87_can_sniffer.ino
|
feature9 |= 0x00000004; // xsns_87_can_sniffer.ino
|
||||||
#endif
|
#endif
|
||||||
// feature9 |= 0x00000008;
|
#if defined(USE_I2C) && defined(USE_QMC5883L)
|
||||||
|
feature9 |= 0x00000008; // xsns_33_qmc5882l.ino
|
||||||
|
#endif
|
||||||
// feature9 |= 0x00000010;
|
// feature9 |= 0x00000010;
|
||||||
// feature9 |= 0x00000020;
|
// feature9 |= 0x00000020;
|
||||||
// feature9 |= 0x00000040;
|
// feature9 |= 0x00000040;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
xsns_99_qmc5883l.ino - QMC5883L 3-Axis Digital Compass sensor support for Tasmota
|
xsns_33_qmc5883l.ino - QMC5883L 3-Axis Digital Compass sensor support for Tasmota
|
||||||
|
|
||||||
Copyright (C) 2022 Helge Scheunemann
|
Copyright (C) 2022 Helge Scheunemann
|
||||||
|
|
||||||
|
@ -15,7 +15,16 @@
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
#ifdef USE_QMC5883L
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* QMC5883L is 3-Axis Digital Compass sensor
|
||||||
|
*
|
||||||
|
* I2C Address: 0x0D
|
||||||
|
\*********************************************************************************************/
|
||||||
|
/*
|
||||||
DATASHEET
|
DATASHEET
|
||||||
|
|
||||||
The QMC5883L is a multi-chip three-axis magnetic sensor. This
|
The QMC5883L is a multi-chip three-axis magnetic sensor. This
|
||||||
|
@ -152,21 +161,14 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_I2C
|
|
||||||
#ifdef USE_QMC5883L
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
|
||||||
* QMC5883L is 3-Axis Digital Compass sensor
|
|
||||||
*
|
|
||||||
* Source: Helge Scheunemann
|
|
||||||
*
|
|
||||||
* I2C Address: 0x0D
|
|
||||||
\*********************************************************************************************/
|
|
||||||
|
|
||||||
// Define driver ID
|
// Define driver ID
|
||||||
#define XSNS_33 33
|
#define XSNS_33 33
|
||||||
#define XI2C_71 71 // See I2CDEVICES.md
|
#define XI2C_71 71 // See I2CDEVICES.md
|
||||||
|
|
||||||
|
#ifndef QMC5883L_TEMP_SHIFT
|
||||||
|
#define QMC5883L_TEMP_SHIFT 23 // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The default I2C address of this chip */
|
/* The default I2C address of this chip */
|
||||||
#define QMC5883L_ADDR 0x0D
|
#define QMC5883L_ADDR 0x0D
|
||||||
|
|
||||||
|
@ -215,49 +217,42 @@
|
||||||
#define QMC5883L_CONFIG2_RESET 0b10000000
|
#define QMC5883L_CONFIG2_RESET 0b10000000
|
||||||
|
|
||||||
// data field
|
// data field
|
||||||
struct QMC5883L_s
|
struct QMC5883L_s {
|
||||||
{
|
|
||||||
int16_t MX, MY, MZ;
|
int16_t MX, MY, MZ;
|
||||||
int16_t temp;
|
float temp;
|
||||||
uint16_t scalar;
|
uint16_t scalar;
|
||||||
} *QMC5883L = nullptr;
|
} *QMC5883L = nullptr;
|
||||||
|
|
||||||
|
|
||||||
// Initialise the device
|
// Initialise the device
|
||||||
void QMC5883L_Init()
|
void QMC5883L_Init() {
|
||||||
{
|
if (!I2cSetDevice(QMC5883L_ADDR)) { return; }
|
||||||
if (!I2cSetDevice(QMC5883L_ADDR))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
I2cSetActiveFound(QMC5883L_ADDR, "QMC5883L");
|
|
||||||
// reset QMC5883L
|
// reset QMC5883L
|
||||||
if (I2cWrite8(QMC5883L_ADDR, QMC5883L_CONFIG2, QMC5883L_CONFIG2_RESET) == false)
|
if (I2cWrite8(QMC5883L_ADDR, QMC5883L_CONFIG2, QMC5883L_CONFIG2_RESET) == false) { return; }
|
||||||
return; // Software Reset
|
// Software Reset
|
||||||
if (I2cWrite8(QMC5883L_ADDR, QMC5883L_RESET, 0x01) == false)
|
if (I2cWrite8(QMC5883L_ADDR, QMC5883L_RESET, 0x01) == false) { return; }
|
||||||
return;
|
|
||||||
// write config
|
// write config
|
||||||
if (I2cWrite8(QMC5883L_ADDR, QMC5883L_CONFIG, QMC5883L_CONFIG_OS256 | QMC5883L_CONFIG_8GAUSS | QMC5883L_CONFIG_100HZ | QMC5883L_CONFIG_CONT) == false)
|
if (I2cWrite8(QMC5883L_ADDR, QMC5883L_CONFIG, QMC5883L_CONFIG_OS256 | QMC5883L_CONFIG_8GAUSS | QMC5883L_CONFIG_100HZ | QMC5883L_CONFIG_CONT) == false) { return; }
|
||||||
return;
|
|
||||||
|
I2cSetActiveFound(QMC5883L_ADDR, "QMC5883L");
|
||||||
QMC5883L = (QMC5883L_s *)calloc(1, sizeof(struct QMC5883L_s));
|
QMC5883L = (QMC5883L_s *)calloc(1, sizeof(struct QMC5883L_s));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read the magnetic data
|
//Read the magnetic data
|
||||||
void QMC5883L_read_data(void)
|
void QMC5883L_read_data(void) {
|
||||||
{
|
|
||||||
// check if chip is ready to provice data
|
// check if chip is ready to provice data
|
||||||
if (!(I2cRead8(QMC5883L_ADDR, QMC5883L_STATUS) & QMC5883L_STATUS_DRDY))
|
if (!(I2cRead8(QMC5883L_ADDR, QMC5883L_STATUS) & QMC5883L_STATUS_DRDY)) { return; } // Chip not yet ready, next round try again
|
||||||
return; // chip not yet ready, next round try again
|
|
||||||
|
|
||||||
QMC5883L->MX = I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_X_LSB); // select LSB register
|
QMC5883L->MX = I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_X_LSB); // Select LSB register
|
||||||
QMC5883L->MY = I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_Y_LSB);
|
QMC5883L->MY = I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_Y_LSB);
|
||||||
QMC5883L->MZ = I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_Z_LSB);
|
QMC5883L->MZ = I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_Z_LSB);
|
||||||
|
|
||||||
// calculate scalar magnetic induction
|
// calculate scalar magnetic induction
|
||||||
QMC5883L->scalar = sqrt((QMC5883L->MX * QMC5883L->MX) + (QMC5883L->MY * QMC5883L->MY) + (QMC5883L->MZ * QMC5883L->MZ));
|
// QMC5883L->scalar = sqrt((QMC5883L->MX * QMC5883L->MX) + (QMC5883L->MY * QMC5883L->MY) + (QMC5883L->MZ * QMC5883L->MZ)); // 650 bytes larger
|
||||||
|
QMC5883L->scalar = SqrtInt((QMC5883L->MX * QMC5883L->MX) + (QMC5883L->MY * QMC5883L->MY) + (QMC5883L->MZ * QMC5883L->MZ));
|
||||||
|
|
||||||
// get temperature
|
// get temperature
|
||||||
QMC5883L->temp = (I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_TEMP_LSB) / 100) + QMC5883L_TEMP_SHIFT;
|
QMC5883L->temp = ConvertTemp((I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_TEMP_LSB) / 100) + QMC5883L_TEMP_SHIFT); // Temp in celsius
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -266,49 +261,36 @@ void QMC5883L_read_data(void)
|
||||||
|
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
const char HTTP_SNS_QMC5883L[] PROGMEM =
|
const char HTTP_SNS_QMC5883L[] PROGMEM =
|
||||||
"{s}QMC5883L " D_MX "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
"{s}QMC5883L " D_MX "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
"{s}QMC5883L " D_MY "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
"{s}QMC5883L " D_MY "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
"{s}QMC5883L " D_MZ "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
"{s}QMC5883L " D_MZ "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
"{s}QMC5883L " D_MAGNETICFLD "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
"{s}QMC5883L " D_MAGNETICFLD "{m}%d " D_UNIT_MICROTESLA "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
"{s}QMC5883L " D_TEMPERATURE "{m}%d " D_UNIT_DEGREE D_UNIT_CELSIUS "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
|
||||||
|
|
||||||
const char HTTP_SNS_QMC5883L_ERROR[] PROGMEM =
|
|
||||||
"{s}QMC5883L {m} %s {e}";
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void QMC5883L_Show(uint8_t json) {
|
||||||
void QMC5883L_Show(uint8_t json)
|
if (json) {
|
||||||
{
|
ResponseAppend_P(PSTR(",\"QMC5883L\":{\"" D_JSON_MX "\":%d,\"" D_JSON_MY "\":%d,\"" D_JSON_MZ "\":%d,\"" D_JSON_MAGNETICFLD "\":%u,\"" D_JSON_TEMPERATURE "\":%*_f}"),
|
||||||
if (json)
|
QMC5883L->MX, QMC5883L->MY, QMC5883L->MZ, QMC5883L->scalar, Settings->flag2.temperature_resolution, &QMC5883L->temp);
|
||||||
{
|
|
||||||
ResponseAppend_P(PSTR(",\"QMC5883L\":{\"" D_JSON_MX "\":%d,\"" D_JSON_MY "\":%d,\"" D_JSON_MZ "\":%d,\"" D_JSON_MAGNETICFLD "\":%u,\"" D_JSON_TEMPERATURE "\":%d}"), QMC5883L->MX, QMC5883L->MY, QMC5883L->MZ, QMC5883L->scalar, QMC5883L->temp);
|
|
||||||
}
|
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
else
|
} else {
|
||||||
{
|
WSContentSend_PD(HTTP_SNS_QMC5883L, QMC5883L->MX, QMC5883L->MY, QMC5883L->MZ, QMC5883L->scalar);
|
||||||
WSContentSend_PD(HTTP_SNS_QMC5883L, QMC5883L->MX, QMC5883L->MY, QMC5883L->MZ, QMC5883L->scalar, QMC5883L->temp);
|
WSContentSend_Temp("QMC5883L", QMC5883L->temp);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Interface
|
* Interface
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
bool Xsns33(byte function)
|
bool Xsns33(byte function) {
|
||||||
{
|
if (!I2cEnabled(XI2C_71)) { return false; }
|
||||||
if (!I2cEnabled(XI2C_71))
|
|
||||||
{
|
if (FUNC_INIT == function) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (FUNC_INIT == function)
|
|
||||||
{
|
|
||||||
QMC5883L_Init();
|
QMC5883L_Init();
|
||||||
}
|
}
|
||||||
else if (QMC5883L != nullptr)
|
else if (QMC5883L != nullptr) {
|
||||||
{
|
switch (function) {
|
||||||
switch (function)
|
|
||||||
{
|
|
||||||
case FUNC_JSON_APPEND:
|
case FUNC_JSON_APPEND:
|
||||||
QMC5883L_Show(1);
|
QMC5883L_Show(1);
|
||||||
break;
|
break;
|
||||||
|
@ -324,5 +306,5 @@ bool Xsns33(byte function)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif // USE_QMC5883L
|
#endif // USE_QMC5883L
|
||||||
#endif // USE_I2C
|
#endif // USE_I2C
|
|
@ -286,7 +286,7 @@ a_features = [[
|
||||||
"USE_PCF85363","USE_DS3502","USE_IMPROV","USE_FLOWRATEMETER",
|
"USE_PCF85363","USE_DS3502","USE_IMPROV","USE_FLOWRATEMETER",
|
||||||
"USE_BP5758D","USE_HYT","USE_SM2335","USE_DISPLAY_TM1621_SONOFF"
|
"USE_BP5758D","USE_HYT","USE_SM2335","USE_DISPLAY_TM1621_SONOFF"
|
||||||
],[
|
],[
|
||||||
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","",
|
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
|
||||||
"","","","",
|
"","","","",
|
||||||
"","","","",
|
"","","","",
|
||||||
"","","","",
|
"","","","",
|
||||||
|
@ -321,7 +321,7 @@ else:
|
||||||
obj = json.load(fp)
|
obj = json.load(fp)
|
||||||
|
|
||||||
def StartDecode():
|
def StartDecode():
|
||||||
print ("\n*** decode-status.py v12.1.1.2 by Theo Arends and Jacek Ziolkowski ***")
|
print ("\n*** decode-status.py v12.1.1.4 by Theo Arends and Jacek Ziolkowski ***")
|
||||||
|
|
||||||
# print("Decoding\n{}".format(obj))
|
# print("Decoding\n{}".format(obj))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue