From 49aef654c8985d2fb614968614d8ec8cebb291c1 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Mon, 10 Nov 2025 22:43:26 +0300 Subject: [PATCH 01/16] Add files via upload --- lib/Espfc/src/Device/MagQMC5338P.h | 123 +++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 lib/Espfc/src/Device/MagQMC5338P.h diff --git a/lib/Espfc/src/Device/MagQMC5338P.h b/lib/Espfc/src/Device/MagQMC5338P.h new file mode 100644 index 00000000..89c41257 --- /dev/null +++ b/lib/Espfc/src/Device/MagQMC5338P.h @@ -0,0 +1,123 @@ +#ifndef _ESPFC_DEVICE_MAG_QMC5338P_H_ +#define _ESPFC_DEVICE_MAG_QMC5338P_H_ + +#include "MagDevice.h" +#include "BusDevice.h" + +// العنوان الصحيح لـ QMC5883P +#define QMC5883P_ADDRESS 0x2C +#define QMC5883P_DEFAULT_ADDRESS 0x2C + +// سجلات QMC5883P حسب مواصفات Adafruit +#define QMC5883P_REG_CHIPID 0x00 +#define QMC5883P_REG_XOUT_LSB 0x01 +#define QMC5883P_REG_XOUT_MSB 0x02 +#define QMC5883P_REG_YOUT_LSB 0x03 +#define QMC5883P_REG_YOUT_MSB 0x04 +#define QMC5883P_REG_ZOUT_LSB 0x05 +#define QMC5883P_REG_ZOUT_MSB 0x06 +#define QMC5883P_REG_STATUS 0x09 +#define QMC5883P_REG_CONTROL1 0x0A +#define QMC5883P_REG_CONTROL2 0x0B + +// Range values (as defined in Adafruit lib) +#define QMC5883P_RANGE_30G 0x00 +#define QMC5883P_RANGE_12G 0x01 +#define QMC5883P_RANGE_8G 0x02 +#define QMC5883P_RANGE_2G 0x03 + +// Mode values +#define QMC5883P_MODE_CONTINUOUS 0x03 // Continuous measurement mode + +namespace Espfc { +namespace Device { + +class MagQMC5338P : public MagDevice +{ +public: + int begin(BusDevice* bus) override + { + return begin(bus, QMC5883P_DEFAULT_ADDRESS); + } + + int begin(BusDevice* bus, uint8_t addr) override { + setBus(bus, addr); + + if (!testConnection()) return 0; + + // نستخدم ±8G (0x02) كنطاق افتراضي للدرون + _currentRange = QMC5883P_RANGE_8G; + setMode(_currentRange); + + // وضع التشغيل المستمر + uint8_t ctrl1 = (QMC5883P_MODE_CONTINUOUS) | // bits [1:0] + (0x02 << 2) | // ODR = 100Hz (0x02) + (0x03 << 4) | // OSR = 1 (0x03) ← أسرع + (0x00 << 6); // DSR = 1 + _bus->writeByte(_addr, QMC5883P_REG_CONTROL1, ctrl1); + + // قراءة أولية + uint8_t buffer[6]; + _bus->read(_addr, QMC5883P_REG_XOUT_LSB, 6, buffer); + + return 1; + } + + int readMag(VectorInt16& v) override { + uint8_t buffer[6]; + if (_bus->read(_addr, QMC5883P_REG_XOUT_LSB, 6, buffer) != 6) { + return 0; + } + + // في QMC5883P: X = [MSB=0x02, LSB=0x01] → buffer[1], buffer[0] + v.x = (int16_t)((buffer[1] << 8) | buffer[0]); + v.y = (int16_t)((buffer[3] << 8) | buffer[2]); + v.z = (int16_t)((buffer[5] << 8) | buffer[4]); + + return 1; + } + + const VectorFloat convert(const VectorInt16& v) const override { + float lsb_per_gauss; + switch (_currentRange) { + case QMC5883P_RANGE_30G: lsb_per_gauss = 1000.0f; break; + case QMC5883P_RANGE_12G: lsb_per_gauss = 2500.0f; break; + case QMC5883P_RANGE_8G: lsb_per_gauss = 3750.0f; break; + case QMC5883P_RANGE_2G: lsb_per_gauss = 15000.0f; break; + default: lsb_per_gauss = 3750.0f; // fallback to 8G + } + float scale = 1.0f / lsb_per_gauss; + return VectorFloat{ v.x * scale, v.y * scale, v.z * scale }; + } + + int getRate() const override { + return 100; // بناءً على ODR = 100Hz + } + + virtual MagDeviceType getType() const override { + return MAG_QMC5883P; + } + + void setMode(uint8_t range) { + _currentRange = range; + // اضبط البتات [3:2] في CONTROL2 + uint8_t ctrl2 = (range << 2); + _bus->writeByte(_addr, QMC5883P_REG_CONTROL2, ctrl2); + } + + bool testConnection() override { + uint8_t chip_id; + if (_bus->read(_addr, QMC5883P_REG_CHIPID, 1, &chip_id) != 1) { + return false; + } + return chip_id == 0x80; // كما في مكتبة Adafruit + } + +private: + uint8_t _currentRange = QMC5883P_RANGE_8G; +}; + +} // namespace Device +} // namespace Espfc + +#endif \ No newline at end of file From 07ea954abe53e15c3defe82c3eaa4e057b45115b Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Mon, 10 Nov 2025 22:50:04 +0300 Subject: [PATCH 02/16] Add 'QMC5883P' to device choices in MagDevice --- lib/Espfc/src/Device/BusDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Espfc/src/Device/BusDevice.cpp b/lib/Espfc/src/Device/BusDevice.cpp index a9ca598d..9de3720d 100644 --- a/lib/Espfc/src/Device/BusDevice.cpp +++ b/lib/Espfc/src/Device/BusDevice.cpp @@ -6,7 +6,7 @@ namespace Espfc::Device { const char ** BusDevice::getNames() { - static const char* busDevChoices[] = { PSTR("NONE"), PSTR("AUTO"), PSTR("I2C"), PSTR("SPI"), PSTR("SLV"), NULL }; + static const char* devChoices[] = { PSTR("AUTO"), PSTR("NONE"), PSTR("HMC5883L"), PSTR("AK8975"), PSTR("AK8963"), PSTR("QMC5883L"), PSTR("QMC5883P"),NULL }; return busDevChoices; } From 43a758a92b3e9a95d5536ff2ba6f846ff2e0ac39 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Mon, 10 Nov 2025 22:50:48 +0300 Subject: [PATCH 03/16] Add MAG_QMC5883P to MagDevice.h enum --- lib/Espfc/src/Device/MagDevice.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Espfc/src/Device/MagDevice.h b/lib/Espfc/src/Device/MagDevice.h index 6bb5823b..2ca993c7 100644 --- a/lib/Espfc/src/Device/MagDevice.h +++ b/lib/Espfc/src/Device/MagDevice.h @@ -12,6 +12,7 @@ enum MagDeviceType { MAG_AK8975 = 3, MAG_AK8963 = 4, MAG_QMC5883 = 5, + MAG_QMC5883P= 6, MAG_MAX }; From 1eb193140f7353a3eb664ca317a1a6fece449a9c Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Mon, 10 Nov 2025 22:53:01 +0300 Subject: [PATCH 04/16] Add support for MagQMC5338P device detection --- lib/Espfc/src/Hardware.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Espfc/src/Hardware.cpp b/lib/Espfc/src/Hardware.cpp index 6c37292a..17e728e9 100644 --- a/lib/Espfc/src/Hardware.cpp +++ b/lib/Espfc/src/Hardware.cpp @@ -8,6 +8,7 @@ #include "Device/GyroBMI160.h" #include "Device/MagHMC5338L.h" #include "Device/MagQMC5338L.h" +#include "device/MagQMC5338P.h" #include "Device/MagAK8963.h" #include "Device/BaroDevice.h" #include "Device/BaroBMP085.h" @@ -40,6 +41,7 @@ namespace { static Espfc::Device::GyroBMI160 bmi160; static Espfc::Device::MagHMC5338L hmc5883l; static Espfc::Device::MagQMC5338L qmc5883l; + static Espfc::Device::MagQMC5338P qmc5883p; static Espfc::Device::MagAK8963 ak8963; static Espfc::Device::BaroBMP085 bmp085; static Espfc::Device::BaroBMP280 bmp280; @@ -128,6 +130,7 @@ void Hardware::detectMag() if(!detectedMag && detectDevice(ak8963, i2cBus)) detectedMag = &ak8963; if(!detectedMag && detectDevice(hmc5883l, i2cBus)) detectedMag = &hmc5883l; if(!detectedMag && detectDevice(qmc5883l, i2cBus)) detectedMag = &qmc5883l; + if(!detectedMag && detectDevice(qmc5883p, i2cBus)) detectedMag = &qmc5883p; } #endif if(gyroSlaveBus.getBus()) @@ -135,6 +138,7 @@ void Hardware::detectMag() if(!detectedMag && detectDevice(ak8963, gyroSlaveBus)) detectedMag = &ak8963; if(!detectedMag && detectDevice(hmc5883l, gyroSlaveBus)) detectedMag = &hmc5883l; if(!detectedMag && detectDevice(qmc5883l, gyroSlaveBus)) detectedMag = &qmc5883l; + if(!detectedMag && detectDevice(qmc5883p, gyroSlaveBus)) detectedMag = &qmc5883p; } _model.state.mag.dev = detectedMag; From 0505cd49da67b0ae31d4499dc29ab0439fdd69d7 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Mon, 10 Nov 2025 22:53:54 +0300 Subject: [PATCH 05/16] Add QMC5883P to supported magnetometers list --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c7a22336..f6689941 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ After flashing you need to configure few things first: * Gyro: MPU6050, MPU6000, MPU6500, MPU9250, ICM20602, BMI160 * Barometers: BMP180, BMP280, SPL06 - * Magnetometers: HMC5883, QMC5883, AK8963 + * Magnetometers: HMC5883, QMC5883, AK8963, QMC5883P * Receivers: PPM, SBUS, IBUS, CRSF/ELRS * Esc Protocols: PWM, BRUSHED, ONESHOT125, ONESHOT42, MULTISHOT, DSHOT150, DSHOT300, DSHOT600 * Other protocols: MSP, CLI, BLACKBOX, ESPNOW From 8d0e72123be8d7c2479a0b22e27fa0713ee1cb50 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Tue, 11 Nov 2025 13:58:52 +0300 Subject: [PATCH 06/16] Update MagDevice.cpp --- lib/Espfc/src/Device/MagDevice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Espfc/src/Device/MagDevice.cpp b/lib/Espfc/src/Device/MagDevice.cpp index 63a20384..9ade20b6 100644 --- a/lib/Espfc/src/Device/MagDevice.cpp +++ b/lib/Espfc/src/Device/MagDevice.cpp @@ -6,7 +6,7 @@ namespace Espfc::Device { const char ** MagDevice::getNames() { - static const char* devChoices[] = { PSTR("AUTO"), PSTR("NONE"), PSTR("HMC5883L"), PSTR("AK8975"), PSTR("AK8963"), PSTR("QMC5883L"),NULL }; + static const char* devChoices[] = { PSTR("AUTO"), PSTR("NONE"), PSTR("HMC5883L"), PSTR("AK8975"), PSTR("AK8963"), PSTR("QMC5883L"),PSTR("QMC5883P"),NULL }; return devChoices; } @@ -16,4 +16,4 @@ const char * MagDevice::getName(DeviceType type) return getNames()[type]; } -} \ No newline at end of file +} From a0dd25c742248d924e8023a6b4f562b22a220d27 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Tue, 11 Nov 2025 14:01:54 +0300 Subject: [PATCH 07/16] BusDevice.cpp --- lib/Espfc/src/Device/BusDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Espfc/src/Device/BusDevice.cpp b/lib/Espfc/src/Device/BusDevice.cpp index 9de3720d..a9ca598d 100644 --- a/lib/Espfc/src/Device/BusDevice.cpp +++ b/lib/Espfc/src/Device/BusDevice.cpp @@ -6,7 +6,7 @@ namespace Espfc::Device { const char ** BusDevice::getNames() { - static const char* devChoices[] = { PSTR("AUTO"), PSTR("NONE"), PSTR("HMC5883L"), PSTR("AK8975"), PSTR("AK8963"), PSTR("QMC5883L"), PSTR("QMC5883P"),NULL }; + static const char* busDevChoices[] = { PSTR("NONE"), PSTR("AUTO"), PSTR("I2C"), PSTR("SPI"), PSTR("SLV"), NULL }; return busDevChoices; } From 96c18e866ff02f80456401db7cc677c611c6dc39 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Tue, 11 Nov 2025 14:07:38 +0300 Subject: [PATCH 08/16] Update MagQMC5338P.h --- lib/Espfc/src/Device/MagQMC5338P.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/Espfc/src/Device/MagQMC5338P.h b/lib/Espfc/src/Device/MagQMC5338P.h index 89c41257..a6ef86e2 100644 --- a/lib/Espfc/src/Device/MagQMC5338P.h +++ b/lib/Espfc/src/Device/MagQMC5338P.h @@ -4,11 +4,11 @@ #include "MagDevice.h" #include "BusDevice.h" -// العنوان الصحيح لـ QMC5883P +// address for QMC5883P #define QMC5883P_ADDRESS 0x2C #define QMC5883P_DEFAULT_ADDRESS 0x2C -// سجلات QMC5883P حسب مواصفات Adafruit +// QMC5883P records according to Adafruit specifications #define QMC5883P_REG_CHIPID 0x00 #define QMC5883P_REG_XOUT_LSB 0x01 #define QMC5883P_REG_XOUT_MSB 0x02 @@ -45,18 +45,18 @@ class MagQMC5338P : public MagDevice if (!testConnection()) return 0; - // نستخدم ±8G (0x02) كنطاق افتراضي للدرون + // We use ±8G (0x02) as the default range for the drone. _currentRange = QMC5883P_RANGE_8G; setMode(_currentRange); - // وضع التشغيل المستمر + // Continuous operating mode uint8_t ctrl1 = (QMC5883P_MODE_CONTINUOUS) | // bits [1:0] (0x02 << 2) | // ODR = 100Hz (0x02) - (0x03 << 4) | // OSR = 1 (0x03) ← أسرع + (0x03 << 4) | // OSR = 1 (0x03) ← faster (0x00 << 6); // DSR = 1 _bus->writeByte(_addr, QMC5883P_REG_CONTROL1, ctrl1); - // قراءة أولية + // Initial reading uint8_t buffer[6]; _bus->read(_addr, QMC5883P_REG_XOUT_LSB, 6, buffer); @@ -69,7 +69,7 @@ class MagQMC5338P : public MagDevice return 0; } - // في QMC5883P: X = [MSB=0x02, LSB=0x01] → buffer[1], buffer[0] + // in QMC5883P: X = [MSB=0x02, LSB=0x01] → buffer[1], buffer[0] v.x = (int16_t)((buffer[1] << 8) | buffer[0]); v.y = (int16_t)((buffer[3] << 8) | buffer[2]); v.z = (int16_t)((buffer[5] << 8) | buffer[4]); @@ -91,7 +91,7 @@ class MagQMC5338P : public MagDevice } int getRate() const override { - return 100; // بناءً على ODR = 100Hz + return 100; // Based on ODR = 100Hz } virtual MagDeviceType getType() const override { @@ -100,7 +100,7 @@ class MagQMC5338P : public MagDevice void setMode(uint8_t range) { _currentRange = range; - // اضبط البتات [3:2] في CONTROL2 + // Set the bits to [3:2] in CONTROL2 uint8_t ctrl2 = (range << 2); _bus->writeByte(_addr, QMC5883P_REG_CONTROL2, ctrl2); } @@ -110,14 +110,14 @@ class MagQMC5338P : public MagDevice if (_bus->read(_addr, QMC5883P_REG_CHIPID, 1, &chip_id) != 1) { return false; } - return chip_id == 0x80; // كما في مكتبة Adafruit + return chip_id == 0x80; } private: uint8_t _currentRange = QMC5883P_RANGE_8G; }; -} // namespace Device -} // namespace Espfc +} +} -#endif \ No newline at end of file +#endif From 7d77190b27a2f4eacc208a005f2db95d3bb74e47 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Tue, 11 Nov 2025 14:13:58 +0300 Subject: [PATCH 09/16] Update Hardware.cpp --- lib/Espfc/src/Hardware.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Espfc/src/Hardware.cpp b/lib/Espfc/src/Hardware.cpp index 17e728e9..f765426d 100644 --- a/lib/Espfc/src/Hardware.cpp +++ b/lib/Espfc/src/Hardware.cpp @@ -8,7 +8,7 @@ #include "Device/GyroBMI160.h" #include "Device/MagHMC5338L.h" #include "Device/MagQMC5338L.h" -#include "device/MagQMC5338P.h" +#include "Device/MagQMC5338P.h" #include "Device/MagAK8963.h" #include "Device/BaroDevice.h" #include "Device/BaroBMP085.h" From a2247f22bbff8bb366d14c154c1d61c07f5519b8 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Wed, 10 Dec 2025 19:56:50 +0300 Subject: [PATCH 10/16] Update MagQMC5338P.h Enable Set/Reset (write 0x29 to Z_MSB) --- lib/Espfc/src/Device/MagQMC5338P.h | 52 ++++++++++++++++-------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/lib/Espfc/src/Device/MagQMC5338P.h b/lib/Espfc/src/Device/MagQMC5338P.h index a6ef86e2..f754485d 100644 --- a/lib/Espfc/src/Device/MagQMC5338P.h +++ b/lib/Espfc/src/Device/MagQMC5338P.h @@ -1,14 +1,12 @@ -#ifndef _ESPFC_DEVICE_MAG_QMC5338P_H_ -#define _ESPFC_DEVICE_MAG_QMC5338P_H_ +#ifndef _ESPFC_DEVICE_MAG_QMC5883P_H_ +#define _ESPFC_DEVICE_MAG_QMC5883P_H_ #include "MagDevice.h" #include "BusDevice.h" -// address for QMC5883P #define QMC5883P_ADDRESS 0x2C #define QMC5883P_DEFAULT_ADDRESS 0x2C -// QMC5883P records according to Adafruit specifications #define QMC5883P_REG_CHIPID 0x00 #define QMC5883P_REG_XOUT_LSB 0x01 #define QMC5883P_REG_XOUT_MSB 0x02 @@ -20,19 +18,17 @@ #define QMC5883P_REG_CONTROL1 0x0A #define QMC5883P_REG_CONTROL2 0x0B -// Range values (as defined in Adafruit lib) #define QMC5883P_RANGE_30G 0x00 #define QMC5883P_RANGE_12G 0x01 #define QMC5883P_RANGE_8G 0x02 #define QMC5883P_RANGE_2G 0x03 -// Mode values -#define QMC5883P_MODE_CONTINUOUS 0x03 // Continuous measurement mode +#define QMC5883P_MODE_CONTINUOUS 0x03 namespace Espfc { namespace Device { -class MagQMC5338P : public MagDevice +class MagQMC5883P : public MagDevice { public: int begin(BusDevice* bus) override @@ -45,18 +41,22 @@ class MagQMC5338P : public MagDevice if (!testConnection()) return 0; - // We use ±8G (0x02) as the default range for the drone. - _currentRange = QMC5883P_RANGE_8G; - setMode(_currentRange); + // 🔑 Step 1: Enable Set/Reset (write 0x29 to Z_MSB) + _bus->writeByte(_addr, QMC5883P_REG_ZOUT_MSB, 0x29); - // Continuous operating mode - uint8_t ctrl1 = (QMC5883P_MODE_CONTINUOUS) | // bits [1:0] - (0x02 << 2) | // ODR = 100Hz (0x02) - (0x03 << 4) | // OSR = 1 (0x03) ← faster - (0x00 << 6); // DSR = 1 + // 🔑 Step 2: Set Range in CONTROL2[3:2] (Adafruit style) + _currentRange = QMC5883P_RANGE_8G; + setMode(_currentRange); // This will write to CONTROL2 + + // 🔑 Step 3: Configure CONTROL1 + uint8_t ctrl1 = + QMC5883P_MODE_CONTINUOUS | // [1:0] + (0x02 << 2) | // ODR = 100Hz [3:2] + (0x03 << 4) | // OSR = 1 [5:4] + (0x00 << 6); // DSR = 1 [7:6] _bus->writeByte(_addr, QMC5883P_REG_CONTROL1, ctrl1); - // Initial reading + // Initial read uint8_t buffer[6]; _bus->read(_addr, QMC5883P_REG_XOUT_LSB, 6, buffer); @@ -69,7 +69,7 @@ class MagQMC5338P : public MagDevice return 0; } - // in QMC5883P: X = [MSB=0x02, LSB=0x01] → buffer[1], buffer[0] + // 🔑 Read raw values EXACTLY like Adafruit (no sign flip yet) v.x = (int16_t)((buffer[1] << 8) | buffer[0]); v.y = (int16_t)((buffer[3] << 8) | buffer[2]); v.z = (int16_t)((buffer[5] << 8) | buffer[4]); @@ -78,29 +78,31 @@ class MagQMC5338P : public MagDevice } const VectorFloat convert(const VectorInt16& v) const override { + // 🔑 Use Adafruit's conversion factors (based on actual range) float lsb_per_gauss; switch (_currentRange) { - case QMC5883P_RANGE_30G: lsb_per_gauss = 1000.0f; break; - case QMC5883P_RANGE_12G: lsb_per_gauss = 2500.0f; break; - case QMC5883P_RANGE_8G: lsb_per_gauss = 3750.0f; break; - case QMC5883P_RANGE_2G: lsb_per_gauss = 15000.0f; break; - default: lsb_per_gauss = 3750.0f; // fallback to 8G + case QMC5883P_RANGE_30G: lsb_per_gauss = 1000.0f; break; + case QMC5883P_RANGE_12G: lsb_per_gauss = 2500.0f; break; + case QMC5883P_RANGE_8G: lsb_per_gauss = 3750.0f; break; + case QMC5883P_RANGE_2G: lsb_per_gauss = 15000.0f; break; + default: lsb_per_gauss = 3750.0f; } float scale = 1.0f / lsb_per_gauss; return VectorFloat{ v.x * scale, v.y * scale, v.z * scale }; } int getRate() const override { - return 100; // Based on ODR = 100Hz + return 100; } virtual MagDeviceType getType() const override { return MAG_QMC5883P; } + // 🔑 CORRECT setMode: writes range to CONTROL2[3:2] void setMode(uint8_t range) { _currentRange = range; - // Set the bits to [3:2] in CONTROL2 + // Range is in bits [3:2] of CONTROL2 uint8_t ctrl2 = (range << 2); _bus->writeByte(_addr, QMC5883P_REG_CONTROL2, ctrl2); } From 32501f810f69a04f3dd781e899eb0d71691dc005 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Sat, 27 Dec 2025 22:06:12 +0300 Subject: [PATCH 11/16] Update MagQMC5338P.h --- lib/Espfc/src/Device/MagQMC5338P.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Espfc/src/Device/MagQMC5338P.h b/lib/Espfc/src/Device/MagQMC5338P.h index f754485d..f0391694 100644 --- a/lib/Espfc/src/Device/MagQMC5338P.h +++ b/lib/Espfc/src/Device/MagQMC5338P.h @@ -1,5 +1,5 @@ -#ifndef _ESPFC_DEVICE_MAG_QMC5883P_H_ -#define _ESPFC_DEVICE_MAG_QMC5883P_H_ +#ifndef _ESPFC_DEVICE_MAG_QMC5338P_H_ +#define _ESPFC_DEVICE_MAG_QMC5338P_H_ #include "MagDevice.h" #include "BusDevice.h" @@ -123,3 +123,4 @@ class MagQMC5883P : public MagDevice } #endif + From 7c6abd54e6875e7318c4c036eb94ebe262f9197e Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Sat, 27 Dec 2025 22:10:47 +0300 Subject: [PATCH 12/16] Update MagQMC5338L.h --- lib/Espfc/src/Device/MagQMC5338L.h | 175 ++++++++++++++--------------- 1 file changed, 85 insertions(+), 90 deletions(-) diff --git a/lib/Espfc/src/Device/MagQMC5338L.h b/lib/Espfc/src/Device/MagQMC5338L.h index f2873b26..1b18253f 100644 --- a/lib/Espfc/src/Device/MagQMC5338L.h +++ b/lib/Espfc/src/Device/MagQMC5338L.h @@ -1,130 +1,125 @@ -#ifndef _ESPFC_DEVICE_MAG_QMC5338L_H_ -#define _ESPFC_DEVICE_MAG_QMC5338L_H_ +#ifndef _ESPFC_DEVICE_MAG_QMC5338P_H_ +#define _ESPFC_DEVICE_MAG_QMC5338P_H_ #include "MagDevice.h" #include "BusDevice.h" -#define QMC5883L_ADDRESS 0x0D // this device only has one address -#define QMC5883L_DEFAULT_ADDRESS 0x0D +#define QMC5883P_ADDRESS 0x2C +#define QMC5883P_DEFAULT_ADDRESS 0x2C -#define QMC5883L_RA_CONFIG_A 0x09 -#define QMC5883L_RA_CONFIG_B 0x0A -#define QMC5883L_RA_MODE 0x09 +#define QMC5883P_REG_CHIPID 0x00 +#define QMC5883P_REG_XOUT_LSB 0x01 +#define QMC5883P_REG_XOUT_MSB 0x02 +#define QMC5883P_REG_YOUT_LSB 0x03 +#define QMC5883P_REG_YOUT_MSB 0x04 +#define QMC5883P_REG_ZOUT_LSB 0x05 +#define QMC5883P_REG_ZOUT_MSB 0x06 +#define QMC5883P_REG_STATUS 0x09 +#define QMC5883P_REG_CONTROL1 0x0A +#define QMC5883P_REG_CONTROL2 0x0B -#define QMC5883L_RA_STATUS 0x06 - -#define QMC5883L_RA_DATAX_H 0x01 -#define QMC5883L_RA_DATAX_L 0x00 -#define QMC5883L_RA_DATAZ_H 0x05 -#define QMC5883L_RA_DATAZ_L 0x04 -#define QMC5883L_RA_DATAY_H 0x03 -#define QMC5883L_RA_DATAY_L 0x02 - -#define QMC5883L_RA_TEMP_L 0x07 -#define QMC5883L_RA_TEMP_H 0x08 - -#define QMC5883L_RA_RST_TIME 0x0B -#define QMC5883L_RA_RSV 0x0C -#define QMC5883L_RA_CHIPID 0x0D - -#define QMC5883L_RATE_10 0x00 -#define QMC5883L_RATE_50 0x01 -#define QMC5883L_RATE_100 0x02 -#define QMC5883L_RATE_200 0x03 - -#define QMC5883L_RANGE_2G 0x00 -#define QMC5883L_RANGE_8G 0x01 - -#define QMC5883L_OSR_512 0x00 -#define QMC5883L_OSR_256 0x01 -#define QMC5883L_OSR_128 0x02 -#define QMC5883L_OSR_64 0x03 - -#define QMC5883L_MODE_CONTINUOUS 0x01 -#define QMC5883L_MODE_IDLE 0x00 - -#define QMC5883L_STATUS_LOCK_BIT 1 -#define QMC5883L_STATUS_READY_BIT 0 +#define QMC5883P_RANGE_30G 0x00 +#define QMC5883P_RANGE_12G 0x01 +#define QMC5883P_RANGE_8G 0x02 +#define QMC5883P_RANGE_2G 0x03 +#define QMC5883P_MODE_CONTINUOUS 0x03 namespace Espfc { - namespace Device { -class MagQMC5338L: public MagDevice +class MagQMC5338P : public MagDevice { - public: - int begin(BusDevice * bus) override +public: + int begin(BusDevice* bus) override { - return begin(bus, QMC5883L_DEFAULT_ADDRESS); + return begin(bus, QMC5883P_DEFAULT_ADDRESS); } - int begin(BusDevice * bus, uint8_t addr) override - { - setBus(bus, addr); + int begin(BusDevice* bus, uint8_t addr) override { + setBus(bus, addr); - if(!testConnection()) return 0; + if (!testConnection()) return 0; - setMode(QMC5883L_OSR_64, QMC5883L_RANGE_2G, QMC5883L_RATE_100, QMC5883L_MODE_CONTINUOUS); + // 🔑 Step 1: Enable Set/Reset (write 0x29 to Z_MSB) + _bus->writeByte(_addr, QMC5883P_REG_ZOUT_MSB, 0x29); - uint8_t buffer[6]; - _bus->read(_addr, QMC5883L_RA_DATAX_H, 6, buffer); + // 🔑 Step 2: Set Range in CONTROL2[3:2] (Adafruit style) + _currentRange = QMC5883P_RANGE_8G; + setMode(_currentRange); // This will write to CONTROL2 - return 1; - } + // 🔑 Step 3: Configure CONTROL1 + uint8_t ctrl1 = + QMC5883P_MODE_CONTINUOUS | // [1:0] + (0x02 << 2) | // ODR = 100Hz [3:2] + (0x03 << 4) | // OSR = 1 [5:4] + (0x00 << 6); // DSR = 1 [7:6] + _bus->writeByte(_addr, QMC5883P_REG_CONTROL1, ctrl1); - int readMag(VectorInt16& v) override - { - uint8_t buffer[6]; - _bus->readFast(_addr, QMC5883L_RA_DATAX_L, 6, buffer); + // Initial read + uint8_t buffer[6]; + _bus->read(_addr, QMC5883P_REG_XOUT_LSB, 6, buffer); - v.x = (((int16_t)buffer[1]) << 8) | buffer[0]; + return 1; + } - v.y = (((int16_t)buffer[3]) << 8) | buffer[2]; + int readMag(VectorInt16& v) override { + uint8_t buffer[6]; + if (_bus->read(_addr, QMC5883P_REG_XOUT_LSB, 6, buffer) != 6) { + return 0; + } - v.z = (((int16_t)buffer[5]) << 8) | buffer[4]; + // 🔑 Read raw values EXACTLY like Adafruit (no sign flip yet) + v.x = (int16_t)((buffer[1] << 8) | buffer[0]); + v.y = (int16_t)((buffer[3] << 8) | buffer[2]); + v.z = (int16_t)((buffer[5] << 8) | buffer[4]); - return 1; + return 1; } - const VectorFloat convert(const VectorInt16& v) const override - { - const float scale = 1.f / 1090.f; - return VectorFloat{v} * scale; + const VectorFloat convert(const VectorInt16& v) const override { + // 🔑 Use Adafruit's conversion factors (based on actual range) + float lsb_per_gauss; + switch (_currentRange) { + case QMC5883P_RANGE_30G: lsb_per_gauss = 1000.0f; break; + case QMC5883P_RANGE_12G: lsb_per_gauss = 2500.0f; break; + case QMC5883P_RANGE_8G: lsb_per_gauss = 3750.0f; break; + case QMC5883P_RANGE_2G: lsb_per_gauss = 15000.0f; break; + default: lsb_per_gauss = 3750.0f; + } + float scale = 1.0f / lsb_per_gauss; + return VectorFloat{ v.x * scale, v.y * scale, v.z * scale }; } - int getRate() const override - { - return 75; + int getRate() const override { + return 100; } - virtual MagDeviceType getType() const override - { - return MAG_QMC5883; + virtual MagDeviceType getType() const override { + return MAG_QMC5883P; } - void setMode(uint8_t osr, uint8_t rng, uint8_t odr, uint8_t mode) - { - _mode = (osr << 6) | (rng << 4) | (odr << 2) | (mode); - uint8_t res = _bus->writeByte(_addr, QMC5883L_RA_MODE, ((osr << 6) | (rng << 4) | (odr << 2) | (mode))); - - (void)res; + // 🔑 CORRECT setMode: writes range to CONTROL2[3:2] + void setMode(uint8_t range) { + _currentRange = range; + // Range is in bits [3:2] of CONTROL2 + uint8_t ctrl2 = (range << 2); + _bus->writeByte(_addr, QMC5883P_REG_CONTROL2, ctrl2); } - bool testConnection() override - { - uint8_t buffer[3] = { 0, 0, 0 }; - uint8_t len = _bus->read(_addr, QMC5883L_RA_CHIPID, 1, buffer); - - return len == 1 && buffer[0] == 0xFF; + bool testConnection() override { + uint8_t chip_id; + if (_bus->read(_addr, QMC5883P_REG_CHIPID, 1, &chip_id) != 1) { + return false; + } + return chip_id == 0x80; } - private: - uint8_t _mode; +private: + uint8_t _currentRange = QMC5883P_RANGE_8G; }; -} - -} +} +} #endif From acc7ef9fc52eada8c8cc9c794ab4e8683bb3d3a0 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Sat, 27 Dec 2025 22:33:32 +0300 Subject: [PATCH 13/16] Update Hardware.cpp From d90cadae0a07cb5f78ecd9aaf59e6eb4eb7fb51a Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Sat, 27 Dec 2025 22:35:44 +0300 Subject: [PATCH 14/16] Update MagQMC5338L.h --- lib/Espfc/src/Device/MagQMC5338L.h | 175 +++++++++++++++-------------- 1 file changed, 90 insertions(+), 85 deletions(-) diff --git a/lib/Espfc/src/Device/MagQMC5338L.h b/lib/Espfc/src/Device/MagQMC5338L.h index 1b18253f..f2873b26 100644 --- a/lib/Espfc/src/Device/MagQMC5338L.h +++ b/lib/Espfc/src/Device/MagQMC5338L.h @@ -1,125 +1,130 @@ -#ifndef _ESPFC_DEVICE_MAG_QMC5338P_H_ -#define _ESPFC_DEVICE_MAG_QMC5338P_H_ +#ifndef _ESPFC_DEVICE_MAG_QMC5338L_H_ +#define _ESPFC_DEVICE_MAG_QMC5338L_H_ #include "MagDevice.h" #include "BusDevice.h" -#define QMC5883P_ADDRESS 0x2C -#define QMC5883P_DEFAULT_ADDRESS 0x2C +#define QMC5883L_ADDRESS 0x0D // this device only has one address +#define QMC5883L_DEFAULT_ADDRESS 0x0D -#define QMC5883P_REG_CHIPID 0x00 -#define QMC5883P_REG_XOUT_LSB 0x01 -#define QMC5883P_REG_XOUT_MSB 0x02 -#define QMC5883P_REG_YOUT_LSB 0x03 -#define QMC5883P_REG_YOUT_MSB 0x04 -#define QMC5883P_REG_ZOUT_LSB 0x05 -#define QMC5883P_REG_ZOUT_MSB 0x06 -#define QMC5883P_REG_STATUS 0x09 -#define QMC5883P_REG_CONTROL1 0x0A -#define QMC5883P_REG_CONTROL2 0x0B +#define QMC5883L_RA_CONFIG_A 0x09 +#define QMC5883L_RA_CONFIG_B 0x0A +#define QMC5883L_RA_MODE 0x09 -#define QMC5883P_RANGE_30G 0x00 -#define QMC5883P_RANGE_12G 0x01 -#define QMC5883P_RANGE_8G 0x02 -#define QMC5883P_RANGE_2G 0x03 +#define QMC5883L_RA_STATUS 0x06 + +#define QMC5883L_RA_DATAX_H 0x01 +#define QMC5883L_RA_DATAX_L 0x00 +#define QMC5883L_RA_DATAZ_H 0x05 +#define QMC5883L_RA_DATAZ_L 0x04 +#define QMC5883L_RA_DATAY_H 0x03 +#define QMC5883L_RA_DATAY_L 0x02 + +#define QMC5883L_RA_TEMP_L 0x07 +#define QMC5883L_RA_TEMP_H 0x08 + +#define QMC5883L_RA_RST_TIME 0x0B +#define QMC5883L_RA_RSV 0x0C +#define QMC5883L_RA_CHIPID 0x0D + +#define QMC5883L_RATE_10 0x00 +#define QMC5883L_RATE_50 0x01 +#define QMC5883L_RATE_100 0x02 +#define QMC5883L_RATE_200 0x03 + +#define QMC5883L_RANGE_2G 0x00 +#define QMC5883L_RANGE_8G 0x01 + +#define QMC5883L_OSR_512 0x00 +#define QMC5883L_OSR_256 0x01 +#define QMC5883L_OSR_128 0x02 +#define QMC5883L_OSR_64 0x03 + +#define QMC5883L_MODE_CONTINUOUS 0x01 +#define QMC5883L_MODE_IDLE 0x00 + +#define QMC5883L_STATUS_LOCK_BIT 1 +#define QMC5883L_STATUS_READY_BIT 0 -#define QMC5883P_MODE_CONTINUOUS 0x03 namespace Espfc { + namespace Device { -class MagQMC5338P : public MagDevice +class MagQMC5338L: public MagDevice { -public: - int begin(BusDevice* bus) override + public: + int begin(BusDevice * bus) override { - return begin(bus, QMC5883P_DEFAULT_ADDRESS); + return begin(bus, QMC5883L_DEFAULT_ADDRESS); } - int begin(BusDevice* bus, uint8_t addr) override { - setBus(bus, addr); + int begin(BusDevice * bus, uint8_t addr) override + { + setBus(bus, addr); - if (!testConnection()) return 0; + if(!testConnection()) return 0; - // 🔑 Step 1: Enable Set/Reset (write 0x29 to Z_MSB) - _bus->writeByte(_addr, QMC5883P_REG_ZOUT_MSB, 0x29); + setMode(QMC5883L_OSR_64, QMC5883L_RANGE_2G, QMC5883L_RATE_100, QMC5883L_MODE_CONTINUOUS); - // 🔑 Step 2: Set Range in CONTROL2[3:2] (Adafruit style) - _currentRange = QMC5883P_RANGE_8G; - setMode(_currentRange); // This will write to CONTROL2 + uint8_t buffer[6]; + _bus->read(_addr, QMC5883L_RA_DATAX_H, 6, buffer); - // 🔑 Step 3: Configure CONTROL1 - uint8_t ctrl1 = - QMC5883P_MODE_CONTINUOUS | // [1:0] - (0x02 << 2) | // ODR = 100Hz [3:2] - (0x03 << 4) | // OSR = 1 [5:4] - (0x00 << 6); // DSR = 1 [7:6] - _bus->writeByte(_addr, QMC5883P_REG_CONTROL1, ctrl1); + return 1; + } - // Initial read - uint8_t buffer[6]; - _bus->read(_addr, QMC5883P_REG_XOUT_LSB, 6, buffer); + int readMag(VectorInt16& v) override + { + uint8_t buffer[6]; + _bus->readFast(_addr, QMC5883L_RA_DATAX_L, 6, buffer); - return 1; - } + v.x = (((int16_t)buffer[1]) << 8) | buffer[0]; - int readMag(VectorInt16& v) override { - uint8_t buffer[6]; - if (_bus->read(_addr, QMC5883P_REG_XOUT_LSB, 6, buffer) != 6) { - return 0; - } + v.y = (((int16_t)buffer[3]) << 8) | buffer[2]; - // 🔑 Read raw values EXACTLY like Adafruit (no sign flip yet) - v.x = (int16_t)((buffer[1] << 8) | buffer[0]); - v.y = (int16_t)((buffer[3] << 8) | buffer[2]); - v.z = (int16_t)((buffer[5] << 8) | buffer[4]); + v.z = (((int16_t)buffer[5]) << 8) | buffer[4]; - return 1; + return 1; } - const VectorFloat convert(const VectorInt16& v) const override { - // 🔑 Use Adafruit's conversion factors (based on actual range) - float lsb_per_gauss; - switch (_currentRange) { - case QMC5883P_RANGE_30G: lsb_per_gauss = 1000.0f; break; - case QMC5883P_RANGE_12G: lsb_per_gauss = 2500.0f; break; - case QMC5883P_RANGE_8G: lsb_per_gauss = 3750.0f; break; - case QMC5883P_RANGE_2G: lsb_per_gauss = 15000.0f; break; - default: lsb_per_gauss = 3750.0f; - } - float scale = 1.0f / lsb_per_gauss; - return VectorFloat{ v.x * scale, v.y * scale, v.z * scale }; + const VectorFloat convert(const VectorInt16& v) const override + { + const float scale = 1.f / 1090.f; + return VectorFloat{v} * scale; } - int getRate() const override { - return 100; + int getRate() const override + { + return 75; } - virtual MagDeviceType getType() const override { - return MAG_QMC5883P; + virtual MagDeviceType getType() const override + { + return MAG_QMC5883; } - // 🔑 CORRECT setMode: writes range to CONTROL2[3:2] - void setMode(uint8_t range) { - _currentRange = range; - // Range is in bits [3:2] of CONTROL2 - uint8_t ctrl2 = (range << 2); - _bus->writeByte(_addr, QMC5883P_REG_CONTROL2, ctrl2); + void setMode(uint8_t osr, uint8_t rng, uint8_t odr, uint8_t mode) + { + _mode = (osr << 6) | (rng << 4) | (odr << 2) | (mode); + uint8_t res = _bus->writeByte(_addr, QMC5883L_RA_MODE, ((osr << 6) | (rng << 4) | (odr << 2) | (mode))); + + (void)res; } - bool testConnection() override { - uint8_t chip_id; - if (_bus->read(_addr, QMC5883P_REG_CHIPID, 1, &chip_id) != 1) { - return false; - } - return chip_id == 0x80; + bool testConnection() override + { + uint8_t buffer[3] = { 0, 0, 0 }; + uint8_t len = _bus->read(_addr, QMC5883L_RA_CHIPID, 1, buffer); + + return len == 1 && buffer[0] == 0xFF; } -private: - uint8_t _currentRange = QMC5883P_RANGE_8G; + private: + uint8_t _mode; }; -} -} +} + +} #endif From 1c8455522a7773c0b3bf84c49508d4d52c5e30b2 Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Sat, 27 Dec 2025 22:36:35 +0300 Subject: [PATCH 15/16] Update MagQMC5338P.h --- lib/Espfc/src/Device/MagQMC5338P.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Espfc/src/Device/MagQMC5338P.h b/lib/Espfc/src/Device/MagQMC5338P.h index f0391694..ad4e1b32 100644 --- a/lib/Espfc/src/Device/MagQMC5338P.h +++ b/lib/Espfc/src/Device/MagQMC5338P.h @@ -28,7 +28,7 @@ namespace Espfc { namespace Device { -class MagQMC5883P : public MagDevice +class MagQMC5338P : public MagDevice { public: int begin(BusDevice* bus) override @@ -124,3 +124,4 @@ class MagQMC5883P : public MagDevice #endif + From ac005fdc6a97b206b46e3485e773fe296c239fdf Mon Sep 17 00:00:00 2001 From: hussam-qawaqzeh Date: Mon, 29 Dec 2025 19:59:51 +0300 Subject: [PATCH 16/16] remove UTF symbols from code --- lib/Espfc/src/Device/MagQMC5338P.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/Espfc/src/Device/MagQMC5338P.h b/lib/Espfc/src/Device/MagQMC5338P.h index ad4e1b32..8410ad39 100644 --- a/lib/Espfc/src/Device/MagQMC5338P.h +++ b/lib/Espfc/src/Device/MagQMC5338P.h @@ -41,14 +41,14 @@ class MagQMC5338P : public MagDevice if (!testConnection()) return 0; - // 🔑 Step 1: Enable Set/Reset (write 0x29 to Z_MSB) + // Step 1: Enable Set/Reset (write 0x29 to Z_MSB) _bus->writeByte(_addr, QMC5883P_REG_ZOUT_MSB, 0x29); - // 🔑 Step 2: Set Range in CONTROL2[3:2] (Adafruit style) + // Step 2: Set Range in CONTROL2[3:2] (Adafruit style) _currentRange = QMC5883P_RANGE_8G; setMode(_currentRange); // This will write to CONTROL2 - // 🔑 Step 3: Configure CONTROL1 + // Step 3: Configure CONTROL1 uint8_t ctrl1 = QMC5883P_MODE_CONTINUOUS | // [1:0] (0x02 << 2) | // ODR = 100Hz [3:2] @@ -69,7 +69,7 @@ class MagQMC5338P : public MagDevice return 0; } - // 🔑 Read raw values EXACTLY like Adafruit (no sign flip yet) + // Read raw values EXACTLY like Adafruit (no sign flip yet) v.x = (int16_t)((buffer[1] << 8) | buffer[0]); v.y = (int16_t)((buffer[3] << 8) | buffer[2]); v.z = (int16_t)((buffer[5] << 8) | buffer[4]); @@ -78,7 +78,7 @@ class MagQMC5338P : public MagDevice } const VectorFloat convert(const VectorInt16& v) const override { - // 🔑 Use Adafruit's conversion factors (based on actual range) + // Use Adafruit's conversion factors (based on actual range) float lsb_per_gauss; switch (_currentRange) { case QMC5883P_RANGE_30G: lsb_per_gauss = 1000.0f; break; @@ -99,7 +99,7 @@ class MagQMC5338P : public MagDevice return MAG_QMC5883P; } - // 🔑 CORRECT setMode: writes range to CONTROL2[3:2] + // CORRECT setMode: writes range to CONTROL2[3:2] void setMode(uint8_t range) { _currentRange = range; // Range is in bits [3:2] of CONTROL2 @@ -125,3 +125,4 @@ class MagQMC5338P : public MagDevice #endif +