Skip to content

Commit d460d1d

Browse files
committed
add QMC6309, HP203B
1 parent f1183e3 commit d460d1d

File tree

9 files changed

+157
-33
lines changed

9 files changed

+157
-33
lines changed

src/madflight.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#define MADFLIGHT_VERSION "madflight v2.0.0"
1+
#define MADFLIGHT_VERSION "madflight v2.0.1-DEV"
22

33
//madflight.h - Flight Controller for ESP32 / ESP32-S3 / RP2350 / RP2040 / STM32
44

src/madflight/bar/BarGizmoHP203B.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include "bar.h"
4+
#include "../hal/MF_I2C.h"
5+
6+
class BarGizmoHP203B: public BarGizmo {
7+
private:
8+
MF_I2CDevice *dev;
9+
public:
10+
BarGizmoHP203B(MF_I2C *i2c, int8_t i2c_adr, uint32_t sampleRate) {
11+
(void) sampleRate; //TODO
12+
if(i2c_adr == 0) i2c_adr = 0XEC; // fixed: 0XEC or 0xEE
13+
this->dev = new MF_I2CDevice(i2c, i2c_adr);
14+
dev->write(0b01010000, nullptr, 0); // ADC_CVT = 010, 100 OSR=256 (8.2ms), 00 press+temp
15+
}
16+
17+
bool update(float *press, float *temp) override {
18+
uint8_t d[6];
19+
dev->read(0x10, d, 6); //READ_PT
20+
int32_t t = ((d[0] << 16) | (d[1] << 8) | d[2]) & 0x000fffff; //20 bit big-endian signed
21+
if(t & 0x00080000) t |= 0xfff00000; //20bit sign expansion
22+
uint32_t p = ((d[3] << 16) | (d[4] << 8) | d[5]) & 0x000fffff; //20 bit big-endian unsigned
23+
24+
*temp = t * 0.01; //temperature in [C]
25+
*press = 0.01 * p; //pressure in [Pa]
26+
return true;
27+
}
28+
};

src/madflight/bar/bar.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ SOFTWARE.
2929
#include "BarGizmoBMP280.h"
3030
#include "BarGizmoBMP390.h"
3131
#include "BarGizmoMS5611.h"
32+
#include "BarGizmoHP203B.h"
3233
#include <math.h>
3334

3435
//create global module instance
@@ -43,8 +44,8 @@ int Bar::setup() {
4344
press = 0;
4445
temp = 0;
4546
alt = 0;
46-
ts = micros();
47-
dt = 0;
47+
ts = 0;
48+
dt = 0;
4849

4950
//create gizmo
5051
delete gizmo;
@@ -68,6 +69,11 @@ int Bar::setup() {
6869
gizmo = new BarGizmoMS5611(config.i2c_bus, config.i2c_adr, config.sampleRate);
6970
}
7071
break;
72+
case Cfg::bar_gizmo_enum::mf_HP203B :
73+
if(config.i2c_bus) {
74+
gizmo = new BarGizmoHP203B(config.i2c_bus, config.i2c_adr, config.sampleRate);
75+
}
76+
break;
7177
}
7278

