beautified code xsns 33 qmc5883l (#21312)

* Add files via upload

* Add files via upload

beautified code

* Update xsns_33_qmc5883l.ino

date removed

* Add files via upload

adapt defaults for bf-xsns_33_qmc5883l

* Update tasmota/my_user_config.h

Co-authored-by: Erik Kunze <eku@users.noreply.github.com>

---------

Co-authored-by: Erik Kunze <eku@users.noreply.github.com>
This commit is contained in:
fb-pilot 2024-05-07 10:06:57 +02:00 committed by GitHub
parent 08f9b37b99
commit 2f59523416
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 99 additions and 127 deletions

View File

@ -728,9 +728,9 @@ https://rya.nc/tasmota-fingerprint.html"
// #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) (+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 QMC5883L_OVERSAMPLE 1 // 0 .. 3 => 512, 256(default), 128, 64
// #define QMC5883L_GAUSS 0 // 0,1(default) => 2GAUSS, 8GAUSS(default)
// #define QMC5883L_FILTER 2 // 0 .. 3 => 10HZ, 50HZ, 109HZ(default), 200HZ
// #define QMC5883L_OVERSAMPLE 0 // 0 .. 3 => 512(default), 256, 128, 64
// #define QMC5883L_GAUSS 1 // 0,1(default) => 2GAUSS, 8GAUSS(default)
// #define QMC5883L_FILTER 0 // 0 .. 3 => 10HZ(default), 50HZ, 100HZ, 200HZ
// #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
// #define INA3221_MAX_COUNT // change the number of devices to search for (default 4).

View File

@ -1,7 +1,7 @@
/*
xsns_33_qmc5883l.ino - QMC5883L 3-Axis Digital Compass sensor support for Tasmota
Copyright (C) 2022 Helge Scheunemann and Friedbert Bader
Copyright (C) 2022 Helge Scheunemann + fb-pilot
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
@ -24,19 +24,20 @@
*
* I2C Address: 0x0D
*
* #define QMC5883L_OVERSAMPLE 1 // 0 .. 3 => 512, 256, 128, 64
* #define QMC5883L_GAUSS 1 // 0,1 => 2GAUSS, 8GAUSS
* #define QMC5883L_FILTER 2 // 0 .. 3 => 10HZ, 50HZ, 109HZ, 200HZ
* #define QMC5883L_TEMP_SHIFT 23 // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
*
* Calibration :
* valid relations : 1 T = 10000 G ... 1G = 0.1mT = 100µT
* Dynamic Output Field Range ±2 or ±8 Gauss ==> ±200µT or ±800µT
* Sensitivity [1]
* Field Range = ±2G 12000 LSB/G --> factor = 120
* Field Range = ±8G 3000 LSB/G --> factor = 30
* #define QMC5883L_OVERSAMPLE 0 // 0 .. 3 => over Sample Ratio : 512, 256, 128, 64
* #define QMC5883L_GAUSS 1 // 0 .. 1 => full Scale : 2GAUSS, 8GAUSS
* #define QMC5883L_FILTER 0 // 0 .. 3 => Output Data Rate : 10HZ, 50HZ, 109HZ, 200HZ
* #define QMC5883L_TEMP_SHIFT 23.0f // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
* #define QMC5883L_DECIMAL 4 // Decimals for display
\*********************************************************************************************/
#ifndef QMC5883L_TEMP_SHIFT
#define QMC5883L_TEMP_SHIFT 23.0f // sensor temperature is not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
#endif
#ifndef QMC5883L_DECIMAL
#define QMC5883L_DECIMAL 4
#endif
/*
DATASHEET
@ -72,7 +73,21 @@
0BH SET/RESET Period FBR [7:0] Read/Write
0CH Reserved Read only
0DH Reserved Read only
/* Register numbers */
#define QMC5883L_X_LSB 0x00
#define QMC5883L_X_MSB 0x01
#define QMC5883L_Y_LSB 0x02
#define QMC5883L_Y_MSB 0x03
#define QMC5883L_Z_LSB 0x04
#define QMC5883L_Z_MSB 0x05
#define QMC5883L_STATUS 0x06
#define QMC5883L_TEMP_LSB 0x07
#define QMC5883L_TEMP_MSB 0x08
#define QMC5883L_CONFIG 0x09
#define QMC5883L_CONFIG2 0x0a
#define QMC5883L_RESET 0x0b // SET/RESET Period it is recommended that the register 0BH is written by 0x01.
// #define QMC5883L_RESERVED 0x0c
/*
9.2 Register Definition
9.2.1 Output Data Register
Registers 00H ~ 05H store the measurement data from each axis magnetic sensor in continuous-measurement.
@ -80,7 +95,20 @@
ODR setup in control registers 1. The data stays the same, regardless of reading status through I2C, until new
data replaces them. Each axis has 16 bit data width in 2s complement, i.e., MSB of 01H/03H/05H indicates the
sign of each axis. The output data of each channel saturates at -32768 and 32767.
* Calibration :
* valid relations : 1 T = 10000 G ... 1G = 0.1mT = 100µT
* Dynamic Output Field Range ±2 or ±8 Gauss ==> ±200µT or ±800µT
* Sensitivity [1]
* Field Range = ±2G 12000 LSB/G --> factor = 120
* Field Range = ±8G 3000 LSB/G --> factor = 30
*/
#if QMC5883L_GAUSS == 0
#define QMC5883L_FACTOR 120.0f
#else
#define QMC5883L_FACTOR 30.0f
#endif
/*
Table 14. Output Data Register
Addr. 7 6 5 4 3 2 1 0
00H Data Output X LSB Register XOUT[7:0]
@ -97,8 +125,12 @@
Table 15. Status Register 1
Addr. 7 6 5 4 3 2 1 0
06H DOR OVL DRDY
06H DOR OVL DRDY
*/
#define QMC5883L_STATUS_DRDY 1
#define QMC5883L_STATUS_OVL 2
// #define QMC5883L_STATUS_DOR 4
/*
Data Ready Register (DRDY), it is set when all three axis data is ready, and loaded to the output data registers in
the continuous measurement mode. It is reset to 0 by reading any data register (00H~05H) through I2C
commends
@ -143,14 +175,20 @@
Table 18. Control Register 1
Addr 7 6 5 4 3 2 1 0
09H OSR[1:0] RNG[1:0] ODR[1:0] MODE[1:0]
09H OSR[1:0] RNG[1:0] ODR[1:0] MODE[1:0]
Reg. Definition 00 01 10 11
Mode Mode Control Standby Continuous Reserve Reserve
ODR Output Data Rate 10Hz 50Hz 100Hz 200Hz
RNG Full Scale 2G 8G Reserve Reserve
OSR Over Sample Ratio 512 256 128 64
*/
// #define QMC5883L_CONFIG_STANDBY 0b00000000
#define QMC5883L_CONFIG_CONT 0b00000001
#define QMC5883L_SHIFT_ODR 2 // for QMC5883L_FILTER
#define QMC5883L_SHIFT_RNG 4 // for QMC5883L_GAUSS
#define QMC5883L_SHIFT_OSR 6 // for QMC5883L_OVERSAMPLE
/*
Interrupt enabling is controlled by register INT_ENB in control register 2. Once the interrupt is enabled, it will flag
when new data is in Data Output Registers.
INT_ENB: 0: enable interrupt PIN, 1: disable interrupt PIN
@ -164,111 +202,50 @@
Table 19. Control Register 2
Addr. 7 6 5 4 3 2 1 0
0AH SOFT_RST ROL_PNT INT_ENB
*/
#define QMC5883L_CONFIG2_RESET 0b10000000
/*
9.2.5 SET/RESET Period Register
SET/RESET Period is controlled by FBR [7:0], it is recommended that the register 0BH is written by 0x01.
Table 20. SET/RESET Period Register
Addr. 7 6 5 4 3 2 1 0
0BH SET/RESET Perio [7:0]
*/
// Define driver ID
#define XSNS_33 33
#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 */
#define QMC5883L_ADDR 0x0D
/* Register numbers */
#define QMC5883L_X_LSB 0x00
#define QMC5883L_X_MSB 0x01
#define QMC5883L_Y_LSB 0x02
#define QMC5883L_Y_MSB 0x03
#define QMC5883L_Z_LSB 0x04
#define QMC5883L_Z_MSB 0x05
#define QMC5883L_STATUS 0x06
#define QMC5883L_TEMP_LSB 0x07
#define QMC5883L_TEMP_MSB 0x08
#define QMC5883L_CONFIG 0x09
#define QMC5883L_CONFIG2 0x0a
#define QMC5883L_RESET 0x0b // SET/RESET Period it is recommended that the register 0BH is written by 0x01.
// #define QMC5883L_RESERVED 0x0c
#define QMC5883L_CHIP_ID 0x0d
/* Bit values for the STATUS register ... #define QMC5883L_STATUS 0x06
*/
#define QMC5883L_STATUS_DRDY 1
#define QMC5883L_STATUS_OVL 2
// #define QMC5883L_STATUS_DOR 4
/* set QMC5883L_STATUS_REG ... #define QMC5883L_CONFIG 0x09
Addr 7 6 5 4 3 2 1 0
09H OSR[1:0] RNG[1:0] ODR[1:0] MODE[1:0]
Oversampling values for the CONFIG register
Reg. Definition 00 01 10 11
OSR Over Sample Ratio 512 256 128 64
#define QMC5883L_OVERSAMPLE 1 // 0 .. 3 => 512, 256, 128, 64
*/
#ifndef QMC5883L_OVERSAMPLE
#define QMC5883L_OVERSAMPLE 1
#elif (QMC5883L_OVERSAMPLE>3)
#undef QMC5883L_OVERSAMPLE
#define QMC5883L_OVERSAMPLE 3
#endif
/* Reg. Definition 00 01 10 11
RNG Full Scale 2G 8G Reserve Reserve
#define QMC5883L_GAUSS 1 // 0,1 => 2GAUSS, 8GAUSS
*/
#ifndef QMC5883L_GAUSS
#define QMC5883L_GAUSS 1
#elif (QMC5883L_GAUSS>1)
#undef QMC5883L_GAUSS
#define QMC5883L_GAUSS 1
#endif
#if QMC5883L_GAUSS == 0
#define FACTOR 120
#else
#define FACTOR 30
#endif
/* Reg. Definition 00 01 10 11
ODR Output Data Rate 10Hz 50Hz 100Hz 200Hz
#define QMC5883L_FILTER 2 // 0 .. 3 => 10HZ, 50HZ, 109HZ, 200HZ
*/
#ifndef QMC5883L_FILTER
#define QMC5883L_FILTER 2
#define QMC5883L_FILTER 0
#elif (QMC5883L_FILTER>3)
#undef QMC5883L_FILTER
#define QMC5883L_FILTER 3
#endif
/* Reg. Definition 00 01 10 11
Mode Mode Control Standby Continuous Reserve Reserve */
// #define QMC5883L_CONFIG_STANDBY 0b00000000
#define QMC5883L_CONFIG_CONT 0b00000001
/* Mode values for the CONFIG2 register = Software Reset */
#define QMC5883L_CONFIG2_RESET 0b10000000
#define REG_OVL 0x7fff
// #define OVL "overflow"
#define OVL INFINITY
#define QMC5883L_OVL INFINITY
// data field
struct QMC5883L_s {
int16_t MX, MY, MZ;
// uint16_t scalar;
float MX, MY, MZ;
float temp;
// float MX, MY, MZ, scalar;
bool ovl;
} *QMC5883L = nullptr;
@ -284,8 +261,8 @@ void QMC5883L_Init() {
Addr 7 6 5 4 3 2 1 0
09H OSR[1:0] RNG[1:0] ODR[1:0] MODE[1:0] */
AddLog(LOG_LEVEL_DEBUG,PSTR("QMC: QMC5883L_STATUS_REG 0x%X, size of buffer %d" ),
((QMC5883L_OVERSAMPLE<<6) | (QMC5883L_GAUSS<<4) | (QMC5883L_FILTER<<2) | QMC5883L_CONFIG_CONT), sizeof(struct QMC5883L_s));
if (I2cWrite8(QMC5883L_ADDR, QMC5883L_CONFIG, ((QMC5883L_OVERSAMPLE<<6) | (QMC5883L_GAUSS<<4) | (QMC5883L_FILTER<<2) | QMC5883L_CONFIG_CONT)) == false) { return; }
((QMC5883L_OVERSAMPLE<<QMC5883L_SHIFT_OSR) | (QMC5883L_GAUSS<<QMC5883L_SHIFT_RNG) | (QMC5883L_FILTER<<QMC5883L_SHIFT_ODR) | QMC5883L_CONFIG_CONT), sizeof(struct QMC5883L_s));
if (I2cWrite8(QMC5883L_ADDR, QMC5883L_CONFIG, ((QMC5883L_OVERSAMPLE<<QMC5883L_SHIFT_OSR) | (QMC5883L_GAUSS<<QMC5883L_SHIFT_RNG) | (QMC5883L_FILTER<<QMC5883L_SHIFT_ODR) | QMC5883L_CONFIG_CONT)) == false) { return; }
I2cSetActiveFound(QMC5883L_ADDR, "QMC5883L");
QMC5883L = (QMC5883L_s *)calloc(1, sizeof(struct QMC5883L_s));
@ -293,25 +270,24 @@ void QMC5883L_Init() {
//Read the magnetic data
void QMC5883L_read_data(void) {
// check if chip is ready to provide data
/* check if chip is ready to provide data
Table 15. Status Register 1
Addr. 7 6 5 4 3 2 1 0
06H DOR OVL DRDY
*/
switch (I2cRead8(QMC5883L_ADDR, QMC5883L_STATUS) & (QMC5883L_STATUS_DRDY | QMC5883L_STATUS_OVL)){
case 1:
QMC5883L->ovl = false;
QMC5883L->MX = I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_X_LSB); // Select LSB register
QMC5883L->MY = I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_Y_LSB);
QMC5883L->MZ = I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_Z_LSB);
// calculate scalar magnetic induction
// 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));
QMC5883L->MX = (float) I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_X_LSB) / QMC5883L_FACTOR; // Select LSB register
QMC5883L->MY = (float) I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_Y_LSB) / QMC5883L_FACTOR;
QMC5883L->MZ = (float) I2cReadS16_LE(QMC5883L_ADDR, QMC5883L_Z_LSB) / QMC5883L_FACTOR;
break;
case 3:
QMC5883L->ovl = true;
AddLog(LOG_LEVEL_DEBUG,PSTR("QMC: QMC5883L_STATUS_Overflow"));
QMC5883L->MX = REG_OVL;
QMC5883L->MY = REG_OVL;
QMC5883L->MZ = REG_OVL;
QMC5883L->MX = \
QMC5883L->MY = \
QMC5883L->MZ = QMC5883L_OVL;
break;
default:
return;
@ -326,36 +302,32 @@ void QMC5883L_read_data(void) {
\*********************************************************************************************/
#ifdef USE_WEBSERVER
// {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HTTP_SNS_QMC5883L[] PROGMEM =
"{s}QMC5883L " D_MX "{m}%s " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
"{s}QMC5883L " D_MY "{m}%s " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
"{s}QMC5883L " D_MZ "{m}%s " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
"{s}QMC5883L " D_MAGNETICFLD "{m}%s " D_UNIT_MICROTESLA "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
"{s}QMC5883L " D_MX "{m}%*_f " D_UNIT_MICROTESLA "{e}"
"{s}QMC5883L " D_MY "{m}%*_f " D_UNIT_MICROTESLA "{e}"
"{s}QMC5883L " D_MZ "{m}%*_f " D_UNIT_MICROTESLA "{e}"
"{s}QMC5883L " D_MAGNETICFLD "{m}%*_f " D_UNIT_MICROTESLA "{e}";
#endif
void QMC5883L_Show(uint8_t json) {
char s_mx[12] ;
char s_my[12] ;
char s_mz[12] ;
char s_scalar[12] ;
if (!QMC5883L->ovl) {
dtostrfd((float)QMC5883L->MX / FACTOR, 3, s_mx);
dtostrfd((float)QMC5883L->MY / FACTOR, 3, s_my);
dtostrfd((float)QMC5883L->MZ / FACTOR, 3, s_mz);
dtostrfd((float)(SqrtInt((QMC5883L->MX * QMC5883L->MX) + (QMC5883L->MY * QMC5883L->MY) + (QMC5883L->MZ * QMC5883L->MZ))) / FACTOR, 3, s_scalar);
}else{
dtostrfd(OVL, 3, s_mx);
dtostrfd(OVL, 3, s_my);
dtostrfd(OVL, 3, s_mz);
dtostrfd(OVL, 3, s_scalar);
// s_my = s_mz = s_scalar = s_mx;
}
void QMC5883L_Show(uint8_t json)
{
float QMC5883L_MF = (float) sqrt((QMC5883L->MX * QMC5883L->MX) + (QMC5883L->MY * QMC5883L->MY) + (QMC5883L->MZ * QMC5883L->MZ));
if (json) {
ResponseAppend_P(PSTR(",\"QMC5883L\":{\"" D_JSON_MX "\":%s,\"" D_JSON_MY "\":%s,\"" D_JSON_MZ "\":%s,\"" D_JSON_MAGNETICFLD "\":%s,\"" D_JSON_TEMPERATURE "\":%*_f}"),
s_mx, s_my, s_mz, s_scalar, Settings->flag2.temperature_resolution, &QMC5883L->temp);
ResponseAppend_P(PSTR(",\"QMC5883L\":{\"" \
D_JSON_MX "\":%*_f,\"" D_JSON_MY "\":%*_f,\"" D_JSON_MZ "\":%*_f,\"" \
D_JSON_MAGNETICFLD "\":%*_f,\"" D_JSON_TEMPERATURE "\":%*_f}"),\
QMC5883L_DECIMAL, &QMC5883L->MX, \
QMC5883L_DECIMAL, &QMC5883L->MY, \
QMC5883L_DECIMAL, &QMC5883L->MZ, \
QMC5883L_DECIMAL, &QMC5883L_MF, \
Settings->flag2.temperature_resolution, &QMC5883L->temp);
#ifdef USE_WEBSERVER
} else {
WSContentSend_PD(HTTP_SNS_QMC5883L, s_mx, s_my, s_mz, s_scalar);
WSContentSend_PD(HTTP_SNS_QMC5883L, QMC5883L_DECIMAL, &QMC5883L->MX, \
QMC5883L_DECIMAL, &QMC5883L->MY, \
QMC5883L_DECIMAL, &QMC5883L->MZ, \
QMC5883L_DECIMAL, &QMC5883L_MF);
WSContentSend_Temp("QMC5883L", QMC5883L->temp);
#endif
}
@ -396,4 +368,4 @@ bool Xsns33(uint32_t function) {
return result;
}
#endif // USE_QMC5883L
#endif // USE_I2C
#endif // USE_I2C