mirror of
https://github.com/cagnulein/qdomyos-zwift.git
synced 2026-02-18 23:41:50 +01:00
Compare commits
3 Commits
Mobi-Rower
...
raspberry-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9cfe24358 | ||
|
|
8cc1982dd4 | ||
|
|
f82e099795 |
127
src/homeform.cpp
127
src/homeform.cpp
@@ -781,9 +781,35 @@ homeform::homeform(QQmlApplicationEngine *engine, bluetooth *bl) {
|
||||
QtAndroid::androidContext().object());
|
||||
#endif
|
||||
|
||||
// Initialize GPIO gear worker if enabled
|
||||
gpioGearsEnabled = settings.value(QZSettings::gpio_gears_enabled, QZSettings::default_gpio_gears_enabled).toBool();
|
||||
if (gpioGearsEnabled) {
|
||||
gpioGearWorker = new GPIOGearWorkerThread(this);
|
||||
connect(gpioGearWorker, &GPIOGearWorkerThread::gearUpPressed, this, &homeform::onGPIOGearUpPressed);
|
||||
connect(gpioGearWorker, &GPIOGearWorkerThread::gearDownPressed, this, &homeform::onGPIOGearDownPressed);
|
||||
gpioGearWorker->start();
|
||||
qDebug() << "GPIO Gear Worker initialized for Raspberry Pi";
|
||||
}
|
||||
|
||||
bluetoothManager->homeformLoaded = true;
|
||||
}
|
||||
|
||||
homeform::~homeform() {
|
||||
|
||||
gpx_save_clicked();
|
||||
fit_save_clicked();
|
||||
|
||||
// Cleanup GPIO gear worker
|
||||
if (gpioGearWorker) {
|
||||
gpioGearWorker->stop();
|
||||
gpioGearWorker->quit();
|
||||
gpioGearWorker->wait(1000);
|
||||
delete gpioGearWorker;
|
||||
gpioGearWorker = nullptr;
|
||||
qDebug() << "GPIO Gear Worker cleaned up";
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
extern "C" {
|
||||
JNIEXPORT void JNICALL
|
||||
@@ -1141,11 +1167,6 @@ void homeform::refresh_bluetooth_devices_clicked() {
|
||||
bluetoothManager->restart();
|
||||
}
|
||||
|
||||
homeform::~homeform() {
|
||||
gpx_save_clicked();
|
||||
fit_save_clicked();
|
||||
}
|
||||
|
||||
void homeform::aboutToQuit() {
|
||||
qDebug() << "homeform::aboutToQuit()";
|
||||
|
||||
@@ -8568,3 +8589,99 @@ extern "C" {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// GPIO Gear Worker Thread Implementation
|
||||
GPIOGearWorkerThread::GPIOGearWorkerThread(QObject *parent)
|
||||
: QThread(parent), m_running(false) {
|
||||
#if __has_include(<wiringPi.h>)
|
||||
if (wiringPiSetup() == -1) {
|
||||
qDebug() << "wiringPiSetup failed for GPIO Gear Worker";
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup GPIO pins as inputs with pull-up resistors
|
||||
pinMode(GPIO_GEAR_UP, INPUT);
|
||||
pinMode(GPIO_GEAR_DOWN, INPUT);
|
||||
pullUpDnControl(GPIO_GEAR_UP, PUD_UP);
|
||||
pullUpDnControl(GPIO_GEAR_DOWN, PUD_UP);
|
||||
|
||||
qDebug() << "GPIO Gear Worker: Pins" << GPIO_GEAR_UP << "and" << GPIO_GEAR_DOWN << "initialized";
|
||||
#endif
|
||||
}
|
||||
|
||||
GPIOGearWorkerThread::~GPIOGearWorkerThread() {
|
||||
stop();
|
||||
if (isRunning()) {
|
||||
quit();
|
||||
wait(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void GPIOGearWorkerThread::run() {
|
||||
m_running = true;
|
||||
m_lastUpState = HIGH;
|
||||
m_lastDownState = HIGH;
|
||||
m_lastTriggerTime = QDateTime::currentDateTime().addMSecs(-GPIO_DEBOUNCE_MS);
|
||||
|
||||
qDebug() << "GPIO Gear Worker thread started";
|
||||
|
||||
while (m_running) {
|
||||
#if __has_include(<wiringPi.h>)
|
||||
int upState = digitalRead(GPIO_GEAR_UP);
|
||||
int downState = digitalRead(GPIO_GEAR_DOWN);
|
||||
QDateTime currentTime = QDateTime::currentDateTime();
|
||||
|
||||
// Check for gear up (GPIO 17) - falling edge (button pressed)
|
||||
if (m_lastUpState == HIGH && upState == LOW) {
|
||||
if (m_lastTriggerTime.msecsTo(currentTime) >= GPIO_DEBOUNCE_MS) {
|
||||
emit gearUpPressed();
|
||||
m_lastTriggerTime = currentTime;
|
||||
qDebug() << "GPIO Gear Up pressed";
|
||||
}
|
||||
}
|
||||
|
||||
// Check for gear down (GPIO 27) - falling edge (button pressed)
|
||||
if (m_lastDownState == HIGH && downState == LOW) {
|
||||
if (m_lastTriggerTime.msecsTo(currentTime) >= GPIO_DEBOUNCE_MS) {
|
||||
emit gearDownPressed();
|
||||
m_lastTriggerTime = currentTime;
|
||||
qDebug() << "GPIO Gear Down pressed";
|
||||
}
|
||||
}
|
||||
|
||||
m_lastUpState = upState;
|
||||
m_lastDownState = downState;
|
||||
#endif
|
||||
|
||||
msleep(GPIO_POLL_MS);
|
||||
}
|
||||
|
||||
qDebug() << "GPIO Gear Worker thread stopped";
|
||||
}
|
||||
|
||||
void GPIOGearWorkerThread::stop() {
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
// GPIO Gear Control Methods in homeform
|
||||
void homeform::onGPIOGearUpPressed() {
|
||||
QDateTime currentTime = QDateTime::currentDateTime();
|
||||
if (lastGearGpioTime.msecsTo(currentTime) < 100) {
|
||||
return; // Additional debouncing protection
|
||||
}
|
||||
lastGearGpioTime = currentTime;
|
||||
|
||||
qDebug() << "GPIO Gear Up processed";
|
||||
Plus(QStringLiteral("gears"));
|
||||
}
|
||||
|
||||
void homeform::onGPIOGearDownPressed() {
|
||||
QDateTime currentTime = QDateTime::currentDateTime();
|
||||
if (lastGearGpioTime.msecsTo(currentTime) < 100) {
|
||||
return; // Additional debouncing protection
|
||||
}
|
||||
lastGearGpioTime = currentTime;
|
||||
|
||||
qDebug() << "GPIO Gear Down processed";
|
||||
Minus(QStringLiteral("gears"));
|
||||
}
|
||||
|
||||
@@ -24,6 +24,21 @@
|
||||
#include <QQuickItem>
|
||||
#include <QQuickItemGrabResult>
|
||||
#include <QTextToSpeech>
|
||||
#include <QThread>
|
||||
#include <QDateTime>
|
||||
|
||||
#if __has_include(<wiringPi.h>)
|
||||
#include <wiringPi.h>
|
||||
#else
|
||||
#define INPUT 0
|
||||
#define HIGH 1
|
||||
#define LOW 0
|
||||
#define PUD_UP 2
|
||||
inline int digitalRead(int pin) { Q_UNUSED(pin); return HIGH; }
|
||||
inline void pinMode(int pin, int mode) { Q_UNUSED(pin); Q_UNUSED(mode); }
|
||||
inline void pullUpDnControl(int pin, int pud) { Q_UNUSED(pin); Q_UNUSED(pud); }
|
||||
inline int wiringPiSetup() { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
|
||||
@@ -42,6 +57,31 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class GPIOGearWorkerThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GPIOGearWorkerThread(QObject *parent = nullptr);
|
||||
~GPIOGearWorkerThread();
|
||||
void run() override;
|
||||
void stop();
|
||||
|
||||
signals:
|
||||
void gearUpPressed();
|
||||
void gearDownPressed();
|
||||
|
||||
private:
|
||||
static const uint8_t GPIO_GEAR_UP = 17; // GPIO 17 (Physical pin 11)
|
||||
static const uint8_t GPIO_GEAR_DOWN = 27; // GPIO 27 (Physical pin 13)
|
||||
static const uint16_t GPIO_DEBOUNCE_MS = 100;
|
||||
static const uint16_t GPIO_POLL_MS = 50;
|
||||
|
||||
bool m_running = false;
|
||||
int m_lastUpState = HIGH;
|
||||
int m_lastDownState = HIGH;
|
||||
QDateTime m_lastTriggerTime;
|
||||
};
|
||||
|
||||
class DataObject : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
@@ -709,6 +749,9 @@ class homeform : public QObject {
|
||||
static homeform *m_singleton;
|
||||
TemplateInfoSenderBuilder *userTemplateManager = nullptr;
|
||||
TemplateInfoSenderBuilder *innerTemplateManager = nullptr;
|
||||
GPIOGearWorkerThread *gpioGearWorker = nullptr;
|
||||
QDateTime lastGearGpioTime;
|
||||
bool gpioGearsEnabled = false;
|
||||
QList<QObject *> dataList;
|
||||
QList<SessionLine> Session;
|
||||
QQmlApplicationEngine *engine;
|
||||
@@ -888,6 +931,8 @@ class homeform : public QObject {
|
||||
void sortTilesTimeout();
|
||||
void gearUp();
|
||||
void gearDown();
|
||||
void onGPIOGearUpPressed();
|
||||
void onGPIOGearDownPressed();
|
||||
void changeTimestamp(QTime source, QTime actual);
|
||||
void pelotonOffset_Plus();
|
||||
void pelotonOffset_Minus();
|
||||
|
||||
@@ -943,6 +943,7 @@ const QString QZSettings::inclinationResistancePoints = QStringLiteral("inclinat
|
||||
const QString QZSettings::default_inclinationResistancePoints = QStringLiteral("");
|
||||
|
||||
const QString QZSettings::floatingwindow_type = QStringLiteral("floatingwindow_type");
|
||||
const QString QZSettings::gpio_gears_enabled = QStringLiteral("gpio_gears_enabled");
|
||||
|
||||
|
||||
const uint32_t allSettingsCount = 772;
|
||||
@@ -1737,6 +1738,7 @@ QVariant allSettings[allSettingsCount][2] = {
|
||||
{QZSettings::nordictrack_elite_800, QZSettings::default_nordictrack_elite_800},
|
||||
{QZSettings::inclinationResistancePoints, QZSettings::default_inclinationResistancePoints},
|
||||
{QZSettings::floatingwindow_type, QZSettings::default_floatingwindow_type},
|
||||
{QZSettings::gpio_gears_enabled, QZSettings::default_gpio_gears_enabled},
|
||||
{QZSettings::rogue_echo_bike, QZSettings::default_rogue_echo_bike},
|
||||
};
|
||||
|
||||
|
||||
@@ -2516,6 +2516,9 @@ class QZSettings {
|
||||
static const QString floatingwindow_type;
|
||||
static constexpr int default_floatingwindow_type = 0;
|
||||
|
||||
static const QString gpio_gears_enabled;
|
||||
static constexpr bool default_gpio_gears_enabled = false;
|
||||
|
||||
/**
|
||||
* @brief Write the QSettings values using the constants from this namespace.
|
||||
* @param showDefaults Optionally indicates if the default should be shown with the key.
|
||||
|
||||
@@ -1167,6 +1167,7 @@ import Qt.labs.platform 1.1
|
||||
// 2.19.2
|
||||
property bool tile_hr_time_in_zone_individual_mode: false
|
||||
property bool wahoo_without_wheel_diameter: false
|
||||
property bool gpio_gears_enabled: false
|
||||
}
|
||||
|
||||
function paddingZeros(text, limit) {
|
||||
@@ -12059,6 +12060,45 @@ import Qt.labs.platform 1.1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AccordionElement {
|
||||
id: hardwareControlAccordion
|
||||
title: qsTr("Hardware Control")
|
||||
indicatRectColor: Material.color(Material.Grey)
|
||||
textColor: Material.color(Material.Yellow)
|
||||
color: Material.backgroundColor
|
||||
accordionContent: ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
IndicatorOnlySwitch {
|
||||
id: gpioGearsEnabledDelegate
|
||||
text: qsTr("GPIO Gears Control")
|
||||
spacing: 0
|
||||
bottomPadding: 0
|
||||
topPadding: 0
|
||||
rightPadding: 0
|
||||
leftPadding: 0
|
||||
clip: false
|
||||
checked: settings.gpio_gears_enabled
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
Layout.fillWidth: true
|
||||
onClicked: { settings.gpio_gears_enabled = checked; window.settings_restart_to_apply = true; }
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Enable GPIO-based gear shifting on Raspberry Pi (GPIO 17 for up, GPIO 27 for down)")
|
||||
font.bold: true
|
||||
font.italic: true
|
||||
font.pixelSize: Qt.application.font.pixelSize - 2
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
Layout.fillWidth: true
|
||||
color: Material.color(Material.Lime)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*##^##
|
||||
Designer {
|
||||
|
||||
Reference in New Issue
Block a user