From 4ff73760e531846b30e585aaa409d06e3135e703 Mon Sep 17 00:00:00 2001 From: uvos Date: Fri, 21 Jan 2022 19:41:52 +0100 Subject: [PATCH] add support for turnouts --- src/items/itemstore.cpp | 4 ++- src/items/train.cpp | 6 ++--- src/items/train.h | 1 + src/items/turnout.cpp | 17 +++++++++++++ src/items/turnout.h | 19 ++++++++++++++ src/main.cpp | 3 ++- src/microcontroller.cpp | 42 +++++++++++++++++++++++++----- src/microcontroller.h | 13 +++++++--- src/ui/itemscrollbox.cpp | 43 ++++++++++++++++++++++--------- src/ui/itemwidget.cpp | 55 +++++++++++++++++++++++++++++++--------- src/ui/itemwidget.ui | 19 +++++++++++++- trainControllerUI.pro | 6 ++--- 12 files changed, 184 insertions(+), 44 deletions(-) create mode 100644 src/items/turnout.cpp create mode 100644 src/items/turnout.h diff --git a/src/items/itemstore.cpp b/src/items/itemstore.cpp index 4688361..d0f11c9 100644 --- a/src/items/itemstore.cpp +++ b/src/items/itemstore.cpp @@ -8,12 +8,14 @@ ItemStore::ItemStore(QObject *parent): QObject(parent) void ItemStore::addItem(std::shared_ptr item) { bool mached = false; - for(unsigned i = 0; i < items_.size(); i++ ) if(*items_[i] == *item) mached = true; + for(unsigned i = 0; i < items_.size(); i++ ) + if(*items_[i] == *item) mached = true; if(!mached) { items_.push_back(std::shared_ptr(item)); itemAdded(std::weak_ptr(items_.back())); } + qDebug()<<"Got item: "<id()<<" matched: "<>& itemIn) diff --git a/src/items/train.cpp b/src/items/train.cpp index e1ab282..5ce02b7 100644 --- a/src/items/train.cpp +++ b/src/items/train.cpp @@ -14,19 +14,19 @@ void Train::setFunction(uint8_t funciton, bool value) { Item::setFunction(funciton, value); if(micro) - micro->itemSetFunction(train_id_, funciton, value); + micro->trainSetFunction(train_id_, funciton, value); } void Train::setValue(uint8_t value) { Item::setValue(value); if(micro) - micro->itemSetSpeed(train_id_, value); + micro->trainSetSpeed(train_id_, value); } void Train::reverse() { if(micro) - micro->itemReverse(train_id_); + micro->trainReverse(train_id_); } diff --git a/src/items/train.h b/src/items/train.h index 1764a15..d921012 100644 --- a/src/items/train.h +++ b/src/items/train.h @@ -20,6 +20,7 @@ public slots: void reverse(); virtual void setFunction(uint8_t function, bool on); virtual void setValue(uint8_t value); + uint8_t getTrainId(){return train_id_;} }; #endif // TRAIN_H diff --git a/src/items/turnout.cpp b/src/items/turnout.cpp new file mode 100644 index 0000000..61b5a57 --- /dev/null +++ b/src/items/turnout.cpp @@ -0,0 +1,17 @@ +#include "turnout.h" + +Microcontroller *Turnout::micro = nullptr; + +Turnout::Turnout(uint8_t id, uint8_t address, uint8_t subaddress) + : subaddress_(subaddress), turnoutId_(id) +{ + itemId_ = address | (subaddress << 8); + name_ = QString("Turnout ")+QString::number(id); +} + +void Turnout::setValue(uint8_t value) +{ + Item::setValue(value); + if(micro) + micro->tunoutSetDirection(turnoutId_, value); +} diff --git a/src/items/turnout.h b/src/items/turnout.h new file mode 100644 index 0000000..713887d --- /dev/null +++ b/src/items/turnout.h @@ -0,0 +1,19 @@ +#ifndef TURNOUT_H +#define TURNOUT_H + +#include "item.h" +#include "../microcontroller.h" + +class Turnout : public Item +{ + uint8_t subaddress_; + uint8_t turnoutId_; +public: + static Microcontroller *micro; + + explicit Turnout(uint8_t id = 0, uint8_t address = 0, uint8_t subaddress = 0); + virtual void setValue(uint8_t value); + uint8_t getTurnoutId(){return turnoutId_;} +}; + +#endif // TURNOUT_H diff --git a/src/main.cpp b/src/main.cpp index a75e1ad..1954520 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,6 +11,7 @@ #include "ui/mainwindow.h" #include "items/itemstore.h" #include "items/train.h" +#include "items/turnout.h" #define BAUD QSerialPort::Baud38400 @@ -86,7 +87,7 @@ int main(int argc, char *argv[]) micro.setPower(true); Train::micro = µ - + Turnout::micro = µ ItemStore items; QObject::connect(µ, &Microcontroller::gotItemList, &items, &ItemStore::addItems); diff --git a/src/microcontroller.cpp b/src/microcontroller.cpp index 5d15a00..a5395f1 100644 --- a/src/microcontroller.cpp +++ b/src/microcontroller.cpp @@ -3,8 +3,9 @@ #include #include #include "items/train.h" +#include "items/turnout.h" -void Microcontroller::itemSetSpeed(uint8_t id, uint8_t speed) +void Microcontroller::trainSetSpeed(uint8_t id, uint8_t speed) { qDebug()<<__func__; std::stringstream ss; @@ -12,20 +13,27 @@ void Microcontroller::itemSetSpeed(uint8_t id, uint8_t speed) write(ss.str().c_str()); } -void Microcontroller::itemReverse(uint8_t id) +void Microcontroller::trainReverse(uint8_t id) { std::stringstream ss; ss<<"train "<<(unsigned)id<<" reverse\n"; write(ss.str().c_str()); } -void Microcontroller::itemSetFunction(uint8_t id, uint8_t function, bool on) +void Microcontroller::trainSetFunction(uint8_t id, uint8_t function, bool on) { std::stringstream ss; ss<<"train "<<(unsigned)id<<" function "<<(unsigned)function<<' '<<(on ? "on" : "off")<<'\n'; write(ss.str().c_str()); } +void Microcontroller::tunoutSetDirection(uint8_t id, bool direction) +{ + std::stringstream ss; + ss<<"turnout "<<(unsigned)id<<" set "<<(!direction ? "left" : "right")<<'\n'; + write(ss.str().c_str()); +} + void Microcontroller::setPower(bool on) { write(on ? "power on\n" : "power off\n"); @@ -68,6 +76,7 @@ bool Microcontroller::connected() void Microcontroller::requestState() { write("train list\n"); + write("turnout list\n"); } //housekeeping @@ -94,19 +103,34 @@ void Microcontroller::setIODevice(QIODevice *port) std::shared_ptr Microcontroller::processTrainLine(const QString& buffer) { QStringList bufferList = buffer.split(' '); - if(bufferList.size() >= 9 && buffer.startsWith("NUMBER:")) + if(bufferList.size() >= 13 && buffer.startsWith("NUMBER:")) { return std::shared_ptr(new Train(bufferList[1].toInt(), bufferList[3].toInt(), bufferList[12].toInt())); } return nullptr; } +std::shared_ptr Microcontroller::processTurnoutLine(const QString& buffer) +{ + qDebug()<<__func__<<" :"<= 6 && buffer.startsWith("NUMBER:")) + { + return std::shared_ptr(new Turnout(bufferList[1].toInt(), bufferList[5].toInt())); + } + return nullptr; +} + void Microcontroller::processList(const QString& buffer) { QStringList bufferList = buffer.split(' '); - if(bufferList.size() >= 13 && buffer.startsWith("NUMBER:")) + qDebug()<<__func__<<" :"<= 10 && buffer.startsWith("NUMBER:")) { - itemList.push_back(processTrainLine(buffer)); + if(listMode == TRAIN_LIST) + itemList.push_back(processTrainLine(buffer)); + else if(listMode == TURNOUT_LIST) + itemList.push_back(processTurnoutLine(buffer)); } else { @@ -134,9 +158,13 @@ void Microcontroller::processMicroReturn() { if(_buffer.startsWith("Trains:")) { - listMode = true; + listMode = TRAIN_LIST; itemList.clear(); } + else if(_buffer.startsWith("Turnouts:")) + { + listMode = TURNOUT_LIST; + } else if(_buffer.startsWith("NUMBER:")) { processItemState(_buffer); diff --git a/src/microcontroller.h b/src/microcontroller.h index f4ec474..14b68c7 100644 --- a/src/microcontroller.h +++ b/src/microcontroller.h @@ -30,7 +30,10 @@ public: private: - bool listMode = false; + static constexpr int TRAIN_LIST = 1; + static constexpr int TURNOUT_LIST = 2; + + int listMode = 0; //uint8_t _auxState = 0; @@ -45,6 +48,7 @@ private: void processList(const QString& buffer); void processItemState(const QString& buffer); std::shared_ptr processTrainLine(const QString& buffer); + std::shared_ptr processTurnoutLine(const QString& buffer); void write(char *buffer, const size_t length); void write(const QByteArray& buffer); @@ -59,9 +63,10 @@ public: public slots: void requestState(); - void itemSetSpeed(uint8_t id, uint8_t speed); - void itemReverse(uint8_t id); - void itemSetFunction(uint8_t id, uint8_t function, bool on); + void trainSetSpeed(uint8_t id, uint8_t speed); + void trainReverse(uint8_t id); + void trainSetFunction(uint8_t id, uint8_t function, bool on); + void tunoutSetDirection(uint8_t id, bool direction); void estop(); void setPower(bool on); diff --git a/src/ui/itemscrollbox.cpp b/src/ui/itemscrollbox.cpp index 6b03112..3e8a1a4 100644 --- a/src/ui/itemscrollbox.cpp +++ b/src/ui/itemscrollbox.cpp @@ -1,5 +1,8 @@ #include "itemscrollbox.h" #include "ui_relayscrollbox.h" +#include "ui_relayscrollbox.h" +#include "../items/train.h" +#include "../items/turnout.h" ItemScrollBox::ItemScrollBox(QWidget *parent) : QWidget(parent), @@ -17,24 +20,40 @@ ItemScrollBox::~ItemScrollBox() void ItemScrollBox::addItem(std::weak_ptr item) { - static int lifetimeNum = 0; if(auto workItem = item.lock()) { widgets_.push_back(new ItemWidget(item, this)); - if(lifetimeNum == 0) - widgets_.back()->setShortcuts(QKeySequence(Qt::Key_Q), QKeySequence(Qt::Key_A), QKeySequence(Qt::Key_Z)); - else if(lifetimeNum == 1) - widgets_.back()->setShortcuts(QKeySequence(Qt::Key_W), QKeySequence(Qt::Key_S), QKeySequence(Qt::Key_X)); - else if(lifetimeNum == 2) - widgets_.back()->setShortcuts(QKeySequence(Qt::Key_E), QKeySequence(Qt::Key_D), QKeySequence(Qt::Key_C)); - else if(lifetimeNum == 3) - widgets_.back()->setShortcuts(QKeySequence(Qt::Key_R), QKeySequence(Qt::Key_F), QKeySequence(Qt::Key_V)); - else if(lifetimeNum == 4) - widgets_.back()->setShortcuts(QKeySequence(Qt::Key_T), QKeySequence(Qt::Key_G), QKeySequence(Qt::Key_B)); + Train* train = dynamic_cast(workItem.get()); + Turnout* turnout = dynamic_cast(workItem.get()); + if(train) + { + if(train->getTrainId() == 0) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_Q), QKeySequence(Qt::Key_A), QKeySequence(Qt::Key_Z)); + else if(train->getTrainId() == 1) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_W), QKeySequence(Qt::Key_S), QKeySequence(Qt::Key_X)); + else if(train->getTrainId() == 2) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_E), QKeySequence(Qt::Key_D), QKeySequence(Qt::Key_C)); + else if(train->getTrainId() == 3) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_R), QKeySequence(Qt::Key_F), QKeySequence(Qt::Key_V)); + else if(train->getTrainId() == 4) + widgets_.back()->setShortcuts(QKeySequence(Qt::Key_T), QKeySequence(Qt::Key_G), QKeySequence(Qt::Key_B)); + } + else if(turnout) + { + if(turnout->getTurnoutId() == 0) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_1)); + else if(turnout->getTurnoutId() == 1) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_2)); + else if(turnout->getTurnoutId() == 2) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_3)); + else if(turnout->getTurnoutId() == 3) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_4)); + else if(turnout->getTurnoutId() == 4) + widgets_.back()->setShortcuts(QKeySequence(), QKeySequence(), QKeySequence(Qt::Key_5)); + } ui->relayWidgetVbox->addWidget(widgets_.back()); connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest); connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem); - lifetimeNum++; } } diff --git a/src/ui/itemwidget.cpp b/src/ui/itemwidget.cpp index 30fd342..94a27e2 100644 --- a/src/ui/itemwidget.cpp +++ b/src/ui/itemwidget.cpp @@ -5,6 +5,7 @@ #include #include #include "../items/train.h" +#include "../items/turnout.h" ItemWidget::ItemWidget(std::weak_ptr item, QWidget *parent) : QWidget(parent), @@ -23,14 +24,29 @@ ItemWidget::ItemWidget(std::weak_ptr item, QWidget *parent) : connect(ui->checkBox_f3, &QCheckBox::stateChanged, this, &ItemWidget::f3); connect(ui->checkBox_f4, &QCheckBox::stateChanged, this, &ItemWidget::f4); connect(ui->pushButton_reverse, &QPushButton::clicked, this, &ItemWidget::reverse); + connect(ui->radioButton_left, &QRadioButton::clicked, this, [this](){moveToValue(0);}); + connect(ui->radioButton_right, &QRadioButton::clicked, this, [this](){moveToValue(1);}); Train* train = dynamic_cast(workingRelay.get()); - if(!train) - { + Turnout* turnout = dynamic_cast(workingRelay.get()); + + if(turnout) + { + ui->checkBox_f1->hide(); + ui->checkBox_f2->hide(); + ui->checkBox_f3->hide(); + ui->checkBox_f4->hide(); + ui->slider->hide(); + } + + if(!train) + { ui->pushButton_reverse->hide(); - } - else - { + } + else + { + ui->radioButton_left->hide(); + ui->radioButton_right->hide(); uint8_t functionMask = train->getFunctionMask(); if(!(functionMask & (1 << 0))) ui->checkBox_f1->hide(); @@ -40,8 +56,7 @@ ItemWidget::ItemWidget(std::weak_ptr item, QWidget *parent) : ui->checkBox_f3->hide(); if(!(functionMask & (1 << 3))) ui->checkBox_f4->hide(); - } - + } } else disable(); } @@ -56,11 +71,21 @@ void ItemWidget::deleteItem() void ItemWidget::moveToValue(int value) { - qDebug()<<__func__; + ui->slider->blockSignals(true); + ui->radioButton_left->blockSignals(true); + ui->radioButton_right->blockSignals(true); + ui->pushButton_reverse->setDisabled(value != 0); + ui->slider->setValue(value); + ui->radioButton_left->setChecked(!value); + ui->radioButton_right->setChecked(value); if(auto workingItem = item_.lock()) workingItem->setValue(value); else disable(); + + ui->slider->blockSignals(false); + ui->radioButton_left->blockSignals(false); + ui->radioButton_right->blockSignals(false); } void ItemWidget::f1(int value) @@ -97,10 +122,13 @@ void ItemWidget::reverse() if(auto workingItem = item_.lock()) { Train* train = dynamic_cast(workingItem.get()); - if(train && ui->slider->value() == 0) + if(train && workingItem->getValue() == 0) train->reverse(); else - ui->slider->setValue(0); + { + qDebug()<<"!((bool)workingItem->getValue()) "<getValue()); + moveToValue(!((bool)workingItem->getValue())); + } } else disable(); } @@ -130,14 +158,17 @@ bool ItemWidget::controles(const ItemData& relay) void ItemWidget::stepUp() { - ui->slider->setValue(ui->slider->value()+1); + moveToValue(ui->slider->value()+1); } void ItemWidget::stepDown() { if(ui->slider->value() == 0) + { moveToValue(0); - ui->slider->setValue(ui->slider->value()-1); + return; + } + moveToValue(ui->slider->value()-1); } void ItemWidget::setShortcuts(QKeySequence up, QKeySequence down, QKeySequence rev) diff --git a/src/ui/itemwidget.ui b/src/ui/itemwidget.ui index 56024d7..7283a26 100644 --- a/src/ui/itemwidget.ui +++ b/src/ui/itemwidget.ui @@ -6,7 +6,7 @@ 0 0 - 264 + 280 83 @@ -67,6 +67,23 @@ + + + + Left + + + true + + + + + + + Right + + + diff --git a/trainControllerUI.pro b/trainControllerUI.pro index 56f69b7..3ecf230 100644 --- a/trainControllerUI.pro +++ b/trainControllerUI.pro @@ -4,9 +4,7 @@ # #------------------------------------------------- -QT += core gui widgets network multimedia - -QT += serialport +QT += core gui widgets network serialport TARGET = traincontrollerui TEMPLATE = app @@ -25,6 +23,7 @@ QMAKE_CXXFLAGS += -std=c++17 -O2 SOURCES += \ src/items/train.cpp \ + src/items/turnout.cpp \ src/mainobject.cpp \ src/ui/itemwidget.cpp \ src/ui/itemscrollbox.cpp \ @@ -36,6 +35,7 @@ SOURCES += \ HEADERS += \ src/items/train.h \ + src/items/turnout.h \ src/mainobject.h \ src/ui/itemwidget.h \ src/ui/itemscrollbox.h \