Added expanded settings requested by ChatGPT for magnetic fields; the values remain pinned and when a magnet is moved about 10mm away, still the values remain pinned. Going to log an Issue, but preserving here, and will revert to LillyGO version for Issue submission

This commit is contained in:
John Poole 2026-04-19 16:33:10 -07:00
commit a2e34659a6
4 changed files with 231 additions and 1 deletions

View file

@ -31,6 +31,9 @@
#include <SensorQMC6309.hpp> #include <SensorQMC6309.hpp>
#include <SensorWireHelper.h> #include <SensorWireHelper.h>
#include "LoRaBoards.h" #include "LoRaBoards.h"
#include "QmcServices.h"
#define Serial QmcSerial
void calibrate(); void calibrate();
MagnetometerBase *magnetometer; MagnetometerBase *magnetometer;
@ -41,6 +44,7 @@ void setup()
while (!Serial); while (!Serial);
setupBoards(); setupBoards();
qmcServicesBegin();
// The desired output data rate in Hz. Allowed values are 1.0, 10.0, 50.0, 100.0 and 200.0HZ. // The desired output data rate in Hz. Allowed values are 1.0, 10.0, 50.0, 100.0 and 200.0HZ.
float data_rate_hz = 200.0f; float data_rate_hz = 200.0f;
@ -184,6 +188,7 @@ void setup()
void loop() void loop()
{ {
qmcServicesUpdate();
MagnetometerData data; MagnetometerData data;
@ -194,6 +199,20 @@ void loop()
float y = MagnetometerUtils::gaussToMicroTesla(data.magnetic_field.y); float y = MagnetometerUtils::gaussToMicroTesla(data.magnetic_field.y);
float z = MagnetometerUtils::gaussToMicroTesla(data.magnetic_field.z); float z = MagnetometerUtils::gaussToMicroTesla(data.magnetic_field.z);
float deg_xy = atan2(y, x) * 180.0f / PI;
float deg_xny = atan2(-y, x) * 180.0f / PI;
float deg_yx = atan2(x, y) * 180.0f / PI;
float deg_nxy = atan2(y, -x) * 180.0f / PI;
float deg_xz = atan2(z, x) * 180.0f / PI;
float deg_zx = atan2(x, z) * 180.0f / PI;
float deg_yz = atan2(z, y) * 180.0f / PI;
float deg_zy = atan2(y, z) * 180.0f / PI;
auto norm360 = [](float d) {
while (d < 0) d += 360.0f;
while (d >= 360.0f) d -= 360.0f;
return d;
};
Serial.print("Mag:"); Serial.print("Mag:");
Serial.print(" X:"); Serial.print(x); Serial.print(" X:"); Serial.print(x);
Serial.print(" Y:"); Serial.print(y); Serial.print(" Y:"); Serial.print(y);
@ -222,10 +241,20 @@ void loop()
Serial.print(strength, 2); Serial.print(strength, 2);
Serial.println(" μT"); Serial.println(" μT");
Serial.print(" XY:"); Serial.print(norm360(deg_xy), 2);
Serial.print(" XnY:"); Serial.print(norm360(deg_xny), 2);
Serial.print(" YX:"); Serial.print(norm360(deg_yx), 2);
Serial.print(" nXY:"); Serial.print(norm360(deg_nxy), 2);
Serial.print(" XZ:"); Serial.print(norm360(deg_xz), 2);
Serial.print(" ZX:"); Serial.print(norm360(deg_zx), 2);
Serial.print(" YZ:"); Serial.print(norm360(deg_yz), 2);
Serial.print(" ZY:"); Serial.println(norm360(deg_zy), 2);
if (data.overflow) { if (data.overflow) {
Serial.println("\tWarning: Data Overflow occurred!"); Serial.println("\tWarning: Data Overflow occurred!");
} }
} }
qmcServicesUpdate();
delay(10); delay(10);
} }

View file