7379
//check gizmo
@@ -81,17 +87,18 @@ int Bar::setup() {
8187

8288
bool Bar::update() {
8389
if(!gizmo) return false;
84-
if (micros() - ts >= _samplePeriod) {
85-
uint32_t tsnew = micros();
86-
dt = (tsnew - ts) / 1000000.0;
87-
gizmo->update(&press, &temp);
88-
float P = press;
89-
//float T = temp;
90-
//alt = 153.84348f * (1 - pow(P/101325.0f, 0.19029496f)) * (T + 273.15f); //hypsometric formula - reduces to barometric with T=15C
91-
alt = 44330.0f * (1 - pow(P/101325.0f, 0.19029496f)); //barometric formula 0.19029496 = 1/5.255
92-
//alt = (101325.0f - P) / 12.0f; //linearisation of barometric formula at sealevel
93-
ts = tsnew;
94-
return true;
95-
}
96-
return false;
90+
91+
uint32_t now = micros();
92+
if(now - ts < _samplePeriod) return false;
93+
if(now - ts < 2 * _samplePeriod) ts += _samplePeriod; else ts = now; //keep exact _samplePeriod timing, unless we missed an interval
94+
95+
dt = (now - ts) / 1000000.0;
96+
gizmo->update(&press, &temp);
97+
float P = press;
98+
//float T = temp;
99+
//alt = 153.84348f * (1 - pow(P / 101325.0f, 0.19029496f)) * (T + 273.15f); //hypsometric formula - reduces to barometric with T=15C
100+
alt = 44330.0f * (1 - pow(P / 101325.0f, 0.19029496f)); //barometric formula 0.19029496 = 1/5.255
101+
//alt = (101325.0f - P) / 12.0f; //linearisation of barometric formula at sealevel
102+
ts = now;
103+
return true;
97104
}

src/madflight/cfg/cfg.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ SOFTWARE.
183183
MF_PARAM( ahr_gizmo, 0, int32_t, 'e', mf_MAHONY,mf_MAHONY_BF,mf_MADGWICK,mf_VQF) \
184184
\
185185
/*BAR - Barometer*/ \
186-
MF_PARAM( bar_gizmo, 0, int32_t, 'e', mf_NONE,mf_BMP280,mf_BMP388,mf_BMP390,mf_MS5611) \
186+
MF_PARAM( bar_gizmo, 0, int32_t, 'e', mf_NONE,mf_BMP280,mf_BMP388,mf_BMP390,mf_MS5611,mf_HP203B) \
187187
MF_PARAM( bar_i2c_bus, -1, int32_t, 'i') \
188188
MF_PARAM( bar_i2c_adr, 0, int32_t, 'i') \
189189
MF_PARAM( bar_rate, 1000, float, 'f') /*Barometer sample rate in Hz (default 100)*/ \
@@ -216,7 +216,7 @@ SOFTWARE.
216216
MF_PARAM( led_on, 0, int32_t, 'e', mf_LOW_IS_ON,mf_HIGH_IS_ON) \
217217
\
218218
/*MAG - Magnetometer*/ \
219-
MF_PARAM( mag_gizmo, 0, int32_t, 'e', mf_NONE,mf_QMC5883) \
219+
MF_PARAM( mag_gizmo, 0, int32_t, 'e', mf_NONE,mf_QMC5883,mf_QMC6309) \
220220
MF_PARAM( mag_i2c_bus, -1, int32_t, 'i') \
221221
MF_PARAM( mag_i2c_adr, 0, int32_t, 'i') \
222222
MF_PARAM( mag_lp, 1e10, float, 'f') /*Magnetometer Gyro Low Pass Filter cutoff frequency in Hz (default 1e10Hz, i.e. no filtering) */ \

src/madflight/hal/MF_I2C.h

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,60 @@ class MF_I2C {
3535
return requestFrom(address, len, true);
3636
}
3737

38-
//non "Arduino standard" extension
39-
uint32_t transceive(uint8_t address, uint8_t* wbuf, uint32_t wlen, uint8_t* rbuf, uint32_t rlen) {
40-
beginTransmission(address);
41-
write(wbuf, wlen);
42-
endTransmission(false);
43-
requestFrom(address, rlen);
44-
return read(rbuf, rlen);
45-
}
46-
4738
//virtual void begin(uint8_t address) = 0;
4839
//virtual void onReceive(void(*)(int)) = 0;
4940
//virtual void onRequest(void(*)(void)) = 0;
5041
};
5142