@ -0,0 +1,174 @@
#include "QmcServices.h"
#include <TBeamClock.h>
#include <TBeamStorage.h>
#include <TBeamWeb.h>
#ifndef BOARD_ID
#define BOARD_ID "NODE"
#endif
#ifndef NODE_LABEL
#define NODE_LABEL BOARD_ID
#endif
#ifndef LOG_AP_IP_OCTET
#define LOG_AP_IP_OCTET 25
#endif
namespace {
tbeam::TBeamClock clockService(Wire1);
tbeam::TBeamStorage storageService(::Serial);
tbeam::TBeamWeb webService(::Serial);
bool servicesStarted = false;
uint32_t lastFlushMs = 0;
uint32_t lastClockUpdateMs = 0;
char logPath[128] = {};
void openRunLog()
{
if (!storageService.ready()) {
return;
}
char runId[64] = {};
tbeam::DateTime rtc;
int64_t epoch = 0;
if (clockService.readValidRtc(rtc, &epoch)) {
tbeam::TBeamClock::makeRunId(rtc, BOARD_ID, runId, sizeof(runId));
} else {
snprintf(runId, sizeof(runId), "%s_%lu", BOARD_ID, static_cast<unsigned long>(millis() / 1000));
}
snprintf(logPath, sizeof(logPath), "/logs/qmc63xx/%s.log", runId);
if (!storageService.openLog(logPath)) {
::Serial.printf("[qmc-services] log open failed: %s\n", storageService.lastError());
logPath[0] = '\0';
return;
}
storageService.println("# test: qmc63xx");
storageService.print("# board_id: ");
storageService.println(BOARD_ID);
storageService.print("# node_label: ");
storageService.println(NODE_LABEL);
storageService.print("# log_path: ");
storageService.println(logPath);
if (clockService.valid()) {
char iso[32] = {};
tbeam::TBeamClock::formatIsoUtc(clockService.lastRtc(), iso, sizeof(iso));
storageService.print("# rtc_utc: ");
storageService.println(iso);
}
storageService.println("# serial_tee: enabled");
storageService.flush();
}
} // namespace
QmcSerialTee QmcSerial;
void QmcSerialTee::begin(unsigned long baud)
{
::Serial.begin(baud);
}
size_t QmcSerialTee::write(uint8_t value)
{
const size_t serialWritten = ::Serial.write(value);
if (servicesStarted && storageService.isLogOpen()) {
storageService.write(&value, 1);
}
return serialWritten;
}
size_t QmcSerialTee::write(const uint8_t* buffer, size_t size)
{
const size_t serialWritten = ::Serial.write(buffer, size);
if (servicesStarted && storageService.isLogOpen()) {
storageService.write(buffer, size);
}
return serialWritten;
}
void QmcSerialTee::flush()
{
::Serial.flush();
if (servicesStarted && storageService.isLogOpen()) {
storageService.flush();
}
}
void qmcServicesBegin()
{
if (servicesStarted) {
return;
}
tbeam::ClockConfig clockConfig;
clockConfig.beginWire = false;
clockService.begin(clockConfig);
clockService.update();
tbeam::StorageConfig storageConfig;
storageConfig.logDir = "/logs/qmc63xx";
storageConfig.enablePinDumps = false;
storageService.begin(storageConfig);
openRunLog();
tbeam::WebConfig webConfig;
webConfig.ssidPrefix = "GPSQA";
webConfig.boardId = BOARD_ID;
webConfig.password = nullptr;
webConfig.ipOctet = LOG_AP_IP_OCTET;
webConfig.enableDelete = true;
webService.begin(storageService, webConfig);
servicesStarted = true;
::Serial.printf("[qmc-services] board=%s label=%s\n", BOARD_ID, NODE_LABEL);
if (clockService.valid()) {
char iso[32] = {};
tbeam::TBeamClock::formatIsoUtc(clockService.lastRtc(), iso, sizeof(iso));
::Serial.printf("[qmc-services] rtc=%s\n", iso);
} else {
::Serial.printf("[qmc-services] rtc invalid: %s\n", clockService.lastError());
}
::Serial.printf("[qmc-services] log=%s\n", logPath[0] ? logPath : "(not open)");
if (webService.ready()) {
::Serial.printf("[qmc-services] web=http://%s/ ssid=%s\n",
webService.ip().toString().c_str(),
webService.ssid());
} else {
::Serial.printf("[qmc-services] web unavailable: %s\n", webService.lastError());
}
}
void qmcServicesUpdate()
{
if (!servicesStarted) {
return;
}
const uint32_t now = millis();
storageService.update();
webService.update();
if (now - lastClockUpdateMs >= 1000) {
lastClockUpdateMs = now;
clockService.update();
}
if (now - lastFlushMs >= 2000) {
lastFlushMs = now;
storageService.flush();
}
}
const char* qmcServicesLogPath()
{
return logPath;
}

View file

@ -0,0 +1,19 @@
#pragma once
#include <Arduino.h>
class QmcSerialTee : public Print {
public:
void begin(unsigned long baud);
explicit operator bool() const { return true; }
size_t write(uint8_t value) override;
size_t write(const uint8_t* buffer, size_t size) override;
void flush();
};
extern QmcSerialTee QmcSerial;
void qmcServicesBegin();
void qmcServicesUpdate();
const char* qmcServicesLogPath();

View file

@ -16,7 +16,9 @@ monitor_speed = 115200
; Reuse LilyGO's bundled libraries: ; Reuse LilyGO's bundled libraries:
; SensorLib, ESP8266_SSD1306, XPowersLib, RadioLib, etc. ; SensorLib, ESP8266_SSD1306, XPowersLib, RadioLib, etc.
lib_extra_dirs = /usr/local/src/LilyGo-LoRa-Series/lib lib_extra_dirs =
/usr/local/src/LilyGo-LoRa-Series/lib
/usr/local/src/microreticulum/microReticulumTbeam/lib
monitor_filters = monitor_filters =
default default
@ -26,6 +28,12 @@ monitor_filters =
build_flags = build_flags =
-DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_USB_CDC_ON_BOOT=1
-DCORE_DEBUG_LEVEL=0 -DCORE_DEBUG_LEVEL=0
-I /usr/local/src/microreticulum/microReticulumTbeam/shared/boards
-I /usr/local/src/microreticulum/microReticulumTbeam/external/microReticulum_Firmware
-D BOARD_MODEL=BOARD_TBEAM_S_V1
-D BOARD_ID=\"CY\"
-D NODE_LABEL=\"Cy\"
-D LOG_AP_IP_OCTET=25
[env:T_BEAM_S3_SUPREME_SX1262] [env:T_BEAM_S3_SUPREME_SX1262]
board = t-beams3-supreme board = t-beams3-supreme