43+
44+
class MF_I2CDevice {
45+
public:
46+
MF_I2C *i2c;
47+
uint8_t adr;
48+
49+
MF_I2CDevice(MF_I2C *i2c, uint8_t adr) {
50+
this->i2c = i2c;
51+
this->adr = adr;
52+
}
53+
54+
uint32_t write(uint8_t reg, uint8_t *data, uint32_t len) {
55+
i2c->beginTransmission(adr);
56+
uint32_t rv = i2c->write(&reg, 1);
57+
if(len > 0) {
58+
rv += i2c->write(data, len);
59+
}
60+
return rv;
61+
}
62+
63+
uint32_t write(uint8_t reg, uint8_t data) {
64+
return write(reg, &data, 1);
65+
}
66+
67+
uint32_t read(uint8_t reg, uint8_t *data, uint32_t len) {
68+
uint32_t rv = 0;
69+
i2c->beginTransmission(adr);
70+
i2c->write(&reg, 1);
71+
if(len > 0) {
72+
i2c->endTransmission(false);
73+
i2c->requestFrom(adr, len);
74+
rv = i2c->read(data, len);
75+
}
76+
return rv;
77+
}
78+
79+
uint32_t transceive(uint8_t* wbuf, uint32_t wlen, uint8_t* rbuf, uint32_t rlen) {
80+
uint32_t rv = 0;
81+
i2c->beginTransmission(adr);
82+
if(wlen > 0) rv = i2c->write(wbuf, wlen);
83+
if(wlen > 0 && rlen > 0) i2c->endTransmission(false);
84+
if(rlen > 0) {
85+
i2c->requestFrom(adr, rlen);
86+
rv = i2c->read(rbuf, rlen);
87+
}
88+
return rv;
89+
}
90+
};
91+
5292
// Wrapper around an arduino TwoWire-like pointer T
5393
template<class T>
5494
class MF_I2CPtrWrapper : public MF_I2C {

src/madflight/mag/MagGizmoQMC5883L.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class MagGizmoQMC5883L: public MagGizmo {
1515
//return (mag_QMC5883L.detect() ? 0 : 1);
1616
}
1717

18-
bool read_uT(float *x, float *y, float *z) override {
18+
bool update(float *x, float *y, float *z) override {
1919
mag_QMC5883L.read_uT(x, y, z);
2020
return true;
2121
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
3+
#include "mag.h"
4+
#include "../hal/MF_I2C.h"
5+
6+
7+
class MagGizmoQMC6309 : public MagGizmo {
8+
private:
9+
MF_I2CDevice *dev;
10+
public:
11+
MagGizmoQMC6309(MF_I2C *i2c, int8_t i2c_adr) {
12+
i2c_adr = 0x7C; // fixed: 0x7C
13+
this->dev = new MF_I2CDevice(i2c, i2c_adr);
14+
15+
//setup for 16 sample moving average (my interpretation of data sheet OSR2 setting), sample rate = 1500Hz (continous mode)
16+
dev->write(0x0B, 0x04); //ODR=1Hz, Scale=8G, Reset
17+
dev->write(0x0A, 0xFD); //OSR2(filter)=16, OSR=1, Continuous Mode
18+
}
19+
20+
bool update(float *x, float *y, float *z) override {
21+
uint8_t d[6];
22+
dev->read(0x01, d, 6);
23+
int16_t mx = d[0] | (d[1] << 8); //16 bit litte-endian signed
24+
int16_t my = d[2] | (d[3] << 8);
25+
int16_t mz = d[4] | (d[5] << 8);
26+
27+
*x = 200e-9 * mx; //in [T]
28+
*y = 200e-9 * my;
29+
*z = 200e-9 * mz;
30+
return true;
31+
}
32+
};

src/madflight/mag/mag.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ SOFTWARE.
2727
#include <Arduino.h> //Serial
2828
#include "mag.h"
2929
#include "MagGizmoQMC5883L.h"
30+
#include "MagGizmoQMC6309.h"
3031

3132
//create global module instance
3233
Mag mag;
@@ -36,6 +37,12 @@ int Mag::setup() {
3637

3738
_samplePeriod = 1000000 / config.sampleRate;
3839

40+
//clear state
41+
x = 0; //"North" magnetic flux [uT]
42+
y = 0; //"East" magnetic flux [uT]
43+
z = 0; //"Down" magnetic flux [uT]
44+
ts = 0; //last sample time in [us]
45+
3946
//create gizmo
4047
delete gizmo;
4148
switch(config.gizmo) {
@@ -47,6 +54,11 @@ int Mag::setup() {
4754
gizmo = new MagGizmoQMC5883L(config.i2c_bus, config.i2c_adr);
4855
}
4956
break;
57+
case Cfg::mag_gizmo_enum::mf_QMC6309 :
58+
if(config.i2c_bus) {
59+
gizmo = new MagGizmoQMC6309(config.i2c_bus, config.i2c_adr);
60+
}
61+
break;
5062
}
5163

5264
//check gizmo
@@ -60,7 +72,12 @@ int Mag::setup() {
6072

6173
bool Mag::update() {
6274
if(!gizmo) return false;
63-
if(micros() - mag_time < _samplePeriod) return false;
64-
mag_time = micros();
65-
return gizmo->read_uT(&x, &y, &z);
75+
76+
uint32_t now = micros();
77+
if(now - ts < _samplePeriod) return false;
78+
if(now - ts < 2 * _samplePeriod) ts += _samplePeriod; else ts = now; //keep exact _samplePeriod timing, unless we missed an interval
79+
80+
if(!gizmo->update(&x, &y, &z)) return false;
81+
ts = now;
82+
return true;
6683
}

src/madflight/mag/mag.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct MagState {
3232
float x = 0; //"North" magnetic flux [uT]
3333
float y = 0; //"East" magnetic flux [uT]
3434
float z = 0; //"Down" magnetic flux [uT]
35+
uint32_t ts = 0; //last sample time in [us]
3536
};
3637

3738
struct MagConfig {
@@ -45,7 +46,7 @@ struct MagConfig {
4546
class MagGizmo {
4647
public:
4748
virtual ~MagGizmo() {};
48-
virtual bool read_uT(float *x, float *y, float *z) = 0; //returns true if new sample was retrieved
49+
virtual bool update(float *x, float *y, float *z) = 0; //returns true if new sample was retrieved
4950
};
5051

5152
class Mag : public MagState {
@@ -59,7 +60,6 @@ class Mag : public MagState {
5960
bool installed() {return (gizmo != nullptr); } // Returns true if a gizmo was setup
6061

6162
protected:
62-
uint32_t mag_time = 0; //last sample time in [us]
6363
uint32_t _samplePeriod = 0; //gizmo sample period in [us]
6464

6565
bool _installed = false;

0 commit comments

Comments
 (0)