diff --git a/LICENSE.md b/LICENSE.md index 30b0c28..ca6dd34 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,5 +1,5 @@ ## MIT License -Copyright 2023 Alexandr Ananev [mail@ananev.org] +Copyright 2024 Alexandr Ananev [mail@ananev.org] Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 7b64aa2..f83920d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ # Open ModScan Open ModScan is a free implimentation of modbus master (client) utility for modbus-tcp and modbus-rtu protocols. -![image](https://github.com/sanny32/OpenModScan/assets/13627951/aa912ece-4b76-44b4-9523-5b0b0156a64b) +![image](https://github.com/sanny32/OpenModScan/assets/13627951/c2df0ea1-0f27-4d4b-8cc0-b6268caf8f11) -![image](https://github.com/sanny32/OpenModScan/assets/13627951/77bee5d8-09a8-4845-8d64-02b7bf3cf592) + +![image](https://github.com/sanny32/OpenModScan/assets/13627951/2e24982e-3b32-4434-928e-6518505e48ae) + ## Features @@ -28,7 +30,8 @@ Registers Modbus Logging -![image](https://github.com/sanny32/OpenModScan/assets/13627951/b3e43b25-ea7b-4beb-96c9-c7b9d6a65a03) +![image](https://github.com/sanny32/OpenModScan/assets/13627951/69de27f0-b09b-4587-8493-6d1908610735) + ## Extended Featues @@ -52,7 +55,7 @@ Modbus Logging Now building is available with Qt/qmake (version 5.15 and above) or Qt Creator. Supports both OS Microsoft Windows and Linux. ## MIT License -Copyright 2023 Alexandr Ananev [mail@ananev.org] +Copyright 2024 Alexandr Ananev [mail@ananev.org] Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/omodscan/controls/bytelisttextedit.cpp b/omodscan/controls/bytelisttextedit.cpp index 3973280..a8ecab2 100644 --- a/omodscan/controls/bytelisttextedit.cpp +++ b/omodscan/controls/bytelisttextedit.cpp @@ -67,17 +67,17 @@ void ByteListTextEdit::setValue(const QByteArray& value) { case DecMode: { - const auto text = formatByteArray(DataDisplayMode::Decimal, value); + const auto text = formatUInt8Array(DataDisplayMode::UInt16, value); if(text != toPlainText()) - setPlainText(formatByteArray(DataDisplayMode::Decimal, value)); + setPlainText(formatUInt8Array(DataDisplayMode::UInt16, value)); } break; case HexMode: { - const auto text = formatByteArray(DataDisplayMode::Hex, value); + const auto text = formatUInt8Array(DataDisplayMode::Hex, value); if(text != toPlainText()) - setPlainText(formatByteArray(DataDisplayMode::Hex, value)); + setPlainText(formatUInt8Array(DataDisplayMode::Hex, value)); } break; } diff --git a/omodscan/controls/modbusmessagewidget.cpp b/omodscan/controls/modbusmessagewidget.cpp index eac9a27..e89df8d 100644 --- a/omodscan/controls/modbusmessagewidget.cpp +++ b/omodscan/controls/modbusmessagewidget.cpp @@ -12,7 +12,7 @@ ModbusMessageWidget::ModbusMessageWidget(QWidget *parent) : QListWidget(parent) ,_statusClr(Qt::red) ,_byteOrder(ByteOrder::LittleEndian) - ,_dataDisplayMode(DataDisplayMode::Decimal) + ,_dataDisplayMode(DataDisplayMode::UInt16) ,_showTimestamp(true) ,_mm(nullptr) { @@ -150,14 +150,14 @@ void ModbusMessageWidget::update() if(_mm->protocolType() == ModbusMessage::Rtu) { auto adu = reinterpret_cast(_mm->adu()); - const auto checksum = formatWordValue(_dataDisplayMode, adu->checksum()); + const auto checksum = formatUInt16Value(_dataDisplayMode, adu->checksum()); if(adu->matchingChecksum()) { addItem(tr("Checksum: %1").arg(checksum)); } else { - const auto calcChecksum = formatWordValue(_dataDisplayMode, adu->calcChecksum()); + const auto calcChecksum = formatUInt16Value(_dataDisplayMode, adu->calcChecksum()); addItem(tr("Checksum: %1 (Expected: %2)").arg(checksum, calcChecksum, _statusClr.name())); } } @@ -169,20 +169,20 @@ void ModbusMessageWidget::update() if(_mm->protocolType() == ModbusMessage::Tcp) { auto adu = reinterpret_cast(_mm->adu()); - const auto transactionId = adu->isValid() ? formatWordValue(_dataDisplayMode, adu->transactionId()) : "??"; - const auto protocolId = adu->isValid() ? formatWordValue(_dataDisplayMode, adu->protocolId()): "??"; - const auto length = adu->isValid() ? formatWordValue(_dataDisplayMode, adu->length()): "??"; + const auto transactionId = adu->isValid() ? formatUInt16Value(_dataDisplayMode, adu->transactionId()) : "??"; + const auto protocolId = adu->isValid() ? formatUInt16Value(_dataDisplayMode, adu->protocolId()): "??"; + const auto length = adu->isValid() ? formatUInt16Value(_dataDisplayMode, adu->length()): "??"; addItem(tr("Transaction ID: %1").arg(transactionId)); addItem(tr("Protocol ID: %1").arg(protocolId)); addItem(tr("Length: %1").arg(length)); } - addItem(tr("Device ID: %1").arg(formatByteValue(_dataDisplayMode, _mm->deviceId()))); + addItem(tr("Device ID: %1").arg(formatUInt8Value(_dataDisplayMode, _mm->deviceId()))); if(_mm->isException()) { - const auto exception = QString("%1 (%2)").arg(formatByteValue(_dataDisplayMode, _mm->exception()), _mm->exception()); - addItem(tr("Error Code: %1").arg(formatByteValue(_dataDisplayMode, _mm->function()))); + const auto exception = QString("%1 (%2)").arg(formatUInt8Value(_dataDisplayMode, _mm->exception()), _mm->exception()); + addItem(tr("Error Code: %1").arg(formatUInt8Value(_dataDisplayMode, _mm->function()))); addItem(tr("Exception Code: %1").arg(exception)); addChecksum(); return; @@ -190,8 +190,8 @@ void ModbusMessageWidget::update() const auto func = _mm->function(); const auto function = func.isValid() ? - QString("%1 (%2)").arg(formatByteValue(_dataDisplayMode, func), func) : - formatByteValue(_dataDisplayMode, func); + QString("%1 (%2)").arg(formatUInt8Value(_dataDisplayMode, func), func) : + formatUInt8Value(_dataDisplayMode, func); addItem(tr("Function Code: %1").arg(function)); switch(_mm->function()) @@ -200,16 +200,16 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto startAddress = req->isValid() ? formatWordValue(_dataDisplayMode, req->startAddress()) : "??"; - const auto length = req->isValid() ? formatWordValue(_dataDisplayMode, req->length()): "??"; + const auto startAddress = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->startAddress()) : "??"; + const auto length = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->length()): "??"; addItem(tr("Start Address: %1").arg(startAddress)); addItem(tr("Length: %1").arg(length)); } else { auto resp = reinterpret_cast(_mm); - const auto byteCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->byteCount()) : "?"; - const auto coilStatus = resp->isValid() ? formatByteArray(_dataDisplayMode, resp->coilStatus()) : "???"; + const auto byteCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->byteCount()) : "?"; + const auto coilStatus = resp->isValid() ? formatUInt8Array(_dataDisplayMode, resp->coilStatus()) : "???"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("Coil Status: %1").arg(coilStatus)); } @@ -219,16 +219,16 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto startAddress = req->isValid() ? formatWordValue(_dataDisplayMode, req->startAddress()) : "??"; - const auto length = req->isValid() ? formatWordValue(_dataDisplayMode, req->length()): "??"; + const auto startAddress = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->startAddress()) : "??"; + const auto length = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->length()): "??"; addItem(tr("Start Address: %1").arg(startAddress)); addItem(tr("Length: %1").arg(length)); } else { auto resp = reinterpret_cast(_mm); - const auto byteCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->byteCount()) : "?"; - const auto inputStatus = resp->isValid() ? formatByteArray(_dataDisplayMode, resp->inputStatus()) : "???"; + const auto byteCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->byteCount()) : "?"; + const auto inputStatus = resp->isValid() ? formatUInt8Array(_dataDisplayMode, resp->inputStatus()) : "???"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("Input Status: %1").arg(inputStatus)); } @@ -238,16 +238,16 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto startAddress = req->isValid() ? formatWordValue(_dataDisplayMode, req->startAddress()) : "??"; - const auto length = req->isValid() ? formatWordValue(_dataDisplayMode, req->length()): "??"; + const auto startAddress = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->startAddress()) : "??"; + const auto length = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->length()): "??"; addItem(tr("Start Address: %1").arg(startAddress)); addItem(tr("Length: %1").arg(length)); } else { auto resp = reinterpret_cast(_mm); - const auto byteCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->byteCount()) : "?"; - const auto registerValue = resp->isValid() ? formatWordArray(_dataDisplayMode, resp->registerValue(), _byteOrder) : "???"; + const auto byteCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->byteCount()) : "?"; + const auto registerValue = resp->isValid() ? formatUInt16Array(_dataDisplayMode, resp->registerValue(), _byteOrder) : "???"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("Register Value: %1").arg(registerValue)); } @@ -257,16 +257,16 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto startAddress = req->isValid() ? formatWordValue(_dataDisplayMode, req->startAddress()) : "??"; - const auto length = req->isValid() ? formatWordValue(_dataDisplayMode, req->length()): "??"; + const auto startAddress = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->startAddress()) : "??"; + const auto length = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->length()): "??"; addItem(tr("Start Address: %1").arg(startAddress)); addItem(tr("Length: %1").arg(length)); } else { auto resp = reinterpret_cast(_mm); - const auto byteCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->byteCount()) : "?"; - const auto registerValue = resp->isValid() ? formatWordArray(_dataDisplayMode, resp->registerValue(), _byteOrder) : "???"; + const auto byteCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->byteCount()) : "?"; + const auto registerValue = resp->isValid() ? formatUInt16Array(_dataDisplayMode, resp->registerValue(), _byteOrder) : "???"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("Input Registers: %1").arg(registerValue)); } @@ -276,16 +276,16 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto outputAddress = req->isValid() ? formatWordValue(_dataDisplayMode, req->address()) : "??"; - const auto outputValue = req->isValid() ? formatWordValue(_dataDisplayMode, req->value()) : "??"; + const auto outputAddress = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->address()) : "??"; + const auto outputValue = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->value()) : "??"; addItem(tr("Output Address: %1").arg(outputAddress)); addItem(tr("Output Value: %1").arg(outputValue)); } else { auto resp = reinterpret_cast(_mm); - const auto outputAddress = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->address()) : "??"; - const auto outputValue = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->value()) : "??"; + const auto outputAddress = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->address()) : "??"; + const auto outputValue = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->value()) : "??"; addItem(tr("Output Address: %1").arg(outputAddress)); addItem(tr("Output Value: %1").arg(outputValue)); } @@ -295,16 +295,16 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto registerAddress = req->isValid() ? formatWordValue(_dataDisplayMode, req->address()) : "??"; - const auto registerValue = req->isValid() ? formatWordValue(_dataDisplayMode, req->value()) : "??"; + const auto registerAddress = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->address()) : "??"; + const auto registerValue = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->value()) : "??"; addItem(tr("Register Address: %1").arg(registerAddress)); addItem(tr("Register Value: %1").arg(registerValue)); } else { auto resp = reinterpret_cast(_mm); - const auto registerAddress = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->address()) : "??"; - const auto registerValue = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->value()) : "??"; + const auto registerAddress = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->address()) : "??"; + const auto registerValue = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->value()) : "??"; addItem(tr("Register Address: %1").arg(registerAddress)); addItem(tr("Register Value: %1").arg(registerValue)); } @@ -314,7 +314,7 @@ void ModbusMessageWidget::update() if(!_mm->isRequest()) { auto resp = reinterpret_cast(_mm); - const auto outputData = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->outputData()) : "?"; + const auto outputData = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->outputData()) : "?"; addItem(tr("Output Data: %1").arg(outputData)); } break; @@ -323,16 +323,16 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto subFunc = req->isValid() ? formatWordValue(_dataDisplayMode, req->subfunc()) : "??"; - const auto data = req->isValid() ? formatByteArray(_dataDisplayMode, req->data()) : "???"; + const auto subFunc = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->subfunc()) : "??"; + const auto data = req->isValid() ? formatUInt8Array(_dataDisplayMode, req->data()) : "???"; addItem(tr("Sub-function: %1").arg(subFunc)); addItem(tr("Data: %1").arg(data)); } else { auto resp = reinterpret_cast(_mm); - const auto subFunc = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->subfunc()) : "??"; - const auto data = resp->isValid() ? formatByteArray(_dataDisplayMode, resp->data()) : "???"; + const auto subFunc = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->subfunc()) : "??"; + const auto data = resp->isValid() ? formatUInt8Array(_dataDisplayMode, resp->data()) : "???"; addItem(tr("Sub-function: %1").arg(subFunc)); addItem(tr("Data: %1").arg(data)); } @@ -342,8 +342,8 @@ void ModbusMessageWidget::update() if(!_mm->isRequest()) { auto resp = reinterpret_cast(_mm); - const auto status = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->status()) : "??"; - const auto eventCount = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->eventCount()) : "??"; + const auto status = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->status()) : "??"; + const auto eventCount = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->eventCount()) : "??"; addItem(tr("Status: %1").arg(status)); addItem(tr("Event Count: %1").arg(eventCount)); } @@ -353,11 +353,11 @@ void ModbusMessageWidget::update() if(!_mm->isRequest()) { auto resp = reinterpret_cast(_mm); - const auto byteCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->byteCount()) : "?"; - const auto status = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->status()) : "??"; - const auto eventCount = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->eventCount()) : "??"; - const auto messageCount = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->messageCount()) : "??"; - const auto events = resp->isValid() ? formatByteArray(_dataDisplayMode, resp->events()) : "???"; + const auto byteCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->byteCount()) : "?"; + const auto status = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->status()) : "??"; + const auto eventCount = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->eventCount()) : "??"; + const auto messageCount = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->messageCount()) : "??"; + const auto events = resp->isValid() ? formatUInt8Array(_dataDisplayMode, resp->events()) : "???"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("Status: %1").arg(status)); addItem(tr("Event Count: %1").arg(eventCount)); @@ -370,10 +370,10 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto startAddr = req->isValid() ? formatWordValue(_dataDisplayMode, req->startAddress()) : "??"; - const auto quantity = req->isValid() ? formatWordValue(_dataDisplayMode, req->quantity()) : "??"; - const auto byteCount = req->isValid() ? formatByteValue(_dataDisplayMode, req->byteCount()) : "?"; - const auto values = req->isValid() ? formatByteArray(_dataDisplayMode, req->values()) : "???"; + const auto startAddr = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->startAddress()) : "??"; + const auto quantity = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->quantity()) : "??"; + const auto byteCount = req->isValid() ? formatUInt8Value(_dataDisplayMode, req->byteCount()) : "?"; + const auto values = req->isValid() ? formatUInt8Array(_dataDisplayMode, req->values()) : "???"; addItem(tr("Starting Address: %1").arg(startAddr)); addItem(tr("Quantity of Outputs: %1").arg(quantity)); addItem(tr("Byte Count: %1").arg(byteCount)); @@ -382,8 +382,8 @@ void ModbusMessageWidget::update() else { auto resp = reinterpret_cast(_mm); - const auto startAddr = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->startAddress()) : "??"; - const auto quantity = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->quantity()) : "??"; + const auto startAddr = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->startAddress()) : "??"; + const auto quantity = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->quantity()) : "??"; addItem(tr("Starting Address: %1").arg(startAddr)); addItem(tr("Quantity of Outputs: %1").arg(quantity)); } @@ -393,10 +393,10 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto startAddr = req->isValid() ? formatWordValue(_dataDisplayMode, req->startAddress()) : "??"; - const auto quantity = req->isValid() ? formatWordValue(_dataDisplayMode, req->quantity()) : "??"; - const auto byteCount = req->isValid() ? formatByteValue(_dataDisplayMode, req->byteCount()) : "?"; - const auto values = req->isValid() ? formatWordArray(_dataDisplayMode, req->values(), _byteOrder) : "???"; + const auto startAddr = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->startAddress()) : "??"; + const auto quantity = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->quantity()) : "??"; + const auto byteCount = req->isValid() ? formatUInt8Value(_dataDisplayMode, req->byteCount()) : "?"; + const auto values = req->isValid() ? formatUInt16Array(_dataDisplayMode, req->values(), _byteOrder) : "???"; addItem(tr("Starting Address: %1").arg(startAddr)); addItem(tr("Quantity of Registers: %1").arg(quantity)); addItem(tr("Byte Count: %1").arg(byteCount)); @@ -405,8 +405,8 @@ void ModbusMessageWidget::update() else { auto resp = reinterpret_cast(_mm); - const auto startAddr = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->startAddress()) : "??"; - const auto quantity = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->quantity()) : "??"; + const auto startAddr = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->startAddress()) : "??"; + const auto quantity = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->quantity()) : "??"; addItem(tr("Starting Address: %1").arg(startAddr)); addItem(tr("Quantity of Registers: %1").arg(quantity)); } @@ -416,8 +416,8 @@ void ModbusMessageWidget::update() if(!_mm->isRequest()) { auto resp = reinterpret_cast(_mm); - const auto byteCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->byteCount()) : "?"; - const auto data = resp->isValid() ? formatByteArray(_dataDisplayMode, resp->data()) : "?"; + const auto byteCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->byteCount()) : "?"; + const auto data = resp->isValid() ? formatUInt8Array(_dataDisplayMode, resp->data()) : "?"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("Data: %1").arg(data)); } @@ -427,16 +427,16 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto byteCount = req->isValid() ? formatByteValue(_dataDisplayMode, req->byteCount()) : "?"; - const auto data = req->isValid() ? formatByteArray(_dataDisplayMode, req->data()) : "?"; + const auto byteCount = req->isValid() ? formatUInt8Value(_dataDisplayMode, req->byteCount()) : "?"; + const auto data = req->isValid() ? formatUInt8Array(_dataDisplayMode, req->data()) : "?"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("Data: %1").arg(data)); } else { auto resp = reinterpret_cast(_mm); - const auto byteCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->byteCount()) : "?"; - const auto data = resp->isValid() ? formatByteArray(_dataDisplayMode, resp->data()) : "?"; + const auto byteCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->byteCount()) : "?"; + const auto data = resp->isValid() ? formatUInt8Array(_dataDisplayMode, resp->data()) : "?"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("Data: %1").arg(data)); } @@ -446,16 +446,16 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto length = req->isValid() ? formatByteValue(_dataDisplayMode, req->length()) : "?"; - const auto data = req->isValid() ? formatByteArray(_dataDisplayMode, req->data()) : "???"; + const auto length = req->isValid() ? formatUInt8Value(_dataDisplayMode, req->length()) : "?"; + const auto data = req->isValid() ? formatUInt8Array(_dataDisplayMode, req->data()) : "???"; addItem(tr("Request Data Length: %1").arg(length)); addItem(tr("Data: %1").arg(data)); } else { auto resp = reinterpret_cast(_mm); - const auto length = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->length()) : "?"; - const auto data = resp->isValid() ? formatByteArray(_dataDisplayMode, resp->data()) : "???"; + const auto length = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->length()) : "?"; + const auto data = resp->isValid() ? formatUInt8Array(_dataDisplayMode, resp->data()) : "???"; addItem(tr("Response Data Length: %1").arg(length)); addItem(tr("Data: %1").arg(data)); } @@ -465,9 +465,9 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto address = req->isValid() ? formatWordValue(_dataDisplayMode, req->address()) : "??"; - const auto andMask = req->isValid() ? formatWordValue(_dataDisplayMode, req->andMask()) : "??"; - const auto orMask = req->isValid() ? formatWordValue(_dataDisplayMode, req->orMask()) : "??"; + const auto address = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->address()) : "??"; + const auto andMask = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->andMask()) : "??"; + const auto orMask = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->orMask()) : "??"; addItem(tr("Address: %1").arg(address)); addItem(tr("And Mask: %1").arg(andMask)); addItem(tr("Or Mask: %1").arg(orMask)); @@ -475,9 +475,9 @@ void ModbusMessageWidget::update() else { auto resp = reinterpret_cast(_mm); - const auto address = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->address()) : "??"; - const auto andMask = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->andMask()) : "??"; - const auto orMask = resp->isValid() ? formatWordValue(_dataDisplayMode, resp->orMask()) : "??"; + const auto address = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->address()) : "??"; + const auto andMask = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->andMask()) : "??"; + const auto orMask = resp->isValid() ? formatUInt16Value(_dataDisplayMode, resp->orMask()) : "??"; addItem(tr("Address: %1").arg(address)); addItem(tr("And Mask: %1").arg(andMask)); addItem(tr("Or Mask: %1").arg(orMask)); @@ -488,12 +488,12 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto readStartAddr = req->isValid() ? formatWordValue(_dataDisplayMode, req->readStartAddress()) : "??"; - const auto readLength = req->isValid() ? formatWordValue(_dataDisplayMode, req->readLength()) : "??"; - const auto writeStartAddr = req->isValid() ? formatWordValue(_dataDisplayMode, req->writeStartAddress()) : "??"; - const auto writeLength = req->isValid() ? formatWordValue(_dataDisplayMode, req->writeLength()) : "??"; - const auto writeByteCount = req->isValid() ? formatByteValue(_dataDisplayMode, req->writeByteCount()) : "?"; - const auto writeValues = req->isValid() ? formatWordArray(_dataDisplayMode, req->writeValues(), _byteOrder) : "???"; + const auto readStartAddr = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->readStartAddress()) : "??"; + const auto readLength = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->readLength()) : "??"; + const auto writeStartAddr = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->writeStartAddress()) : "??"; + const auto writeLength = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->writeLength()) : "??"; + const auto writeByteCount = req->isValid() ? formatUInt8Value(_dataDisplayMode, req->writeByteCount()) : "?"; + const auto writeValues = req->isValid() ? formatUInt16Array(_dataDisplayMode, req->writeValues(), _byteOrder) : "???"; addItem(tr("Read Starting Address: %1").arg(readStartAddr)); addItem(tr("Quantity to Read: %1").arg(readLength)); addItem(tr("Write Starting Address: %1").arg(writeStartAddr)); @@ -504,8 +504,8 @@ void ModbusMessageWidget::update() else { auto resp = reinterpret_cast(_mm); - const auto byteCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->byteCount()): "?"; - const auto values = resp->isValid() ? formatWordArray(_dataDisplayMode, resp->values(), _byteOrder) : "???"; + const auto byteCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->byteCount()): "?"; + const auto values = resp->isValid() ? formatUInt16Array(_dataDisplayMode, resp->values(), _byteOrder) : "???"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("Registers Value: %1").arg(values)); } @@ -515,15 +515,15 @@ void ModbusMessageWidget::update() if(_mm->isRequest()) { auto req = reinterpret_cast(_mm); - const auto fifoAddr = req->isValid() ? formatWordValue(_dataDisplayMode, req->fifoAddress()) : "??"; + const auto fifoAddr = req->isValid() ? formatUInt16Value(_dataDisplayMode, req->fifoAddress()) : "??"; addItem(tr("FIFO Point Address: %1").arg(fifoAddr)); } else { auto resp = reinterpret_cast(_mm); - const auto byteCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->byteCount()) : "?"; - const auto fifoCount = resp->isValid() ? formatByteValue(_dataDisplayMode, resp->fifoCount()) : "?"; - const auto fifoValue = resp->isValid() ? formatWordArray(_dataDisplayMode, resp->fifoValue(), _byteOrder) : "???"; + const auto byteCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->byteCount()) : "?"; + const auto fifoCount = resp->isValid() ? formatUInt8Value(_dataDisplayMode, resp->fifoCount()) : "?"; + const auto fifoValue = resp->isValid() ? formatUInt16Array(_dataDisplayMode, resp->fifoValue(), _byteOrder) : "???"; addItem(tr("Byte Count: %1").arg(byteCount)); addItem(tr("FIFO Count: %1").arg(fifoCount)); addItem(tr("FIFO Value Register: %1").arg(fifoValue)); @@ -532,7 +532,7 @@ void ModbusMessageWidget::update() default: { - const auto data = _mm->isValid() ? formatByteArray(_dataDisplayMode, _mm->rawData()) : "???"; + const auto data = _mm->isValid() ? formatUInt8Array(_dataDisplayMode, _mm->rawData()) : "???"; addItem(tr("Data: %1").arg(data)); } break; diff --git a/omodscan/controls/numericlineedit.cpp b/omodscan/controls/numericlineedit.cpp index 6785ef1..d6b04c3 100644 --- a/omodscan/controls/numericlineedit.cpp +++ b/omodscan/controls/numericlineedit.cpp @@ -3,6 +3,7 @@ #include #include "qhexvalidator.h" #include "quintvalidator.h" +#include "qint64validator.h" #include "numericlineedit.h" /// @@ -14,7 +15,7 @@ NumericLineEdit::NumericLineEdit(QWidget* parent) ,_paddingZeroes(false) ,_paddingZeroWidth(0) { - setInputMode(DecMode); + setInputMode(Int32Mode); setValue(0); connect(this, &QLineEdit::editingFinished, this, &NumericLineEdit::on_editingFinished); @@ -78,14 +79,14 @@ void NumericLineEdit::setInputMode(InputMode mode) { switch(mode) { - case DecMode: + case Int32Mode: case HexMode: _minValue = INT_MIN; _maxValue = INT_MAX; break; - case UnsignedMode: - _minValue = 0U; + case UInt32Mode: + _minValue = 0; _maxValue = UINT_MAX; break; @@ -98,6 +99,16 @@ void NumericLineEdit::setInputMode(InputMode mode) _minValue = -DBL_MAX; _maxValue = DBL_MAX; break; + + case Int64Mode: + _minValue = QVariant::fromValue(INT64_MIN); + _maxValue = QVariant::fromValue(INT64_MAX); + break; + + case UInt64Mode: + _minValue = 0; + _maxValue = QVariant::fromValue(UINT64_MAX); + break; } } emit rangeChanged(_minValue, _maxValue); @@ -121,7 +132,7 @@ void NumericLineEdit::internalSetValue(QVariant value) { switch(_inputMode) { - case DecMode: + case Int32Mode: value = qBound(_minValue.toInt(), value.toInt(), _maxValue.toInt()); if(_paddingZeroes) { @@ -137,7 +148,7 @@ void NumericLineEdit::internalSetValue(QVariant value) } break; - case UnsignedMode: + case UInt32Mode: value = qBound(_minValue.toUInt(), value.toUInt(), _maxValue.toUInt()); if(_paddingZeroes) { @@ -189,6 +200,42 @@ void NumericLineEdit::internalSetValue(QVariant value) QLineEdit::setText(text); } break; + + case Int64Mode: + { + value = qBound(_minValue.toLongLong(), value.toLongLong(), _maxValue.toLongLong()); + if(_paddingZeroes) + { + const auto text = QStringLiteral("%1").arg(value.toLongLong(), _paddingZeroWidth, 10, QLatin1Char('0')); + if(text != QLineEdit::text()) + QLineEdit::setText(text); + } + else + { + const auto text = QString::number(value.toLongLong()); + if(text != QLineEdit::text()) + QLineEdit::setText(text); + } + } + break; + + case UInt64Mode: + { + value = qBound(_minValue.toULongLong(), value.toULongLong(), _maxValue.toULongLong()); + if(_paddingZeroes) + { + const auto text = QStringLiteral("%1").arg(value.toULongLong(), _paddingZeroWidth, 10, QLatin1Char('0')); + if(text != QLineEdit::text()) + QLineEdit::setText(text); + } + else + { + const auto text = QString::number(value.toULongLong()); + if(text != QLineEdit::text()) + QLineEdit::setText(text); + } + } + break; } if(value != _value) @@ -205,7 +252,7 @@ void NumericLineEdit::updateValue() { switch(_inputMode) { - case DecMode: + case Int32Mode: { bool ok; const auto value = text().toInt(&ok); @@ -214,7 +261,7 @@ void NumericLineEdit::updateValue() } break; - case UnsignedMode: + case UInt32Mode: { bool ok; const auto value = text().toUInt(&ok); @@ -249,6 +296,24 @@ void NumericLineEdit::updateValue() else internalSetValue(_value); } break; + + case Int64Mode: + { + bool ok; + const auto value = text().toLongLong(&ok); + if(ok) internalSetValue(value); + else internalSetValue(_value); + } + break; + + case UInt64Mode: + { + bool ok; + const auto value = text().toULongLong(&ok); + if(ok) internalSetValue(value); + else internalSetValue(_value); + } + break; } } @@ -297,7 +362,7 @@ void NumericLineEdit::on_textChanged(const QString& text) QVariant value; switch(_inputMode) { - case DecMode: + case Int32Mode: { bool ok; const auto valueInt = text.toInt(&ok); @@ -305,11 +370,11 @@ void NumericLineEdit::on_textChanged(const QString& text) } break; - case UnsignedMode: + case UInt32Mode: { bool ok; - const auto valueInt = text.toUInt(&ok); - if(ok) value = qBound(_minValue.toUInt(), valueInt, _maxValue.toUInt()); + const auto valueUInt = text.toUInt(&ok); + if(ok) value = qBound(_minValue.toUInt(), valueUInt, _maxValue.toUInt()); } break; @@ -336,6 +401,22 @@ void NumericLineEdit::on_textChanged(const QString& text) if(ok) value = qBound(_minValue.toDouble(), valueDouble, _maxValue.toDouble()); } break; + + case Int64Mode: + { + bool ok; + const auto valueLongLong = text.toLongLong(&ok); + if(ok) value = qBound(_minValue.toLongLong(), valueLongLong, _maxValue.toLongLong()); + } + break; + + case UInt64Mode: + { + bool ok; + const auto valueULongLong = text.toULongLong(&ok); + if(ok) value = qBound(_minValue.toULongLong(), valueULongLong, _maxValue.toULongLong()); + } + break; } if(value.isValid() && value != _value) @@ -356,7 +437,7 @@ void NumericLineEdit::on_rangeChanged(const QVariant& bottom, const QVariant& to setValidator(nullptr); switch(_inputMode) { - case DecMode: + case Int32Mode: { const int nums = QString::number(top.toInt()).length(); _paddingZeroWidth = qMax(1, nums); @@ -366,7 +447,7 @@ void NumericLineEdit::on_rangeChanged(const QVariant& bottom, const QVariant& to } break; - case UnsignedMode: + case UInt32Mode: { const int nums = QString::number(top.toUInt()).length(); _paddingZeroWidth = qMax(1, nums); @@ -389,6 +470,24 @@ void NumericLineEdit::on_rangeChanged(const QVariant& bottom, const QVariant& to setMaxLength(INT16_MAX); setValidator(new QDoubleValidator(bottom.toDouble(), top.toDouble(), 6, this)); break; + + case Int64Mode: + { + const int nums = QString::number(top.toLongLong()).length(); + _paddingZeroWidth = qMax(1, nums); + setMaxLength(qMax(1, nums)); + setValidator(new QInt64Validator(bottom.toLongLong(), top.toLongLong(), this)); + } + break; + + case UInt64Mode: + { + const int nums = QString::number(top.toULongLong()).length(); + _paddingZeroWidth = qMax(1, nums); + setMaxLength(qMax(1, nums)); + setValidator(new QUIntValidator(bottom.toULongLong(), top.toULongLong(), this)); + } + break; } internalSetValue(_value); blockSignals(false); diff --git a/omodscan/controls/numericlineedit.h b/omodscan/controls/numericlineedit.h index fb072e6..86867f2 100644 --- a/omodscan/controls/numericlineedit.h +++ b/omodscan/controls/numericlineedit.h @@ -13,11 +13,13 @@ class NumericLineEdit : public QLineEdit public: enum InputMode { - DecMode = 0, - UnsignedMode, + Int32Mode = 0, + UInt32Mode, HexMode, FloatMode, - DoubleMode + DoubleMode, + Int64Mode, + UInt64Mode }; explicit NumericLineEdit(QWidget* parent = nullptr); diff --git a/omodscan/controls/outputwidget.cpp b/omodscan/controls/outputwidget.cpp index 6c2fe3c..903b6f6 100644 --- a/omodscan/controls/outputwidget.cpp +++ b/omodscan/controls/outputwidget.cpp @@ -207,12 +207,12 @@ void OutputListModel::updateData(const QModbusDataUnit& data) itemData.ValueStr = formatBinaryValue(pointType, value, byteOrder, itemData.Value); break; - case DataDisplayMode::Decimal: - itemData.ValueStr = formatDecimalValue(pointType, value, byteOrder, itemData.Value); + case DataDisplayMode::UInt16: + itemData.ValueStr = formatUInt16Value(pointType, value, byteOrder, itemData.Value); break; - case DataDisplayMode::Integer: - itemData.ValueStr = formatIntegerValue(pointType, value, byteOrder, itemData.Value); + case DataDisplayMode::Int16: + itemData.ValueStr = formatInt16Value(pointType, value, byteOrder, itemData.Value); break; case DataDisplayMode::Hex: @@ -239,26 +239,47 @@ void OutputListModel::updateData(const QModbusDataUnit& data) byteOrder, (i%4) || (i+3>=rowCount()), itemData.Value); break; - case DataDisplayMode::LongInteger: - itemData.ValueStr = formatLongValue(pointType, value, _lastData.value(i+1), byteOrder, + case DataDisplayMode::Int32: + itemData.ValueStr = formatInt32Value(pointType, value, _lastData.value(i+1), byteOrder, (i%2) || (i+1>=rowCount()), itemData.Value); break; - case DataDisplayMode::SwappedLI: - itemData.ValueStr = formatLongValue(pointType, _lastData.value(i+1), value, byteOrder, + case DataDisplayMode::SwappedInt32: + itemData.ValueStr = formatInt32Value(pointType, _lastData.value(i+1), value, byteOrder, (i%2) || (i+1>=rowCount()), itemData.Value); break; - case DataDisplayMode::UnsignedLongInteger: - itemData.ValueStr = formatUnsignedLongValue(pointType, value, _lastData.value(i+1), byteOrder, + case DataDisplayMode::UInt32: + itemData.ValueStr = formatUInt32Value(pointType, value, _lastData.value(i+1), byteOrder, (i%2) || (i+1>=rowCount()), itemData.Value); break; - case DataDisplayMode::SwappedUnsignedLI: - itemData.ValueStr = formatUnsignedLongValue(pointType, _lastData.value(i+1), value, byteOrder, + case DataDisplayMode::SwappedUInt32: + itemData.ValueStr = formatUInt32Value(pointType, _lastData.value(i+1), value, byteOrder, (i%2) || (i+1>=rowCount()), itemData.Value); break; + + case DataDisplayMode::Int64: + itemData.ValueStr = formatInt64Value(pointType, value, _lastData.value(i+1), _lastData.value(i+2), _lastData.value(i+3), + byteOrder, (i%4) || (i+3>=rowCount()), itemData.Value); + break; + + case DataDisplayMode::SwappedInt64: + itemData.ValueStr = formatInt64Value(pointType, _lastData.value(i+3), _lastData.value(i+2), _lastData.value(i+1), value, + byteOrder, (i%4) || (i+3>=rowCount()), itemData.Value); + + break; + + case DataDisplayMode::UInt64: + itemData.ValueStr = formatUInt64Value(pointType, value, _lastData.value(i+1), _lastData.value(i+2), _lastData.value(i+3), + byteOrder, (i%4) || (i+3>=rowCount()), itemData.Value); + break; + + case DataDisplayMode::SwappedUInt64: + itemData.ValueStr = formatUInt64Value(pointType, _lastData.value(i+3), _lastData.value(i+2), _lastData.value(i+1), value, + byteOrder, (i%4) || (i+3>=rowCount()), itemData.Value); + break; } } @@ -565,10 +586,12 @@ void OutputWidget::paint(const QRect& rc, QPainter& painter) int cx = rc.left(); int cy = rcStatus.bottom(); + int maxWidth = 0; for(int i = 0; i < _listModel->rowCount(); ++i) { const auto text = _listModel->data(_listModel->index(i), Qt::DisplayRole).toString().trimmed(); auto rcItem = painter.boundingRect(cx, cy, rc.width() - cx, rc.height() - cy, Qt::TextSingleLine, text); + maxWidth = qMax(maxWidth, rcItem.width()); if(rcItem.right() > rc.right()) break; else if(rcItem.bottom() < rc.bottom()) @@ -578,7 +601,7 @@ void OutputWidget::paint(const QRect& rc, QPainter& painter) else { cy = rcStatus.bottom(); - cx = rcItem.right() + 10; + cx = rcItem.left() + maxWidth + 10; rcItem = painter.boundingRect(cx, cy, rc.width() - cx, rc.height() - cy, Qt::TextSingleLine, text); if(rcItem.right() > rc.right()) break; @@ -783,16 +806,20 @@ void OutputWidget::on_listView_doubleClicked(const QModelIndex& index) { case DataDisplayMode::FloatingPt: case DataDisplayMode::SwappedFP: - case DataDisplayMode::LongInteger: - case DataDisplayMode::SwappedLI: - case DataDisplayMode::UnsignedLongInteger: - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::Int32: + case DataDisplayMode::SwappedInt32: + case DataDisplayMode::UInt32: + case DataDisplayMode::SwappedUInt32: if(index.row() % 2) idx = _listModel->index(index.row() - 1); break; case DataDisplayMode::DblFloat: case DataDisplayMode::SwappedDbl: + case DataDisplayMode::Int64: + case DataDisplayMode::SwappedInt64: + case DataDisplayMode::UInt64: + case DataDisplayMode::SwappedUInt64: if(index.row() % 4) idx = _listModel->index(index.row() - index.row() % 4); break; diff --git a/omodscan/datasimulator.cpp b/omodscan/datasimulator.cpp index 73f1e86..38098d9 100644 --- a/omodscan/datasimulator.cpp +++ b/omodscan/datasimulator.cpp @@ -202,19 +202,19 @@ void DataSimulator::randomSimulation(DataDisplayMode mode, QModbusDataUnit::Regi switch(mode) { case DataDisplayMode::Binary: - case DataDisplayMode::Integer: - case DataDisplayMode::Decimal: + case DataDisplayMode::Int16: + case DataDisplayMode::UInt16: case DataDisplayMode::Hex: value = generateRandom(params.Range.from(), params.Range.to() + 1); break; - case DataDisplayMode::LongInteger: - case DataDisplayMode::SwappedLI: + case DataDisplayMode::Int32: + case DataDisplayMode::SwappedInt32: value = generateRandom(params.Range); break; - case DataDisplayMode::UnsignedLongInteger: - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::UInt32: + case DataDisplayMode::SwappedUInt32: value = generateRandom(params.Range); break; @@ -227,6 +227,16 @@ void DataSimulator::randomSimulation(DataDisplayMode mode, QModbusDataUnit::Regi case DataDisplayMode::SwappedDbl: value = generateRandom(params.Range); break; + + case DataDisplayMode::Int64: + case DataDisplayMode::SwappedInt64: + value = generateRandom(params.Range); + break; + + case DataDisplayMode::UInt64: + case DataDisplayMode::SwappedUInt64: + value = generateRandom(params.Range); + break; } break; @@ -258,23 +268,23 @@ void DataSimulator::incrementSimulation(DataDisplayMode mode, QModbusDataUnit::R auto&& value = _simulationMap[{ type, addr, deviceId}].CurrentValue; switch(mode) { - case DataDisplayMode::Integer: + case DataDisplayMode::Int16: value = incrementValue(value.toInt(), params.Step, params.Range); break; case DataDisplayMode::Binary: - case DataDisplayMode::Decimal: + case DataDisplayMode::UInt16: case DataDisplayMode::Hex: value = incrementValue(value.toUInt(), params.Step, params.Range); break; - case DataDisplayMode::LongInteger: - case DataDisplayMode::SwappedLI: + case DataDisplayMode::Int32: + case DataDisplayMode::SwappedInt32: value = incrementValue(value.toInt(), params.Step, params.Range); break; - case DataDisplayMode::UnsignedLongInteger: - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::UInt32: + case DataDisplayMode::SwappedUInt32: value = incrementValue(value.toUInt(), params.Step, params.Range); break; @@ -287,6 +297,16 @@ void DataSimulator::incrementSimulation(DataDisplayMode mode, QModbusDataUnit::R case DataDisplayMode::SwappedDbl: value = incrementValue(value.toDouble(), params.Step, params.Range); break; + + case DataDisplayMode::Int64: + case DataDisplayMode::SwappedInt64: + value = incrementValue(value.toLongLong(), params.Step, params.Range); + break; + + case DataDisplayMode::UInt64: + case DataDisplayMode::SwappedUInt64: + value = incrementValue(value.toULongLong(), params.Step, params.Range); + break; } if(value.isValid()) @@ -314,23 +334,23 @@ void DataSimulator::decrementSimailation(DataDisplayMode mode, QModbusDataUnit:: auto&& value = _simulationMap[{ type, addr, deviceId}].CurrentValue; switch(mode) { - case DataDisplayMode::Integer: + case DataDisplayMode::Int16: value = decrementValue(value.toInt(), params.Step, params.Range); break; case DataDisplayMode::Binary: - case DataDisplayMode::Decimal: + case DataDisplayMode::UInt16: case DataDisplayMode::Hex: value = decrementValue(value.toUInt(), params.Step, params.Range); break; - case DataDisplayMode::LongInteger: - case DataDisplayMode::SwappedLI: + case DataDisplayMode::Int32: + case DataDisplayMode::SwappedInt32: value = decrementValue(value.toInt(), params.Step, params.Range); break; - case DataDisplayMode::UnsignedLongInteger: - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::UInt32: + case DataDisplayMode::SwappedUInt32: value = decrementValue(value.toUInt(), params.Step, params.Range); break; @@ -343,6 +363,16 @@ void DataSimulator::decrementSimailation(DataDisplayMode mode, QModbusDataUnit:: case DataDisplayMode::SwappedDbl: value = decrementValue(value.toDouble(), params.Step, params.Range); break; + + case DataDisplayMode::Int64: + case DataDisplayMode::SwappedInt64: + value = decrementValue(value.toLongLong(), params.Step, params.Range); + break; + + case DataDisplayMode::UInt64: + case DataDisplayMode::SwappedUInt64: + value = decrementValue(value.toULongLong(), params.Step, params.Range); + break; } if(value.isValid()) diff --git a/omodscan/dialogs/dialogabout.ui b/omodscan/dialogs/dialogabout.ui index 8ac5d92..f887087 100644 --- a/omodscan/dialogs/dialogabout.ui +++ b/omodscan/dialogs/dialogabout.ui @@ -138,7 +138,7 @@ - © Alexandr Ananev, 2023 + © Alexandr Ananev, 2024 diff --git a/omodscan/dialogs/dialogaddressscan.cpp b/omodscan/dialogs/dialogaddressscan.cpp index 4ba245c..101fc15 100644 --- a/omodscan/dialogs/dialogaddressscan.cpp +++ b/omodscan/dialogs/dialogaddressscan.cpp @@ -58,7 +58,7 @@ QVariant TableViewItemModel::data(const QModelIndex &index, int role) const const auto value = _data.value(idx); const auto pointType = _data.registerType(); auto result = _hexView ? formatHexValue(pointType, value, _byteOrder, outValue) : - formatDecimalValue(pointType, value, _byteOrder, outValue); + formatUInt16Value(pointType, value, _byteOrder, outValue); return _data.hasValue(idx) ? result.remove('<').remove('>') : "-"; } @@ -208,7 +208,7 @@ QVariant LogViewModel::data(const QModelIndex& index, int role) const { case Qt::DisplayRole: { - const DataDisplayMode mode = _hexView ? DataDisplayMode::Hex : DataDisplayMode::Decimal; + const DataDisplayMode mode = _hexView ? DataDisplayMode::Hex : DataDisplayMode::UInt16; return QString("[%1] %2 [%3]").arg(formatAddress(item.Type, item.Addr, false), item.Msg->isRequest() ? "<<" : ">>", item.Msg->toString(mode)); diff --git a/omodscan/dialogs/dialogautosimulation.cpp b/omodscan/dialogs/dialogautosimulation.cpp index aa40f86..8e5dc78 100644 --- a/omodscan/dialogs/dialogautosimulation.cpp +++ b/omodscan/dialogs/dialogautosimulation.cpp @@ -31,33 +31,33 @@ DialogAutoSimulation::DialogAutoSimulation(DataDisplayMode mode, ModbusSimulatio case DataDisplayMode::Binary: break; - case DataDisplayMode::Decimal: + case DataDisplayMode::UInt16: ui->lineEditStepValue->setInputRange(1, USHRT_MAX - 1); ui->lineEditLowLimit->setInputRange(0, USHRT_MAX); ui->lineEditHighLimit->setInputRange(0, USHRT_MAX); break; - case DataDisplayMode::Integer: + case DataDisplayMode::Int16: ui->lineEditStepValue->setInputRange(1, SHRT_MAX - 1); ui->lineEditLowLimit->setInputRange(SHRT_MIN, SHRT_MAX); ui->lineEditHighLimit->setInputRange(SHRT_MIN, SHRT_MAX); break; - case DataDisplayMode::LongInteger: - case DataDisplayMode::SwappedLI: + case DataDisplayMode::Int32: + case DataDisplayMode::SwappedInt32: ui->lineEditStepValue->setInputRange(1, INT_MAX - 1); ui->lineEditLowLimit->setInputRange(INT_MIN, INT_MAX); ui->lineEditHighLimit->setInputRange(INT_MIN, INT_MAX); break; - case DataDisplayMode::UnsignedLongInteger: - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::UInt32: + case DataDisplayMode::SwappedUInt32: ui->lineEditStepValue->setInputRange(1U, UINT_MAX - 1); - ui->lineEditStepValue->setInputMode(NumericLineEdit::UnsignedMode); + ui->lineEditStepValue->setInputMode(NumericLineEdit::UInt32Mode); ui->lineEditLowLimit->setInputRange(0U, UINT_MAX); - ui->lineEditLowLimit->setInputMode(NumericLineEdit::UnsignedMode); + ui->lineEditLowLimit->setInputMode(NumericLineEdit::UInt32Mode); ui->lineEditHighLimit->setInputRange(0U, UINT_MAX); - ui->lineEditHighLimit->setInputMode(NumericLineEdit::UnsignedMode); + ui->lineEditHighLimit->setInputMode(NumericLineEdit::UInt32Mode); break; case DataDisplayMode::Hex: @@ -85,6 +85,26 @@ DialogAutoSimulation::DialogAutoSimulation(DataDisplayMode mode, ModbusSimulatio ui->lineEditLowLimit->setInputMode(NumericLineEdit::DoubleMode); ui->lineEditHighLimit->setInputMode(NumericLineEdit::DoubleMode); break; + + case DataDisplayMode::Int64: + case DataDisplayMode::SwappedInt64: + ui->lineEditStepValue->setInputRange(1, INT64_MAX - 1); + ui->lineEditStepValue->setInputMode(NumericLineEdit::Int64Mode); + ui->lineEditLowLimit->setInputRange(INT64_MIN, INT64_MAX); + ui->lineEditHighLimit->setInputRange(INT64_MIN, INT64_MAX); + ui->lineEditLowLimit->setInputMode(NumericLineEdit::Int64Mode); + ui->lineEditHighLimit->setInputMode(NumericLineEdit::Int64Mode); + break; + + case DataDisplayMode::UInt64: + case DataDisplayMode::SwappedUInt64: + ui->lineEditStepValue->setInputRange(1, UINT64_MAX - 1); + ui->lineEditStepValue->setInputMode(NumericLineEdit::UInt64Mode); + ui->lineEditLowLimit->setInputRange(0, UINT64_MAX); + ui->lineEditHighLimit->setInputRange(0, UINT64_MAX); + ui->lineEditLowLimit->setInputMode(NumericLineEdit::UInt64Mode); + ui->lineEditHighLimit->setInputMode(NumericLineEdit::UInt64Mode); + break; } updateLimits(); diff --git a/omodscan/dialogs/dialogforcemultipleregisters.cpp b/omodscan/dialogs/dialogforcemultipleregisters.cpp index d5ef0fa..03921ed 100644 --- a/omodscan/dialogs/dialogforcemultipleregisters.cpp +++ b/omodscan/dialogs/dialogforcemultipleregisters.cpp @@ -59,43 +59,43 @@ void DialogForceMultipleRegisters::accept() { case DataDisplayMode::Binary: case DataDisplayMode::Hex: - case DataDisplayMode::Decimal: - case DataDisplayMode::Integer: + case DataDisplayMode::UInt16: + case DataDisplayMode::Int16: { auto numEdit = (NumericLineEdit*)ui->tableWidget->cellWidget(i, j); _data[idx] = toByteOrderValue(numEdit->value(), _writeParams.Order); } break; - case DataDisplayMode::LongInteger: + case DataDisplayMode::Int32: if(!(idx % 2) && (idx + 1 < _data.size())) { auto numEdit = (NumericLineEdit*)ui->tableWidget->cellWidget(i, j); - breakLong(numEdit->value(), _data[idx], _data[idx + 1], _writeParams.Order); + breakInt32(numEdit->value(), _data[idx], _data[idx + 1], _writeParams.Order); } break; - case DataDisplayMode::SwappedLI: + case DataDisplayMode::SwappedInt32: if(!(idx % 2) && (idx + 1 < _data.size())) { auto numEdit = (NumericLineEdit*)ui->tableWidget->cellWidget(i, j); - breakLong(numEdit->value(), _data[idx + 1], _data[idx], _writeParams.Order); + breakInt32(numEdit->value(), _data[idx + 1], _data[idx], _writeParams.Order); } break; - case DataDisplayMode::UnsignedLongInteger: + case DataDisplayMode::UInt32: if(!(idx % 2) && (idx + 1 < _data.size())) { auto numEdit = (NumericLineEdit*)ui->tableWidget->cellWidget(i, j); - breakULong(numEdit->value(), _data[idx], _data[idx + 1], _writeParams.Order); + breakUInt32(numEdit->value(), _data[idx], _data[idx + 1], _writeParams.Order); } break; - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::SwappedUInt32: if(!(idx % 2) && (idx + 1 < _data.size())) { auto numEdit = (NumericLineEdit*)ui->tableWidget->cellWidget(i, j); - breakULong(numEdit->value(), _data[idx + 1], _data[idx], _writeParams.Order); + breakUInt32(numEdit->value(), _data[idx + 1], _data[idx], _writeParams.Order); } break; @@ -130,6 +130,38 @@ void DialogForceMultipleRegisters::accept() breakDouble(numEdit->value(), _data[idx + 3], _data[idx + 2], _data[idx + 1], _data[idx], _writeParams.Order); } break; + + case DataDisplayMode::Int64: + if(!(idx % 4) && (idx + 3 < _data.size())) + { + auto numEdit = (NumericLineEdit*)ui->tableWidget->cellWidget(i, j); + breakInt64(numEdit->value(), _data[idx], _data[idx + 1], _data[idx + 2], _data[idx + 3], _writeParams.Order); + } + break; + + case DataDisplayMode::SwappedInt64: + if(!(idx % 4) && (idx + 3 < _data.size())) + { + auto numEdit = (NumericLineEdit*)ui->tableWidget->cellWidget(i, j); + breakInt64(numEdit->value(), _data[idx + 3], _data[idx + 2], _data[idx + 1], _data[idx], _writeParams.Order); + } + break; + + case DataDisplayMode::UInt64: + if(!(idx % 4) && (idx + 3 < _data.size())) + { + auto numEdit = (NumericLineEdit*)ui->tableWidget->cellWidget(i, j); + breakUInt64(numEdit->value(), _data[idx], _data[idx + 1], _data[idx + 2], _data[idx + 3], _writeParams.Order); + } + break; + + case DataDisplayMode::SwappedUInt64: + if(!(idx % 4) && (idx + 3 < _data.size())) + { + auto numEdit = (NumericLineEdit*)ui->tableWidget->cellWidget(i, j); + breakUInt64(numEdit->value(), _data[idx + 3], _data[idx + 2], _data[idx + 1], _data[idx], _writeParams.Order); + } + break; } } } @@ -162,32 +194,32 @@ void DialogForceMultipleRegisters::on_pushButtonRandom_clicked() { case DataDisplayMode::Binary: case DataDisplayMode::Hex: - case DataDisplayMode::Decimal: + case DataDisplayMode::UInt16: _data[i] = QRandomGenerator::global()->bounded(0, USHRT_MAX); break; - case DataDisplayMode::Integer: + case DataDisplayMode::Int16: _data[i] = QRandomGenerator::global()->bounded(SHRT_MIN, SHRT_MAX); break; - case DataDisplayMode::LongInteger: + case DataDisplayMode::Int32: if(!(i % 2) && (i + 1 < _data.size())) - breakLong(QRandomGenerator::global()->bounded(INT_MIN, INT_MAX), _data[i], _data[i + 1], _writeParams.Order); + breakInt32(QRandomGenerator::global()->bounded(INT_MIN, INT_MAX), _data[i], _data[i + 1], _writeParams.Order); break; - case DataDisplayMode::SwappedLI: + case DataDisplayMode::SwappedInt32: if(!(i % 2) && (i + 1 < _data.size())) - breakLong(QRandomGenerator::global()->bounded(INT_MIN, INT_MAX), _data[i + 1], _data[i], _writeParams.Order); + breakInt32(QRandomGenerator::global()->bounded(INT_MIN, INT_MAX), _data[i + 1], _data[i], _writeParams.Order); break; - case DataDisplayMode::UnsignedLongInteger: + case DataDisplayMode::UInt32: if(!(i % 2) && (i + 1 < _data.size())) - breakULong(QRandomGenerator::global()->bounded(0U, UINT_MAX), _data[i], _data[i + 1], _writeParams.Order); + breakUInt32(QRandomGenerator::global()->bounded(0U, UINT_MAX), _data[i], _data[i + 1], _writeParams.Order); break; - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::SwappedUInt32: if(!(i % 2) && (i + 1 < _data.size())) - breakULong(QRandomGenerator::global()->bounded(0U, UINT_MAX), _data[i + 1], _data[i], _writeParams.Order); + breakUInt32(QRandomGenerator::global()->bounded(0U, UINT_MAX), _data[i + 1], _data[i], _writeParams.Order); break; case DataDisplayMode::FloatingPt: @@ -209,6 +241,26 @@ void DialogForceMultipleRegisters::on_pushButtonRandom_clicked() if(!(i % 4) && (i + 3 < _data.size())) breakDouble(QRandomGenerator::global()->bounded(100.), _data[i + 3], _data[i + 2], _data[i + 1], _data[i], _writeParams.Order); break; + + case DataDisplayMode::Int64: + if(!(i % 4) && (i + 3 < _data.size())) + breakInt64((qint64)QRandomGenerator::global()->generate64(), _data[i], _data[i + 1], _data[i + 2], _data[i + 3], _writeParams.Order); + break; + + case DataDisplayMode::SwappedInt64: + if(!(i % 4) && (i + 3 < _data.size())) + breakInt64((qint64)QRandomGenerator::global()->generate64(), _data[i + 3], _data[i + 2], _data[i + 1], _data[i], _writeParams.Order); + break; + + case DataDisplayMode::UInt64: + if(!(i % 4) && (i + 3 < _data.size())) + breakUInt64(QRandomGenerator::global()->generate64(), _data[i], _data[i + 1], _data[i + 2], _data[i + 3], _writeParams.Order); + break; + + case DataDisplayMode::SwappedUInt64: + if(!(i % 4) && (i + 3 < _data.size())) + breakUInt64(QRandomGenerator::global()->generate64(), _data[i + 3], _data[i + 2], _data[i + 1], _data[i], _writeParams.Order); + break; } } @@ -233,47 +285,47 @@ NumericLineEdit* DialogForceMultipleRegisters::createNumEdit(int idx) numEdit->setValue(toByteOrderValue(_data[idx], _writeParams.Order)); break; - case DataDisplayMode::Decimal: - numEdit = new NumericLineEdit(NumericLineEdit::DecMode, ui->tableWidget); + case DataDisplayMode::UInt16: + numEdit = new NumericLineEdit(NumericLineEdit::Int32Mode, ui->tableWidget); numEdit->setInputRange(0, USHRT_MAX); numEdit->setValue(toByteOrderValue(_data[idx], _writeParams.Order)); break; - case DataDisplayMode::Integer: - numEdit = new NumericLineEdit(NumericLineEdit::DecMode, ui->tableWidget); + case DataDisplayMode::Int16: + numEdit = new NumericLineEdit(NumericLineEdit::Int32Mode, ui->tableWidget); numEdit->setInputRange(SHRT_MIN, SHRT_MAX); numEdit->setValue((qint16)toByteOrderValue(_data[idx], _writeParams.Order)); break; - case DataDisplayMode::LongInteger: + case DataDisplayMode::Int32: if(!(idx % 2) && (idx + 1 < _data.size())) { - numEdit = new NumericLineEdit(NumericLineEdit::DecMode, ui->tableWidget); - numEdit->setValue(makeLong(_data[idx], _data[idx + 1], _writeParams.Order)); + numEdit = new NumericLineEdit(NumericLineEdit::Int32Mode, ui->tableWidget); + numEdit->setValue(makeInt32(_data[idx], _data[idx + 1], _writeParams.Order)); } break; - case DataDisplayMode::SwappedLI: + case DataDisplayMode::SwappedInt32: if(!(idx % 2) && (idx + 1 < _data.size())) { - numEdit = new NumericLineEdit(NumericLineEdit::DecMode, ui->tableWidget); - numEdit->setValue(makeLong(_data[idx + 1], _data[idx], _writeParams.Order)); + numEdit = new NumericLineEdit(NumericLineEdit::Int32Mode, ui->tableWidget); + numEdit->setValue(makeInt32(_data[idx + 1], _data[idx], _writeParams.Order)); } break; - case DataDisplayMode::UnsignedLongInteger: + case DataDisplayMode::UInt32: if(!(idx % 2) && (idx + 1 < _data.size())) { - numEdit = new NumericLineEdit(NumericLineEdit::UnsignedMode, ui->tableWidget); - numEdit->setValue(makeULong(_data[idx], _data[idx + 1], _writeParams.Order)); + numEdit = new NumericLineEdit(NumericLineEdit::UInt32Mode, ui->tableWidget); + numEdit->setValue(makeUInt32(_data[idx], _data[idx + 1], _writeParams.Order)); } break; - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::SwappedUInt32: if(!(idx % 2) && (idx + 1 < _data.size())) { - numEdit = new NumericLineEdit(NumericLineEdit::UnsignedMode, ui->tableWidget); - numEdit->setValue(makeULong(_data[idx + 1], _data[idx], _writeParams.Order)); + numEdit = new NumericLineEdit(NumericLineEdit::UInt32Mode, ui->tableWidget); + numEdit->setValue(makeUInt32(_data[idx + 1], _data[idx], _writeParams.Order)); } break; @@ -308,12 +360,44 @@ NumericLineEdit* DialogForceMultipleRegisters::createNumEdit(int idx) numEdit->setValue(makeDouble(_data[idx + 3], _data[idx + 2], _data[idx + 1], _data[idx], _writeParams.Order)); } break; + + case DataDisplayMode::Int64: + if(!(idx % 4) && (idx + 3 < _data.size())) + { + numEdit = new NumericLineEdit(NumericLineEdit::Int64Mode, ui->tableWidget); + numEdit->setValue(makeInt64(_data[idx], _data[idx + 1], _data[idx + 2], _data[idx + 3], _writeParams.Order)); + } + break; + + case DataDisplayMode::SwappedInt64: + if(!(idx % 4) && (idx + 3 < _data.size())) + { + numEdit = new NumericLineEdit(NumericLineEdit::Int64Mode, ui->tableWidget); + numEdit->setValue(makeInt64(_data[idx + 3], _data[idx + 2], _data[idx + 1], _data[idx], _writeParams.Order)); + } + break; + + case DataDisplayMode::UInt64: + if(!(idx % 4) && (idx + 3 < _data.size())) + { + numEdit = new NumericLineEdit(NumericLineEdit::UInt64Mode, ui->tableWidget); + numEdit->setValue(makeUInt64(_data[idx], _data[idx + 1], _data[idx + 2], _data[idx + 3], _writeParams.Order)); + } + break; + + case DataDisplayMode::SwappedUInt64: + if(!(idx % 4) && (idx + 3 < _data.size())) + { + numEdit = new NumericLineEdit(NumericLineEdit::UInt64Mode, ui->tableWidget); + numEdit->setValue(makeUInt64(_data[idx + 3], _data[idx + 2], _data[idx + 1], _data[idx], _writeParams.Order)); + } + break; } if(numEdit) { numEdit->setFrame(false); - numEdit->setMaximumWidth(80); + numEdit->setFixedWidth(150); numEdit->setAlignment(Qt::AlignCenter); numEdit->setToolTip(formatAddress(QModbusDataUnit::HoldingRegisters, _writeParams.Address + idx, _hexView)); } @@ -330,7 +414,7 @@ QLineEdit* DialogForceMultipleRegisters::createLineEdit() auto lineEdit = new QLineEdit(ui->tableWidget); lineEdit->setText("-"); lineEdit->setFrame(false); - lineEdit->setMaximumWidth(80); + lineEdit->setFixedWidth(150); lineEdit->setEnabled(false); lineEdit->setAlignment(Qt::AlignCenter); return lineEdit; @@ -341,7 +425,7 @@ QLineEdit* DialogForceMultipleRegisters::createLineEdit() /// void DialogForceMultipleRegisters::updateTableWidget() { - const int columns = 8; + const int columns = 5; const auto length = _data.length(); ui->tableWidget->clear(); diff --git a/omodscan/dialogs/dialogforcemultipleregisters.ui b/omodscan/dialogs/dialogforcemultipleregisters.ui index 0ce920b..a291e54 100644 --- a/omodscan/dialogs/dialogforcemultipleregisters.ui +++ b/omodscan/dialogs/dialogforcemultipleregisters.ui @@ -6,8 +6,8 @@ 0 0 - 855 - 320 + 960 + 420 diff --git a/omodscan/dialogs/dialogmodbusscanner.cpp b/omodscan/dialogs/dialogmodbusscanner.cpp index 67c86f1..dc6b7ce 100644 --- a/omodscan/dialogs/dialogmodbusscanner.cpp +++ b/omodscan/dialogs/dialogmodbusscanner.cpp @@ -306,6 +306,7 @@ void DialogModbusScanner::startScan() clearScanTime(); clearProgress(); + ui->progressBar->setValue(0); if(ui->listWidget->count() > 0) { @@ -341,7 +342,6 @@ void DialogModbusScanner::clearScanTime() /// void DialogModbusScanner::clearProgress() { - ui->progressBar->setValue(0); ui->labelSpeed->setText(QString(tr("Baud Rate:"))); ui->labelDataBits->setText(QString(tr("Data Bits:"))); ui->labelParity->setText(QString(tr("Parity:"))); @@ -598,6 +598,7 @@ const QModbusRequest DialogModbusScanner::createModbusRequest() const void DialogModbusScanner::on_scanFinished() { ui->pushButtonScan->setIcon(_iconStart); + clearProgress(); } /// diff --git a/omodscan/dialogs/dialogmsgparser.cpp b/omodscan/dialogs/dialogmsgparser.cpp index 88aede7..200bbbd 100644 --- a/omodscan/dialogs/dialogmsgparser.cpp +++ b/omodscan/dialogs/dialogmsgparser.cpp @@ -67,7 +67,7 @@ void DialogMsgParser::on_awake() void DialogMsgParser::on_hexView_toggled(bool checked) { ui->bytesData->setInputMode(checked ? ByteListTextEdit::HexMode : ByteListTextEdit::DecMode); - ui->info->setDataDisplayMode(checked ? DataDisplayMode::Hex : DataDisplayMode::Decimal); + ui->info->setDataDisplayMode(checked ? DataDisplayMode::Hex : DataDisplayMode::UInt16); } /// diff --git a/omodscan/dialogs/dialogusermsg.cpp b/omodscan/dialogs/dialogusermsg.cpp index 8a32815..e66b620 100644 --- a/omodscan/dialogs/dialogusermsg.cpp +++ b/omodscan/dialogs/dialogusermsg.cpp @@ -155,6 +155,6 @@ void DialogUserMsg::on_radioButtonDecimal_clicked(bool checked) ui->comboBoxFunction->setInputMode(FunctionCodeComboBox::DecMode); ui->sendData->setInputMode(ByteListTextEdit::DecMode); ui->responseBuffer->setInputMode(ByteListTextEdit::DecMode); - ui->responseInfo->setDataDisplayMode(DataDisplayMode::Decimal); + ui->responseInfo->setDataDisplayMode(DataDisplayMode::UInt16); } } diff --git a/omodscan/dialogs/dialogwritecoilregister.cpp b/omodscan/dialogs/dialogwritecoilregister.cpp index cc3d57a..d394119 100644 --- a/omodscan/dialogs/dialogwritecoilregister.cpp +++ b/omodscan/dialogs/dialogwritecoilregister.cpp @@ -22,6 +22,27 @@ DialogWriteCoilRegister::DialogWriteCoilRegister(ModbusWriteParams& params, Modb ui->radioButtonOn->setChecked(params.Value.toBool()); ui->radioButtonOff->setChecked(!params.Value.toBool()); ui->buttonBox->setFocus(); + + if(simParams.Mode != SimulationMode::No) + { + QLabel* iconLabel = new QLabel(ui->pushButtonSimulation); + iconLabel->setPixmap(QIcon(":/res/pointGreen.png").pixmap(4, 4)); + iconLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true); + + QLabel* textLabel = new QLabel(ui->pushButtonSimulation->text(), ui->pushButtonSimulation); + textLabel->setAlignment(Qt::AlignCenter); + textLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true); + + auto layout = new QHBoxLayout(ui->pushButtonSimulation); + layout->setContentsMargins(4,0,4,0); + layout->addWidget(iconLabel); + layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); + layout->addWidget(textLabel); + layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); + + ui->pushButtonSimulation->setText(QString()); + ui->pushButtonSimulation->setLayout(layout); + } } /// diff --git a/omodscan/dialogs/dialogwriteholdingregister.cpp b/omodscan/dialogs/dialogwriteholdingregister.cpp index 9e14c13..677f44e 100644 --- a/omodscan/dialogs/dialogwriteholdingregister.cpp +++ b/omodscan/dialogs/dialogwriteholdingregister.cpp @@ -23,17 +23,38 @@ DialogWriteHoldingRegister::DialogWriteHoldingRegister(ModbusWriteParams& params ui->lineEditNode->setValue(params.Node); ui->lineEditAddress->setValue(params.Address); + if(simParams.Mode != SimulationMode::No) + { + QLabel* iconLabel = new QLabel(ui->pushButtonSimulation); + iconLabel->setPixmap(QIcon(":/res/pointGreen.png").pixmap(4, 4)); + iconLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true); + + QLabel* textLabel = new QLabel(ui->pushButtonSimulation->text(), ui->pushButtonSimulation); + textLabel->setAlignment(Qt::AlignCenter); + textLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true); + + auto layout = new QHBoxLayout(ui->pushButtonSimulation); + layout->setContentsMargins(4,0,4,0); + layout->addWidget(iconLabel); + layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); + layout->addWidget(textLabel); + layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); + + ui->pushButtonSimulation->setText(QString()); + ui->pushButtonSimulation->setLayout(layout); + } + switch(mode) { case DataDisplayMode::Binary: break; - case DataDisplayMode::Decimal: + case DataDisplayMode::UInt16: ui->lineEditValue->setInputRange(0, USHRT_MAX); ui->lineEditValue->setValue(params.Value.toUInt()); break; - case DataDisplayMode::Integer: + case DataDisplayMode::Int16: ui->lineEditValue->setInputRange(SHRT_MIN, SHRT_MAX); ui->lineEditValue->setValue(params.Value.toInt()); break; @@ -60,18 +81,32 @@ DialogWriteHoldingRegister::DialogWriteHoldingRegister(ModbusWriteParams& params ui->lineEditValue->setValue(params.Value.toDouble()); break; - case DataDisplayMode::LongInteger: - case DataDisplayMode::SwappedLI: + case DataDisplayMode::Int32: + case DataDisplayMode::SwappedInt32: ui->lineEditValue->setInputRange(INT_MIN, INT_MAX); ui->lineEditValue->setValue(params.Value.toInt()); break; - case DataDisplayMode::UnsignedLongInteger: - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::UInt32: + case DataDisplayMode::SwappedUInt32: ui->lineEditValue->setInputRange(0U, UINT_MAX); - ui->lineEditValue->setInputMode(NumericLineEdit::UnsignedMode); + ui->lineEditValue->setInputMode(NumericLineEdit::UInt32Mode); ui->lineEditValue->setValue(params.Value.toUInt()); break; + + case DataDisplayMode::Int64: + case DataDisplayMode::SwappedInt64: + ui->lineEditValue->setInputRange(INT64_MIN, INT64_MAX); + ui->lineEditValue->setInputMode(NumericLineEdit::Int64Mode); + ui->lineEditValue->setValue(params.Value.toLongLong()); + break; + + case DataDisplayMode::UInt64: + case DataDisplayMode::SwappedUInt64: + ui->lineEditValue->setInputRange(0, UINT64_MAX); + ui->lineEditValue->setInputMode(NumericLineEdit::UInt64Mode); + ui->lineEditValue->setValue(params.Value.toULongLong()); + break; } ui->buttonBox->setFocus(); } diff --git a/omodscan/dialogs/dialogwriteholdingregister.ui b/omodscan/dialogs/dialogwriteholdingregister.ui index bfc8259..7490293 100644 --- a/omodscan/dialogs/dialogwriteholdingregister.ui +++ b/omodscan/dialogs/dialogwriteholdingregister.ui @@ -6,8 +6,8 @@ 0 0 - 203 - 192 + 241 + 205 @@ -132,12 +132,6 @@ 26 - - - 60 - 16777215 - - diff --git a/omodscan/enums.h b/omodscan/enums.h index c319c6f..378d1ad 100644 --- a/omodscan/enums.h +++ b/omodscan/enums.h @@ -44,17 +44,21 @@ inline QSettings& operator >>(QSettings& in, DisplayMode& mode) enum class DataDisplayMode { Binary = 0, - Decimal, - Integer, + UInt16, + Int16, Hex, FloatingPt, SwappedFP, DblFloat, SwappedDbl, - LongInteger, - SwappedLI, - UnsignedLongInteger, - SwappedUnsignedLI + Int32, + SwappedInt32, + UInt32, + SwappedUInt32, + Int64, + SwappedInt64, + UInt64, + SwappedUInt64 }; Q_DECLARE_METATYPE(DataDisplayMode); diff --git a/omodscan/formatutils.h b/omodscan/formatutils.h index c9d964a..f29ee8f 100644 --- a/omodscan/formatutils.h +++ b/omodscan/formatutils.h @@ -11,17 +11,17 @@ /// -/// \brief formatByteValue +/// \brief formatUInt8Value /// \param mode /// \param c /// \return /// -inline QString formatByteValue(DataDisplayMode mode, quint8 c) +inline QString formatUInt8Value(DataDisplayMode mode, quint8 c) { switch(mode) { - case DataDisplayMode::Decimal: - case DataDisplayMode::Integer: + case DataDisplayMode::UInt16: + case DataDisplayMode::Int16: return QString("%1").arg(QString::number(c), 3, '0'); default: @@ -30,19 +30,19 @@ inline QString formatByteValue(DataDisplayMode mode, quint8 c) } /// -/// \brief formatByteArray +/// \brief formatUInt8Array /// \param mode /// \param ar /// \return /// -inline QString formatByteArray(DataDisplayMode mode, const QByteArray& ar) +inline QString formatUInt8Array(DataDisplayMode mode, const QByteArray& ar) { QStringList values; for(quint8 i : ar) switch(mode) { - case DataDisplayMode::Decimal: - case DataDisplayMode::Integer: + case DataDisplayMode::UInt16: + case DataDisplayMode::Int16: values += QString("%1").arg(QString::number(i), 3, '0'); break; @@ -55,22 +55,22 @@ inline QString formatByteArray(DataDisplayMode mode, const QByteArray& ar) } /// -/// \brief formatWordArray +/// \brief formatUInt16Array /// \param mode /// \param ar /// \param order /// \return /// -inline QString formatWordArray(DataDisplayMode mode, const QByteArray& ar, ByteOrder order) +inline QString formatUInt16Array(DataDisplayMode mode, const QByteArray& ar, ByteOrder order) { QStringList values; for(int i = 0; i < ar.size(); i+=2) { - const quint16 value = makeWord(ar[i+1], ar[i], order); + const quint16 value = makeUInt16(ar[i+1], ar[i], order); switch(mode) { - case DataDisplayMode::Decimal: - case DataDisplayMode::Integer: + case DataDisplayMode::UInt16: + case DataDisplayMode::Int16: values += QString("%1").arg(QString::number(value), 5, '0'); break; @@ -84,17 +84,17 @@ inline QString formatWordArray(DataDisplayMode mode, const QByteArray& ar, ByteO } /// -/// \brief formatWordValue +/// \brief formatUInt16Value /// \param mode /// \param v /// \return /// -inline QString formatWordValue(DataDisplayMode mode, quint16 v) +inline QString formatUInt16Value(DataDisplayMode mode, quint16 v) { switch(mode) { - case DataDisplayMode::Decimal: - case DataDisplayMode::Integer: + case DataDisplayMode::UInt16: + case DataDisplayMode::Int16: return QString("%1").arg(QString::number(v), 5, '0'); default: @@ -132,13 +132,13 @@ inline QString formatBinaryValue(QModbusDataUnit::RegisterType pointType, quint1 } /// -/// \brief formatDecimalValue +/// \brief formatUInt16Value /// \param pointType /// \param value /// \param outValue /// \return /// -inline QString formatDecimalValue(QModbusDataUnit::RegisterType pointType, quint16 value, ByteOrder order, QVariant& outValue) +inline QString formatUInt16Value(QModbusDataUnit::RegisterType pointType, quint16 value, ByteOrder order, QVariant& outValue) { QString result; value = toByteOrderValue(value, order); @@ -161,13 +161,13 @@ inline QString formatDecimalValue(QModbusDataUnit::RegisterType pointType, quint } /// -/// \brief formatIntegerValue +/// \brief formatInt16Value /// \param pointType /// \param value /// \param outValue /// \return /// -inline QString formatIntegerValue(QModbusDataUnit::RegisterType pointType, qint16 value, ByteOrder order, QVariant& outValue) +inline QString formatInt16Value(QModbusDataUnit::RegisterType pointType, qint16 value, ByteOrder order, QVariant& outValue) { QString result; value = toByteOrderValue(value, order); @@ -255,7 +255,7 @@ inline QString formatFloatValue(QModbusDataUnit::RegisterType pointType, quint16 } /// -/// \brief formatLongValue +/// \brief formatInt32Value /// \param pointType /// \param value1 /// \param value2 @@ -264,7 +264,7 @@ inline QString formatFloatValue(QModbusDataUnit::RegisterType pointType, quint16 /// \param outValue /// \return /// -inline QString formatLongValue(QModbusDataUnit::RegisterType pointType, quint16 value1, quint16 value2, ByteOrder order, bool flag, QVariant& outValue) +inline QString formatInt32Value(QModbusDataUnit::RegisterType pointType, quint16 value1, quint16 value2, ByteOrder order, bool flag, QVariant& outValue) { QString result; switch(pointType) @@ -279,9 +279,9 @@ inline QString formatLongValue(QModbusDataUnit::RegisterType pointType, quint16 { if(flag) break; - const qint32 value = makeLong(value1, value2, order); + const qint32 value = makeInt32(value1, value2, order); outValue = value; - result = result = QString("<%1>").arg(value, 10, 10, QLatin1Char(' ')); + result = QString("<%1>").arg(value, 10, 10, QLatin1Char(' ')); } break; default: @@ -291,7 +291,7 @@ inline QString formatLongValue(QModbusDataUnit::RegisterType pointType, quint16 } /// -/// \brief formatUnsignedLongValue +/// \brief formatUInt32Value /// \param pointType /// \param value1 /// \param value2 @@ -300,7 +300,7 @@ inline QString formatLongValue(QModbusDataUnit::RegisterType pointType, quint16 /// \param outValue /// \return /// -inline QString formatUnsignedLongValue(QModbusDataUnit::RegisterType pointType, quint16 value1, quint16 value2, ByteOrder order, bool flag, QVariant& outValue) +inline QString formatUInt32Value(QModbusDataUnit::RegisterType pointType, quint16 value1, quint16 value2, ByteOrder order, bool flag, QVariant& outValue) { QString result; switch(pointType) @@ -315,9 +315,9 @@ inline QString formatUnsignedLongValue(QModbusDataUnit::RegisterType pointType, { if(flag) break; - const quint32 value = makeULong(value1, value2, order); + const quint32 value = makeUInt32(value1, value2, order); outValue = value; - result = result = QString("<%1>").arg(value, 10, 10, QLatin1Char('0')); + result = QString("<%1>").arg(value, 10, 10, QLatin1Char('0')); } break; default: @@ -364,6 +364,82 @@ inline QString formatDoubleValue(QModbusDataUnit::RegisterType pointType, quint1 return result; } +/// +/// \brief formatInt64Value +/// \param pointType +/// \param value1 +/// \param value2 +/// \param value3 +/// \param value4 +/// \param order +/// \param flag +/// \param outValue +/// \return +/// +inline QString formatInt64Value(QModbusDataUnit::RegisterType pointType, quint16 value1, quint16 value2, quint16 value3, quint16 value4, ByteOrder order, bool flag, QVariant& outValue) +{ + QString result; + switch(pointType) + { + case QModbusDataUnit::Coils: + case QModbusDataUnit::DiscreteInputs: + outValue = value1; + result = QString("<%1>").arg(value1); + break; + case QModbusDataUnit::HoldingRegisters: + case QModbusDataUnit::InputRegisters: + { + if(flag) break; + + const qint64 value = makeInt64(value1, value2, value3, value4, order); + outValue = value; + result = QString("<%1>").arg(value, 20, 10, QLatin1Char(' ')); + } + break; + default: + break; + } + return result; +} + +/// +/// \brief formatUInt64Value +/// \param pointType +/// \param value1 +/// \param value2 +/// \param value3 +/// \param value4 +/// \param order +/// \param flag +/// \param outValue +/// \return +/// +inline QString formatUInt64Value(QModbusDataUnit::RegisterType pointType, quint16 value1, quint16 value2, quint16 value3, quint16 value4, ByteOrder order, bool flag, QVariant& outValue) +{ + QString result; + switch(pointType) + { + case QModbusDataUnit::Coils: + case QModbusDataUnit::DiscreteInputs: + outValue = value1; + result = QString("<%1>").arg(value1); + break; + case QModbusDataUnit::HoldingRegisters: + case QModbusDataUnit::InputRegisters: + { + if(flag) break; + + const quint64 value = makeUInt64(value1, value2, value3, value4, order); + outValue = value; + result = QString("<%1>").arg(value, 20, 10, QLatin1Char('0')); + } + break; + default: + break; + } + return result; +} + /// /// \brief formatAddress /// \param pointType diff --git a/omodscan/formmodsca.cpp b/omodscan/formmodsca.cpp index 2a40d4d..747595e 100644 --- a/omodscan/formmodsca.cpp +++ b/omodscan/formmodsca.cpp @@ -662,7 +662,7 @@ void FormModSca::on_modbusReply(QModbusReply* reply) else if (reply->error() == QModbusDevice::ProtocolError) { const auto ex = ModbusException(response.exceptionCode()); - const auto errorString = QString("%1 (%2)").arg(ex, formatByteValue(DataDisplayMode::Hex, ex)); + const auto errorString = QString("%1 (%2)").arg(ex, formatUInt8Value(DataDisplayMode::Hex, ex)); ui->outputWidget->setStatus(errorString); } else diff --git a/omodscan/mainwindow.cpp b/omodscan/mainwindow.cpp index 49097c4..f3ab7ac 100644 --- a/omodscan/mainwindow.cpp +++ b/omodscan/mainwindow.cpp @@ -181,8 +181,8 @@ void MainWindow::on_awake() ui->actionShowData->setEnabled(frm != nullptr); ui->actionShowTraffic->setEnabled(frm != nullptr); ui->actionBinary->setEnabled(frm != nullptr); - ui->actionUnsignedDecimal->setEnabled(frm != nullptr); - ui->actionInteger->setEnabled(frm != nullptr); + ui->actionUInt16->setEnabled(frm != nullptr); + ui->actionInt16->setEnabled(frm != nullptr); ui->actionHex->setEnabled(frm != nullptr); ui->actionFloatingPt->setEnabled(frm != nullptr); ui->actionSwappedFP->setEnabled(frm != nullptr); @@ -209,12 +209,16 @@ void MainWindow::on_awake() { const auto ddm = frm->dataDisplayMode(); ui->actionBinary->setChecked(ddm == DataDisplayMode::Binary); - ui->actionUnsignedDecimal->setChecked(ddm == DataDisplayMode::Decimal); - ui->actionInteger->setChecked(ddm == DataDisplayMode::Integer); - ui->actionLongInteger->setChecked(ddm == DataDisplayMode::LongInteger); - ui->actionSwappedLI->setChecked(ddm == DataDisplayMode::SwappedLI); - ui->actionUnsignedLongInteger->setChecked(ddm == DataDisplayMode::UnsignedLongInteger); - ui->actionSwappedUnsignedLI->setChecked(ddm == DataDisplayMode::SwappedUnsignedLI); + ui->actionUInt16->setChecked(ddm == DataDisplayMode::UInt16); + ui->actionInt16->setChecked(ddm == DataDisplayMode::Int16); + ui->actionInt32->setChecked(ddm == DataDisplayMode::Int32); + ui->actionSwappedInt32->setChecked(ddm == DataDisplayMode::SwappedInt32); + ui->actionUInt32->setChecked(ddm == DataDisplayMode::UInt32); + ui->actionSwappedUInt32->setChecked(ddm == DataDisplayMode::SwappedUInt32); + ui->actionInt64->setChecked(ddm == DataDisplayMode::Int64); + ui->actionSwappedInt64->setChecked(ddm == DataDisplayMode::SwappedInt64); + ui->actionUInt64->setChecked(ddm == DataDisplayMode::UInt64); + ui->actionSwappedUInt64->setChecked(ddm == DataDisplayMode::SwappedUInt64); ui->actionHex->setChecked(ddm == DataDisplayMode::Hex); ui->actionFloatingPt->setChecked(ddm == DataDisplayMode::FloatingPt); ui->actionSwappedFP->setChecked(ddm == DataDisplayMode::SwappedFP); @@ -510,48 +514,83 @@ void MainWindow::on_actionBinary_triggered() } /// -/// \brief MainWindow::on_actionUnsignedDecimal_triggered +/// \brief MainWindow::on_actionUInt16_triggered /// -void MainWindow::on_actionUnsignedDecimal_triggered() +void MainWindow::on_actionUInt16_triggered() { - updateDataDisplayMode(DataDisplayMode::Decimal); + updateDataDisplayMode(DataDisplayMode::UInt16); } /// -/// \brief MainWindow::on_actionInteger_triggered +/// \brief MainWindow::on_actionInt16_triggered /// -void MainWindow::on_actionInteger_triggered() +void MainWindow::on_actionInt16_triggered() { - updateDataDisplayMode(DataDisplayMode::Integer); + updateDataDisplayMode(DataDisplayMode::Int16); } /// -/// \brief MainWindow::on_actionLongInteger_triggered +/// \brief MainWindow::on_actionInt32_triggered /// -void MainWindow::on_actionLongInteger_triggered() +void MainWindow::on_actionInt32_triggered() { - updateDataDisplayMode(DataDisplayMode::LongInteger); + updateDataDisplayMode(DataDisplayMode::Int32); } /// -/// \brief MainWindow::on_actionSwappedLI_triggered +/// \brief MainWindow::on_actionSwappedInt32_triggered /// -void MainWindow::on_actionSwappedLI_triggered() +void MainWindow::on_actionSwappedInt32_triggered() { - updateDataDisplayMode(DataDisplayMode::SwappedLI); + updateDataDisplayMode(DataDisplayMode::SwappedInt32); } /// -/// \brief MainWindow::on_actionUnsignedLongInteger_triggered +/// \brief MainWindow::on_actionUInt32_triggered /// -void MainWindow::on_actionUnsignedLongInteger_triggered() +void MainWindow::on_actionUInt32_triggered() { - updateDataDisplayMode(DataDisplayMode::UnsignedLongInteger); + updateDataDisplayMode(DataDisplayMode::UInt32); } -void MainWindow::on_actionSwappedUnsignedLI_triggered() +/// +/// \brief MainWindow::on_actionSwappedUInt32_triggered +/// +void MainWindow::on_actionSwappedUInt32_triggered() +{ + updateDataDisplayMode(DataDisplayMode::SwappedUInt32); +} + +/// +/// \brief MainWindow::on_actionInt64_triggered +/// +void MainWindow::on_actionInt64_triggered() +{ + updateDataDisplayMode(DataDisplayMode::Int64); +} + +/// +/// \brief MainWindow::on_actionSwappedInt64_triggered +/// +void MainWindow::on_actionSwappedInt64_triggered() +{ + updateDataDisplayMode(DataDisplayMode::SwappedInt64); +} + +/// +/// \brief MainWindow::on_actionUInt64_triggered +/// +void MainWindow::on_actionUInt64_triggered() +{ + updateDataDisplayMode(DataDisplayMode::UInt64); +} + +/// +/// \brief MainWindow::on_actionSwappedUInt64_triggered +/// +void MainWindow::on_actionSwappedUInt64_triggered() { - updateDataDisplayMode(DataDisplayMode::SwappedUnsignedLI); + updateDataDisplayMode(DataDisplayMode::SwappedUInt64); } /// @@ -769,7 +808,7 @@ void MainWindow::on_actionAddressScan_triggered() { auto frm = currentMdiChild(); const auto dd = frm ? frm->displayDefinition() : DisplayDefinition(); - const auto mode = frm ? frm->dataDisplayMode() : DataDisplayMode::Decimal; + const auto mode = frm ? frm->dataDisplayMode() : DataDisplayMode::UInt16; const auto order = frm ? frm->byteOrder() : ByteOrder::LittleEndian; auto dlg = new DialogAddressScan(dd, mode, order, _modbusClient, this); diff --git a/omodscan/mainwindow.h b/omodscan/mainwindow.h index 06347d4..825a4ee 100644 --- a/omodscan/mainwindow.h +++ b/omodscan/mainwindow.h @@ -58,12 +58,16 @@ private slots: void on_actionShowData_triggered(); void on_actionShowTraffic_triggered(); void on_actionBinary_triggered(); - void on_actionUnsignedDecimal_triggered(); - void on_actionInteger_triggered(); - void on_actionLongInteger_triggered(); - void on_actionSwappedLI_triggered(); - void on_actionUnsignedLongInteger_triggered(); - void on_actionSwappedUnsignedLI_triggered(); + void on_actionUInt16_triggered(); + void on_actionInt16_triggered(); + void on_actionInt32_triggered(); + void on_actionSwappedInt32_triggered(); + void on_actionUInt32_triggered(); + void on_actionSwappedUInt32_triggered(); + void on_actionInt64_triggered(); + void on_actionSwappedInt64_triggered(); + void on_actionUInt64_triggered(); + void on_actionSwappedUInt64_triggered(); void on_actionHex_triggered(); void on_actionFloatingPt_triggered(); void on_actionSwappedFP_triggered(); diff --git a/omodscan/mainwindow.ui b/omodscan/mainwindow.ui index 27c73e1..a014fc3 100644 --- a/omodscan/mainwindow.ui +++ b/omodscan/mainwindow.ui @@ -103,13 +103,17 @@ - - - - - - + + + + + + + + + + @@ -223,6 +227,12 @@ Display Bar + + + 24 + 24 + + TopToolBarArea @@ -230,15 +240,22 @@ true - - - - + + + + + + + + - - + + + + + @@ -430,34 +447,34 @@ Hex - Ctrl+6 + Ctrl+2 - + true - :/res/actionUnsignedDecimal.png:/res/actionUnsignedDecimal.png + :/res/actionUInt16.png:/res/actionUInt16.png - Unsigned Decimal + Unsigned 16-bit Intger - Ctrl+2 + Ctrl+4 - + true - :/res/actionInteger.png:/res/actionInteger.png + :/res/actionInt16.png:/res/actionInt16.png - Integer + 16-bit Integer Ctrl+3 @@ -472,10 +489,13 @@ :/res/actionFloatingPt.png:/res/actionFloatingPt.png - Floating Pt + Float + + + Float - Ctrl+7 + Ctrl+9 @@ -487,10 +507,13 @@ :/res/actionSwappedFP.png:/res/actionSwappedFP.png - Swapped FP + Swapped Float + + + Swapped Float - Ctrl+Shift+7 + Ctrl+Alt+9 @@ -502,10 +525,13 @@ :/res/actionDblFloat.png:/res/actionDblFloat.png - Dbl Float + Double + + + Double - Ctrl+8 + Ctrl+0 @@ -517,10 +543,13 @@ :/res/actionSwappedDbl.png:/res/actionSwappedDbl.png - Swapped Dbl + Swapped Double + + + Swapped Double - Ctrl+Shift+8 + Ctrl+Alt+0 @@ -690,70 +719,70 @@ F3 - + true - :/res/actionLongInteger.png:/res/actionLongInteger.png + :/res/actionInt32.png:/res/actionInt32.png - Long Integer + 32-bit Integer - Ctrl+4 + Ctrl+5 - + true - :/res/actionSwappedLI.png:/res/actionSwappedLI.png + :/res/actionSwappedInt32.png:/res/actionSwappedInt32.png - Swapped LI + Swapped 32-bit Integer - Swapped Long Integer + Swapped 32-bit Integer - Ctrl+Shift+4 + Ctrl+Alt+5 - + true - :/res/actionUnsignedLI.png:/res/actionUnsignedLI.png + :/res/actionUInt32.png:/res/actionUInt32.png - Unsigned Long Integer + Unsigned 32-bit Integer - Ctrl+5 + Ctrl+6 - + true - :/res/actionSwappedUnsignedLI.png:/res/actionSwappedUnsignedLI.png + :/res/actionSwappedUInt32.png:/res/actionSwappedUInt32.png - Swapped Unsigned LI + Swapped Unsigned 32-bit Integer - Swapped Unsigned Long Integer + Swapped Unsigned 32-bit Integer - Ctrl+Shift+5 + Ctrl+Alt+6 @@ -767,6 +796,66 @@ F9 + + + true + + + + :/res/actionInt64.png:/res/actionInt64.png + + + 64-bit Integer + + + Ctrl+7 + + + + + true + + + + :/res/actionSwappedInt64.png:/res/actionSwappedInt64.png + + + Swapped 64-bit Integer + + + Ctrl+Alt+7 + + + + + true + + + + :/res/actionUInt64.png:/res/actionUInt64.png + + + Unsigned 64-bit Integer + + + Ctrl+8 + + + + + true + + + + :/res/actionSwappedUInt64.png:/res/actionSwappedUInt64.png + + + Swapped Unsigned 64-bit Integer + + + Ctrl+Alt+8 + + diff --git a/omodscan/modbusclient.cpp b/omodscan/modbusclient.cpp index 26dda82..3564d19 100644 --- a/omodscan/modbusclient.cpp +++ b/omodscan/modbusclient.cpp @@ -322,9 +322,31 @@ QModbusDataUnit createHoldingRegistersDataUnit(int newStartAddress, qint32 value auto data = QModbusDataUnit(QModbusDataUnit::HoldingRegisters, newStartAddress, 2); if(swapped) - breakLong(value, values[1], values[0], order); + breakInt32(value, values[1], values[0], order); else - breakLong(value, values[0], values[1], order); + breakInt32(value, values[0], values[1], order); + + data.setValues(values); + return data; +} + +/// +/// \brief createHoldingRegistersDataUnit +/// \param newStartAddress +/// \param value +/// \param order +/// \param swapped +/// \return +/// +QModbusDataUnit createHoldingRegistersDataUnit(int newStartAddress, qint64 value, ByteOrder order, bool swapped) +{ + QVector values(4); + auto data = QModbusDataUnit(QModbusDataUnit::HoldingRegisters, newStartAddress, 4); + + if(swapped) + breakInt64(value, values[3], values[2], values[1], values[0], order); + else + breakInt64(value, values[0], values[1], values[2], values[3], order); data.setValues(values); return data; @@ -412,8 +434,8 @@ void ModbusClient::writeRegister(QModbusDataUnit::RegisterType pointType, const switch(params.DisplayMode) { case DataDisplayMode::Binary: - case DataDisplayMode::Decimal: - case DataDisplayMode::Integer: + case DataDisplayMode::UInt16: + case DataDisplayMode::Int16: case DataDisplayMode::Hex: data = createHoldingRegistersDataUnit(params.Address - 1, params.Value.toUInt(), params.Order); break; @@ -430,15 +452,25 @@ void ModbusClient::writeRegister(QModbusDataUnit::RegisterType pointType, const data = createHoldingRegistersDataUnit(params.Address - 1, params.Value.toDouble(), params.Order, true); break; - case DataDisplayMode::LongInteger: - case DataDisplayMode::UnsignedLongInteger: + case DataDisplayMode::Int32: + case DataDisplayMode::UInt32: data = createHoldingRegistersDataUnit(params.Address - 1, params.Value.toInt(), params.Order, false); break; - case DataDisplayMode::SwappedLI: - case DataDisplayMode::SwappedUnsignedLI: + case DataDisplayMode::SwappedInt32: + case DataDisplayMode::SwappedUInt32: data = createHoldingRegistersDataUnit(params.Address - 1, params.Value.toInt(), params.Order, true); break; + + case DataDisplayMode::Int64: + case DataDisplayMode::UInt64: + data = createHoldingRegistersDataUnit(params.Address - 1, params.Value.toLongLong(), params.Order, false); + break; + + case DataDisplayMode::SwappedInt64: + case DataDisplayMode::SwappedUInt64: + data = createHoldingRegistersDataUnit(params.Address - 1, params.Value.toLongLong(), params.Order, true); + break; } break; @@ -627,7 +659,7 @@ void ModbusClient::on_writeReply() if (reply->error() == QModbusDevice::ProtocolError) { ModbusException ex(raw.exceptionCode()); - emit modbusError(QString("%1. %2 (%3)").arg(errorDesc, ex, formatByteValue(DataDisplayMode::Hex, ex)), requestId); + emit modbusError(QString("%1. %2 (%3)").arg(errorDesc, ex, formatUInt8Value(DataDisplayMode::Hex, ex)), requestId); } else if(reply->error() != QModbusDevice::NoError) emit modbusError(QString("%1. %2").arg(errorDesc, reply->errorString()), requestId); diff --git a/omodscan/modbusmessages/diagnostics.h b/omodscan/modbusmessages/diagnostics.h index 2030b7d..2a8349c 100644 --- a/omodscan/modbusmessages/diagnostics.h +++ b/omodscan/modbusmessages/diagnostics.h @@ -48,7 +48,7 @@ class DiagnosticsRequest : public ModbusMessage /// \return /// quint16 subfunc() const { - return makeWord(ModbusMessage::at(1), ModbusMessage::at(0), ByteOrder::LittleEndian); + return makeUInt16(ModbusMessage::at(1), ModbusMessage::at(0), ByteOrder::LittleEndian); } /// @@ -104,7 +104,7 @@ class DiagnosticsResponse : public ModbusMessage /// \return /// quint16 subfunc() const { - return makeWord(ModbusMessage::at(1), ModbusMessage::at(0), ByteOrder::LittleEndian); + return makeUInt16(ModbusMessage::at(1), ModbusMessage::at(0), ByteOrder::LittleEndian); } /// diff --git a/omodscan/modbusmessages/getcommeventcounter.h b/omodscan/modbusmessages/getcommeventcounter.h index 8e08fac..0344708 100644 --- a/omodscan/modbusmessages/getcommeventcounter.h +++ b/omodscan/modbusmessages/getcommeventcounter.h @@ -79,7 +79,7 @@ class GetCommEventCounterResponse : public ModbusMessage /// \return /// quint16 status() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -87,7 +87,7 @@ class GetCommEventCounterResponse : public ModbusMessage /// \return /// quint16 eventCount() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; diff --git a/omodscan/modbusmessages/getcommeventlog.h b/omodscan/modbusmessages/getcommeventlog.h index f959d04..2cd1ca7 100644 --- a/omodscan/modbusmessages/getcommeventlog.h +++ b/omodscan/modbusmessages/getcommeventlog.h @@ -89,7 +89,7 @@ class GetCommEventLogResponse : public ModbusMessage /// \return /// quint16 status() const { - return makeWord(at(2), at(1), ByteOrder::LittleEndian); + return makeUInt16(at(2), at(1), ByteOrder::LittleEndian); } /// @@ -97,7 +97,7 @@ class GetCommEventLogResponse : public ModbusMessage /// \return /// quint16 eventCount() const { - return makeWord(at(4), at(3), ByteOrder::LittleEndian); + return makeUInt16(at(4), at(3), ByteOrder::LittleEndian); } /// @@ -105,7 +105,7 @@ class GetCommEventLogResponse : public ModbusMessage /// \return /// quint16 messageCount() const { - return makeWord(at(6), at(5), ByteOrder::LittleEndian); + return makeUInt16(at(6), at(5), ByteOrder::LittleEndian); } /// diff --git a/omodscan/modbusmessages/maskwriteregister.h b/omodscan/modbusmessages/maskwriteregister.h index eefc18f..a4957ea 100644 --- a/omodscan/modbusmessages/maskwriteregister.h +++ b/omodscan/modbusmessages/maskwriteregister.h @@ -47,7 +47,7 @@ class MaskWriteRegisterRequest : public ModbusMessage /// \return /// quint16 address() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -55,7 +55,7 @@ class MaskWriteRegisterRequest : public ModbusMessage /// \return /// quint16 andMask() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } /// @@ -63,7 +63,7 @@ class MaskWriteRegisterRequest : public ModbusMessage /// \return /// quint16 orMask() const { - return makeWord(at(5), at(4), ByteOrder::LittleEndian); + return makeUInt16(at(5), at(4), ByteOrder::LittleEndian); } }; @@ -111,7 +111,7 @@ class MaskWriteRegisterResponse : public ModbusMessage /// \return /// quint16 address() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -119,7 +119,7 @@ class MaskWriteRegisterResponse : public ModbusMessage /// \return /// quint16 andMask() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } /// @@ -127,7 +127,7 @@ class MaskWriteRegisterResponse : public ModbusMessage /// \return /// quint16 orMask() const { - return makeWord(at(5), at(4), ByteOrder::LittleEndian); + return makeUInt16(at(5), at(4), ByteOrder::LittleEndian); } }; diff --git a/omodscan/modbusmessages/modbusmessage.h b/omodscan/modbusmessages/modbusmessage.h index 682a149..e760169 100644 --- a/omodscan/modbusmessages/modbusmessage.h +++ b/omodscan/modbusmessages/modbusmessage.h @@ -205,7 +205,7 @@ class ModbusMessage /// \return /// QString toString(DataDisplayMode mode) const { - return formatByteArray(mode, *this); + return formatUInt8Array(mode, *this); } /// diff --git a/omodscan/modbusmessages/readcoils.h b/omodscan/modbusmessages/readcoils.h index 1ecb98a..d59bbc4 100644 --- a/omodscan/modbusmessages/readcoils.h +++ b/omodscan/modbusmessages/readcoils.h @@ -49,7 +49,7 @@ class ReadCoilsRequest : public ModbusMessage /// \return /// quint16 startAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -57,7 +57,7 @@ class ReadCoilsRequest : public ModbusMessage /// \return /// quint16 length() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; diff --git a/omodscan/modbusmessages/readdiscreteinputs.h b/omodscan/modbusmessages/readdiscreteinputs.h index 0e0bceb..e6fa9e5 100644 --- a/omodscan/modbusmessages/readdiscreteinputs.h +++ b/omodscan/modbusmessages/readdiscreteinputs.h @@ -48,7 +48,7 @@ class ReadDiscreteInputsRequest : public ModbusMessage /// \return /// quint16 startAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -56,7 +56,7 @@ class ReadDiscreteInputsRequest : public ModbusMessage /// \return /// quint16 length() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; diff --git a/omodscan/modbusmessages/readfifoqueue.h b/omodscan/modbusmessages/readfifoqueue.h index d124c77..fed434a 100644 --- a/omodscan/modbusmessages/readfifoqueue.h +++ b/omodscan/modbusmessages/readfifoqueue.h @@ -47,7 +47,7 @@ class ReadFifoQueueRequest : public ModbusMessage /// \return /// quint16 fifoAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } }; @@ -97,7 +97,7 @@ class ReadFifoQueueResponse : public ModbusMessage /// \return /// quint16 byteCount() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -105,7 +105,7 @@ class ReadFifoQueueResponse : public ModbusMessage /// \return /// quint16 fifoCount() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } /// diff --git a/omodscan/modbusmessages/readholdingregisters.h b/omodscan/modbusmessages/readholdingregisters.h index b31414a..66fe8cd 100644 --- a/omodscan/modbusmessages/readholdingregisters.h +++ b/omodscan/modbusmessages/readholdingregisters.h @@ -48,7 +48,7 @@ class ReadHoldingRegistersRequest : public ModbusMessage /// \return /// quint16 startAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -56,7 +56,7 @@ class ReadHoldingRegistersRequest : public ModbusMessage /// \return /// quint16 length() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; diff --git a/omodscan/modbusmessages/readinputregisters.h b/omodscan/modbusmessages/readinputregisters.h index 1ee98cc..a4b9d70 100644 --- a/omodscan/modbusmessages/readinputregisters.h +++ b/omodscan/modbusmessages/readinputregisters.h @@ -48,7 +48,7 @@ class ReadInputRegistersRequest : public ModbusMessage /// \return /// quint16 startAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -56,7 +56,7 @@ class ReadInputRegistersRequest : public ModbusMessage /// \return /// quint16 length() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; diff --git a/omodscan/modbusmessages/readwritemultipleregisters.h b/omodscan/modbusmessages/readwritemultipleregisters.h index ef7f9c5..3f2d3f1 100644 --- a/omodscan/modbusmessages/readwritemultipleregisters.h +++ b/omodscan/modbusmessages/readwritemultipleregisters.h @@ -51,7 +51,7 @@ class ReadWriteMultipleRegistersRequest : public ModbusMessage /// \return /// quint16 readStartAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -59,7 +59,7 @@ class ReadWriteMultipleRegistersRequest : public ModbusMessage /// \return /// quint16 readLength() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } /// @@ -67,7 +67,7 @@ class ReadWriteMultipleRegistersRequest : public ModbusMessage /// \return /// quint16 writeStartAddress() const { - return makeWord(at(5), at(4), ByteOrder::LittleEndian); + return makeUInt16(at(5), at(4), ByteOrder::LittleEndian); } /// @@ -75,7 +75,7 @@ class ReadWriteMultipleRegistersRequest : public ModbusMessage /// \return /// quint16 writeLength() const { - return makeWord(at(7), at(6), ByteOrder::LittleEndian); + return makeUInt16(at(7), at(6), ByteOrder::LittleEndian); } /// diff --git a/omodscan/modbusmessages/writemultiplecoils.h b/omodscan/modbusmessages/writemultiplecoils.h index 5d4d81f..b7a2595 100644 --- a/omodscan/modbusmessages/writemultiplecoils.h +++ b/omodscan/modbusmessages/writemultiplecoils.h @@ -49,7 +49,7 @@ class WriteMultipleCoilsRequest : public ModbusMessage /// \return /// quint16 startAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -57,7 +57,7 @@ class WriteMultipleCoilsRequest : public ModbusMessage /// \return /// quint16 quantity() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } /// @@ -121,7 +121,7 @@ class WriteMultipleCoilsResponse : public ModbusMessage /// \return /// quint16 startAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -129,7 +129,7 @@ class WriteMultipleCoilsResponse : public ModbusMessage /// \return /// quint16 quantity() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; diff --git a/omodscan/modbusmessages/writemultipleregisters.h b/omodscan/modbusmessages/writemultipleregisters.h index cb1b09e..3968983 100644 --- a/omodscan/modbusmessages/writemultipleregisters.h +++ b/omodscan/modbusmessages/writemultipleregisters.h @@ -49,7 +49,7 @@ class WriteMultipleRegistersRequest : public ModbusMessage /// \return /// quint16 startAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -57,7 +57,7 @@ class WriteMultipleRegistersRequest : public ModbusMessage /// \return /// quint16 quantity() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } /// @@ -121,7 +121,7 @@ class WriteMultipleRegistersResponse : public ModbusMessage /// \return /// quint16 startAddress() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -129,7 +129,7 @@ class WriteMultipleRegistersResponse : public ModbusMessage /// \return /// quint16 quantity() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; diff --git a/omodscan/modbusmessages/writesinglecoil.h b/omodscan/modbusmessages/writesinglecoil.h index dfeaee0..486caa1 100644 --- a/omodscan/modbusmessages/writesinglecoil.h +++ b/omodscan/modbusmessages/writesinglecoil.h @@ -48,7 +48,7 @@ class WriteSingleCoilRequest : public ModbusMessage /// \return /// quint16 address() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -56,7 +56,7 @@ class WriteSingleCoilRequest : public ModbusMessage /// \return /// quint16 value() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; @@ -105,7 +105,7 @@ class WriteSingleCoilResponse : public ModbusMessage /// \return /// quint16 address() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -113,7 +113,7 @@ class WriteSingleCoilResponse : public ModbusMessage /// \return /// quint16 value() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; diff --git a/omodscan/modbusmessages/writesingleregister.h b/omodscan/modbusmessages/writesingleregister.h index f637261..04423b0 100644 --- a/omodscan/modbusmessages/writesingleregister.h +++ b/omodscan/modbusmessages/writesingleregister.h @@ -47,7 +47,7 @@ class WriteSingleRegisterRequest : public ModbusMessage /// \return /// quint16 address() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -55,7 +55,7 @@ class WriteSingleRegisterRequest : public ModbusMessage /// \return /// quint16 value() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; @@ -103,7 +103,7 @@ class WriteSingleRegisterResponse : public ModbusMessage /// \return /// quint16 address() const { - return makeWord(at(1), at(0), ByteOrder::LittleEndian); + return makeUInt16(at(1), at(0), ByteOrder::LittleEndian); } /// @@ -111,7 +111,7 @@ class WriteSingleRegisterResponse : public ModbusMessage /// \return /// quint16 value() const { - return makeWord(at(3), at(2), ByteOrder::LittleEndian); + return makeUInt16(at(3), at(2), ByteOrder::LittleEndian); } }; diff --git a/omodscan/numericutils.h b/omodscan/numericutils.h index 5a3727e..ca01b92 100644 --- a/omodscan/numericutils.h +++ b/omodscan/numericutils.h @@ -6,12 +6,12 @@ #include "byteorderutils.h" /// -/// \brief makeWord +/// \brief makeUInt16 /// \param lo /// \param hi /// \return /// -inline quint16 makeWord(quint8 lo, quint8 hi, ByteOrder order) +inline quint16 makeUInt16(quint8 lo, quint8 hi, ByteOrder order) { union { quint8 asUint8[2]; @@ -25,13 +25,13 @@ inline quint16 makeWord(quint8 lo, quint8 hi, ByteOrder order) } /// -/// \brief breakWord +/// \brief breakUInt16 /// \param value /// \param lo /// \param hi /// \param order /// -inline void breakWord(quint16 value, quint8& lo, quint8& hi, ByteOrder order) +inline void breakUInt16(quint16 value, quint8& lo, quint8& hi, ByteOrder order) { union { quint8 asUint8[2]; @@ -63,13 +63,13 @@ inline void breakFloat(float value, quint16& lo, quint16& hi, ByteOrder order) } /// -/// \brief breakLong +/// \brief breakInt32 /// \param value /// \param lo /// \param hi /// \param order /// -inline void breakLong(qint32 value, quint16& lo, quint16& hi, ByteOrder order) +inline void breakInt32(qint32 value, quint16& lo, quint16& hi, ByteOrder order) { union { quint16 asUint16[2]; @@ -82,15 +82,52 @@ inline void breakLong(qint32 value, quint16& lo, quint16& hi, ByteOrder order) } /// -/// \brief breakULong +/// \brief breakUInt32 /// \param value /// \param lo /// \param hi /// \param order /// -inline void breakULong(quint32 value, quint16& lo, quint16& hi, ByteOrder order) +inline void breakUInt32(quint32 value, quint16& lo, quint16& hi, ByteOrder order) { - breakLong((qint32)value, lo, hi, order); + breakInt32((qint32)value, lo, hi, order); +} + +/// +/// \brief breakInt64 +/// \param value +/// \param lolo +/// \param lohi +/// \param hilo +/// \param hihi +/// \param order +/// +inline void breakInt64(qint64 value, quint16& lolo, quint16& lohi, quint16& hilo, quint16& hihi, ByteOrder order) +{ + union { + quint16 asUint16[4]; + qint64 asInt64; + } v; + v.asInt64 = value; + + lolo = toByteOrderValue(v.asUint16[0], order); + lohi = toByteOrderValue(v.asUint16[1], order); + hilo = toByteOrderValue(v.asUint16[2], order); + hihi = toByteOrderValue(v.asUint16[3], order); +} + +/// +/// \brief breakUInt64 +/// \param value +/// \param lolo +/// \param lohi +/// \param hilo +/// \param hihi +/// \param order +/// +inline void breakUInt64(quint64 value, quint16& lolo, quint16& lohi, quint16& hilo, quint16& hihi, ByteOrder order) +{ + breakInt64((qint64)value, lolo, lohi, hilo, hihi, order); } /// @@ -137,13 +174,13 @@ inline float makeFloat(quint16 lo, quint16 hi, ByteOrder order) } /// -/// \brief makeLong +/// \brief makeInt32 /// \param lo /// \param hi /// \param order /// \return /// -inline qint32 makeLong(quint16 lo, quint16 hi, ByteOrder order) +inline qint32 makeInt32(quint16 lo, quint16 hi, ByteOrder order) { union { quint16 asUint16[2]; @@ -157,15 +194,53 @@ inline qint32 makeLong(quint16 lo, quint16 hi, ByteOrder order) } /// -/// \brief makeULong +/// \brief makeUInt32 /// \param lo /// \param hi /// \param order /// \return /// -inline quint32 makeULong(quint16 lo, quint16 hi, ByteOrder order) +inline quint32 makeUInt32(quint16 lo, quint16 hi, ByteOrder order) +{ + return (quint32)makeInt32(lo, hi, order); +} + +/// +/// \brief makeInt64 +/// \param lolo +/// \param lohi +/// \param hilo +/// \param hihi +/// \param order +/// \return +/// +inline qint64 makeInt64(quint16 lolo, quint16 lohi, quint16 hilo, quint16 hihi, ByteOrder order) +{ + union { + quint16 asUint16[4]; + qint64 asInt64; + } v; + + v.asUint16[0] = toByteOrderValue(lolo, order); + v.asUint16[1] = toByteOrderValue(lohi, order); + v.asUint16[2] = toByteOrderValue(hilo, order); + v.asUint16[3] = toByteOrderValue(hihi, order); + + return v.asInt64; +} + +/// +/// \brief makeUInt64 +/// \param lolo +/// \param lohi +/// \param hilo +/// \param hihi +/// \param order +/// \return +/// +inline qint64 makeUInt64(quint16 lolo, quint16 lohi, quint16 hilo, quint16 hihi, ByteOrder order) { - return (quint32)makeLong(lo, hi, order); + return (quint64)makeInt64(lolo, lohi, hilo, hihi, order); } /// diff --git a/omodscan/omodscan.pro b/omodscan/omodscan.pro index cdd121a..c01c2b8 100644 --- a/omodscan/omodscan.pro +++ b/omodscan/omodscan.pro @@ -4,7 +4,7 @@ CONFIG += c++17 CONFIG -= debug_and_release CONFIG -= debug_and_release_target -VERSION = 1.6.1 +VERSION = 1.7.0 QMAKE_TARGET_PRODUCT = "Open ModScan" QMAKE_TARGET_DESCRIPTION = "An Open Source Modbus Master (Client) Utility" @@ -78,6 +78,7 @@ SOURCES += \ modbustcpscanner.cpp \ qfixedsizedialog.cpp \ qhexvalidator.cpp \ + qint64validator.cpp \ quintvalidator.cpp \ recentfileactionlist.cpp \ windowactionlist.cpp @@ -166,6 +167,7 @@ HEADERS += \ numericutils.h \ qfixedsizedialog.h \ qhexvalidator.h \ + qint64validator.h \ qmodbusadu.h \ qmodbusadurtu.h \ qmodbusadutcp.h \ diff --git a/omodscan/qint64validator.cpp b/omodscan/qint64validator.cpp new file mode 100644 index 0000000..f09a7ae --- /dev/null +++ b/omodscan/qint64validator.cpp @@ -0,0 +1,43 @@ +#include "qint64validator.h" + +/// +/// \brief QInt64Validator::QInt64Validator +/// \param parent +/// +QInt64Validator::QInt64Validator(QObject *parent) + : QValidator{parent} + ,_bottom(0) + ,_top(UINT_MAX) +{ +} + +/// +/// \brief QInt64Validator::QInt64Validator +/// \param bottom +/// \param top +/// \param parent +/// +QInt64Validator::QInt64Validator(qint64 bottom, qint64 top, QObject *parent) + : QValidator(parent) + ,_bottom(bottom) + ,_top(top) +{ + +} + +/// +/// \brief QInt64Validator::validate +/// \return +/// +QValidator::State QInt64Validator::validate(QString& input, int &) const +{ + bool ok = false; + const auto value = input.toLongLong(&ok, 10); + + if (ok && value >=_bottom && value <=_top ) + { + return QValidator::Acceptable; + } + + return QValidator::Invalid; +} diff --git a/omodscan/qint64validator.h b/omodscan/qint64validator.h new file mode 100644 index 0000000..30dfcff --- /dev/null +++ b/omodscan/qint64validator.h @@ -0,0 +1,24 @@ +#ifndef QINT64VALIDATOR_H +#define QINT64VALIDATOR_H + +#include +#include + +/// +/// \brief The QInt64Validator class +/// +class QInt64Validator : public QValidator +{ + Q_OBJECT +public: + explicit QInt64Validator(QObject *parent = nullptr); + QInt64Validator(qint64 bottom, qint64 top, QObject *parent = nullptr); + + State validate(QString &, int &) const override; + +private: + qint64 _bottom; + qint64 _top; +}; + +#endif // QINT64VALIDATOR_H diff --git a/omodscan/qmodbusadurtu.h b/omodscan/qmodbusadurtu.h index 1c9a5aa..c685673 100644 --- a/omodscan/qmodbusadurtu.h +++ b/omodscan/qmodbusadurtu.h @@ -47,7 +47,7 @@ class QModbusAduRtu : public QModbusAdu /// \return /// quint16 checksum() const { - return makeWord(_data[_data.size() - 1], _data[_data.size() - 2], ByteOrder::LittleEndian); + return makeUInt16(_data[_data.size() - 1], _data[_data.size() - 2], ByteOrder::LittleEndian); } /// diff --git a/omodscan/qmodbusadutcp.h b/omodscan/qmodbusadutcp.h index 3e51cd1..0349770 100644 --- a/omodscan/qmodbusadutcp.h +++ b/omodscan/qmodbusadutcp.h @@ -39,7 +39,7 @@ class QModbusAduTcp : public QModbusAdu /// \return /// quint16 transactionId() const { - return makeWord(_data[1], _data[0], ByteOrder::LittleEndian); + return makeUInt16(_data[1], _data[0], ByteOrder::LittleEndian); } /// @@ -48,7 +48,7 @@ class QModbusAduTcp : public QModbusAdu /// void setTransactionId(quint16 id) { quint8 lo,hi; - breakWord(id, lo, hi, ByteOrder::LittleEndian); + breakUInt16(id, lo, hi, ByteOrder::LittleEndian); _data[1] = lo; _data[0] = hi; } @@ -57,7 +57,7 @@ class QModbusAduTcp : public QModbusAdu /// \return /// quint16 protocolId() const { - return makeWord(_data[3], _data[2], ByteOrder::LittleEndian); + return makeUInt16(_data[3], _data[2], ByteOrder::LittleEndian); } /// @@ -65,7 +65,7 @@ class QModbusAduTcp : public QModbusAdu /// \return /// quint16 length() const { - return makeWord(_data[5], _data[4], ByteOrder::LittleEndian); + return makeUInt16(_data[5], _data[4], ByteOrder::LittleEndian); } /// diff --git a/omodscan/quintvalidator.cpp b/omodscan/quintvalidator.cpp index 3636bf2..4b88b42 100644 --- a/omodscan/quintvalidator.cpp +++ b/omodscan/quintvalidator.cpp @@ -17,7 +17,7 @@ QUIntValidator::QUIntValidator(QObject *parent) /// \param top /// \param parent /// -QUIntValidator::QUIntValidator(uint bottom, uint top, QObject *parent) +QUIntValidator::QUIntValidator(quint64 bottom, quint64 top, QObject *parent) : QValidator(parent) ,_bottom(bottom) ,_top(top) @@ -32,7 +32,7 @@ QUIntValidator::QUIntValidator(uint bottom, uint top, QObject *parent) QValidator::State QUIntValidator::validate(QString& input, int &) const { bool ok = false; - const auto value = input.toUInt(&ok, 10); + const auto value = input.toULongLong(&ok, 10); if (ok && value >=_bottom && value <=_top ) { diff --git a/omodscan/quintvalidator.h b/omodscan/quintvalidator.h index 18476fc..00556bb 100644 --- a/omodscan/quintvalidator.h +++ b/omodscan/quintvalidator.h @@ -12,13 +12,13 @@ class QUIntValidator : public QValidator Q_OBJECT public: explicit QUIntValidator(QObject *parent = nullptr); - QUIntValidator(uint bottom, uint top, QObject *parent = nullptr); + QUIntValidator(quint64 bottom, quint64 top, QObject *parent = nullptr); State validate(QString &, int &) const override; private: - uint _bottom; - uint _top; + quint64 _bottom; + quint64 _top; }; #endif // QUINTVALIDATOR_H diff --git a/omodscan/res/actionBigEndian.png b/omodscan/res/actionBigEndian.png index a1cc310..d9da4b9 100644 Binary files a/omodscan/res/actionBigEndian.png and b/omodscan/res/actionBigEndian.png differ diff --git a/omodscan/res/actionBinary.png b/omodscan/res/actionBinary.png index 62c3afc..8133866 100644 Binary files a/omodscan/res/actionBinary.png and b/omodscan/res/actionBinary.png differ diff --git a/omodscan/res/actionDblFloat.png b/omodscan/res/actionDblFloat.png index 09f5af5..2b5543c 100644 Binary files a/omodscan/res/actionDblFloat.png and b/omodscan/res/actionDblFloat.png differ diff --git a/omodscan/res/actionFloatingPt.png b/omodscan/res/actionFloatingPt.png index 071847d..71c49f1 100644 Binary files a/omodscan/res/actionFloatingPt.png and b/omodscan/res/actionFloatingPt.png differ diff --git a/omodscan/res/actionHex.png b/omodscan/res/actionHex.png index cb9360e..46ad429 100644 Binary files a/omodscan/res/actionHex.png and b/omodscan/res/actionHex.png differ diff --git a/omodscan/res/actionInt16.png b/omodscan/res/actionInt16.png new file mode 100644 index 0000000..d724c96 Binary files /dev/null and b/omodscan/res/actionInt16.png differ diff --git a/omodscan/res/actionInt32.png b/omodscan/res/actionInt32.png new file mode 100644 index 0000000..dd1624d Binary files /dev/null and b/omodscan/res/actionInt32.png differ diff --git a/omodscan/res/actionInt64.png b/omodscan/res/actionInt64.png new file mode 100644 index 0000000..f4b9b10 Binary files /dev/null and b/omodscan/res/actionInt64.png differ diff --git a/omodscan/res/actionInteger.png b/omodscan/res/actionInteger.png deleted file mode 100644 index 5dccd15..0000000 Binary files a/omodscan/res/actionInteger.png and /dev/null differ diff --git a/omodscan/res/actionLittleEndian.png b/omodscan/res/actionLittleEndian.png index 3cdd422..219839c 100644 Binary files a/omodscan/res/actionLittleEndian.png and b/omodscan/res/actionLittleEndian.png differ diff --git a/omodscan/res/actionLongInteger.png b/omodscan/res/actionLongInteger.png deleted file mode 100644 index 782f721..0000000 Binary files a/omodscan/res/actionLongInteger.png and /dev/null differ diff --git a/omodscan/res/actionSwappedDbl.png b/omodscan/res/actionSwappedDbl.png index 043f3dc..4c65df0 100644 Binary files a/omodscan/res/actionSwappedDbl.png and b/omodscan/res/actionSwappedDbl.png differ diff --git a/omodscan/res/actionSwappedFP.png b/omodscan/res/actionSwappedFP.png index 6966a18..ff9b36c 100644 Binary files a/omodscan/res/actionSwappedFP.png and b/omodscan/res/actionSwappedFP.png differ diff --git a/omodscan/res/actionSwappedInt32.png b/omodscan/res/actionSwappedInt32.png new file mode 100644 index 0000000..3fca9f7 Binary files /dev/null and b/omodscan/res/actionSwappedInt32.png differ diff --git a/omodscan/res/actionSwappedInt64.png b/omodscan/res/actionSwappedInt64.png new file mode 100644 index 0000000..a863f96 Binary files /dev/null and b/omodscan/res/actionSwappedInt64.png differ diff --git a/omodscan/res/actionSwappedLI.png b/omodscan/res/actionSwappedLI.png deleted file mode 100644 index f592af2..0000000 Binary files a/omodscan/res/actionSwappedLI.png and /dev/null differ diff --git a/omodscan/res/actionSwappedUInt32.png b/omodscan/res/actionSwappedUInt32.png new file mode 100644 index 0000000..3901cd1 Binary files /dev/null and b/omodscan/res/actionSwappedUInt32.png differ diff --git a/omodscan/res/actionSwappedUInt64.png b/omodscan/res/actionSwappedUInt64.png new file mode 100644 index 0000000..01215bf Binary files /dev/null and b/omodscan/res/actionSwappedUInt64.png differ diff --git a/omodscan/res/actionSwappedUnsignedLI.png b/omodscan/res/actionSwappedUnsignedLI.png deleted file mode 100644 index 43d13ee..0000000 Binary files a/omodscan/res/actionSwappedUnsignedLI.png and /dev/null differ diff --git a/omodscan/res/actionUInt16.png b/omodscan/res/actionUInt16.png new file mode 100644 index 0000000..e680a95 Binary files /dev/null and b/omodscan/res/actionUInt16.png differ diff --git a/omodscan/res/actionUInt32.png b/omodscan/res/actionUInt32.png new file mode 100644 index 0000000..2a32114 Binary files /dev/null and b/omodscan/res/actionUInt32.png differ diff --git a/omodscan/res/actionUInt64.png b/omodscan/res/actionUInt64.png new file mode 100644 index 0000000..3eb05ca Binary files /dev/null and b/omodscan/res/actionUInt64.png differ diff --git a/omodscan/res/actionUnsignedDecimal.png b/omodscan/res/actionUnsignedDecimal.png deleted file mode 100644 index b764f3f..0000000 Binary files a/omodscan/res/actionUnsignedDecimal.png and /dev/null differ diff --git a/omodscan/res/actionUnsignedLI.png b/omodscan/res/actionUnsignedLI.png deleted file mode 100644 index 9e534ec..0000000 Binary files a/omodscan/res/actionUnsignedLI.png and /dev/null differ diff --git a/omodscan/res/license.txt b/omodscan/res/license.txt index 91ce694..8c89a4c 100644 --- a/omodscan/res/license.txt +++ b/omodscan/res/license.txt @@ -1,6 +1,6 @@ MIT License -Copyright 2023 Alexandr Ananev [mail@ananev.org] +Copyright 2024 Alexandr Ananev [mail@ananev.org] Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/omodscan/resources.qrc b/omodscan/resources.qrc index 5e91527..f19c9ed 100644 --- a/omodscan/resources.qrc +++ b/omodscan/resources.qrc @@ -8,7 +8,7 @@ res/actionDisconnect.png res/actionFloatingPt.png res/actionHex.png - res/actionInteger.png + res/actionInt16.png res/actionNew.png res/actionOpen.png res/actionPrint.png @@ -17,7 +17,7 @@ res/actionShowTraffic.png res/actionSwappedDbl.png res/actionSwappedFP.png - res/actionUnsignedDecimal.png + res/actionUInt16.png res/omodscan.png res/iconAbout.png res/iconLandscape.png @@ -28,12 +28,16 @@ res/actionLittleEndian.png res/pointGreen.png res/pointEmpty.png - res/actionLongInteger.png - res/actionSwappedLI.png - res/actionSwappedUnsignedLI.png - res/actionUnsignedLI.png + res/actionInt32.png + res/actionSwappedInt32.png + res/actionSwappedUInt32.png + res/actionUInt32.png res/iconScanStart.png res/iconScanStop.png res/iconClear.png + res/actionInt64.png + res/actionUInt64.png + res/actionSwappedInt64.png + res/actionSwappedUInt64.png diff --git a/omodscan/translations/omodscan_ru.qm b/omodscan/translations/omodscan_ru.qm index ba26532..f38d3c4 100644 Binary files a/omodscan/translations/omodscan_ru.qm and b/omodscan/translations/omodscan_ru.qm differ diff --git a/omodscan/translations/omodscan_ru.ts b/omodscan/translations/omodscan_ru.ts index 4a6d20c..43eb1be 100644 --- a/omodscan/translations/omodscan_ru.ts +++ b/omodscan/translations/omodscan_ru.ts @@ -577,186 +577,186 @@ MODBUS Сканер - + Baud Rate Скорость - + Connection Подключение - + Serial port Порт подключения - + Address Range Диапазон IP адресов - - - + + + from с - - - + + + to по - + Subnet Mask Маска подсети - + Port Range Диапазон портов - - + + Start Scan Сканировать - + <html><head/><body><p><span style=" font-weight:700;">Scanning:</span></p></body></html> <html><head/><body><p><span style=" font-weight:700;">Сканирование:</span></p></body></html> - + Address: Адрес: - + Port: Порт: - + Baud Rate: Скорость бит/с: - + Data Bits: Биты данных: - + Parity: Четность: - + Stop Bits: Стоповые биты: - + Device Id: Узел: - + Scan Time Вермя сканирования - + Data Bits Биты данных - + Parity Четность - + None Нет - + Odd Нечет - + Even Чёт - + Stop Bits Стоповые биты - + Device Id Узел - + Modbus Request Запрос Modbus - + Function Функция - + Address Адрес - + Length Количество - + Response Timeout Таймаут ответа - + msec мсек - + Retry On Timeout Повторить по таймауту - + <html><head/><body><p><span style=" font-weight:700;">Scan Results:</span></p></body></html> <html><head/><body><p><span style=" font-weight:700;">Результаты:</span></p></body></html> - - + + PORT: Device Id (serial port settings) Порт: Узел (параметры порта) - + Clear Results Очистить результаты @@ -771,87 +771,87 @@ Маркер - + Stop Scan Остановить - + Address: port (Device Id) Адрес: порт (Узел) - + Clear previous scan results? Очистить результаты предыдущего сканирования? - + Baud Rate: Скорость бит/с: - + Data Bits: Биты данных: - + Parity: Четность: - + Stop Bits: Стоповые биты: - + Address: Адрес: - + Port: Порт: - + Device Id: Узел: - + Baud Rate: %1 Скорость бит/с: %1 - + Data Bits: %1 Биты данных: %1 - + Parity: %1 Четность: %1 - + Stop Bits: %1 Стоповые биты: %1 - + Address: %1 Адрес: %1 - + Port: %1 Порт: %1 - + Device Id: %1 Узел: %1 @@ -1275,12 +1275,12 @@ single-point write functions 05 and 06.) Значение: - + Auto Simulation Симуляция - + Value, (HEX): Значение, (Шестн): @@ -1498,353 +1498,417 @@ Valid Slave Responses: %2 - + Byte Order - Порядок байтов + Порядок байт - + Extended Расширенные параметры - + View Вид - + Config Конфигурация - + Colors Цвета - + Language Язык - + Window Окно - + Help Помощь - - + + Toolbar Панель инструментов - + Display Bar Панель отображения - + New Новый - + Open... Открыть... - + Close Закрыть - + Save Сохранить - + Save As... Сохранить как... - + Print... Печать... - + Print Setup... Настройка печати... - + Recent File Последние файлы - + Exit Выход - + Connect Подключиться - + Disconnect Отключиться - + Enable Вкл - + Disable Выкл - + Save Config Сохранить конфиг - + Restore Now Восстановить конфиг - + Quick Connect Быстрое подключение - + Data Definition Настройки отображения - + Show Data Данные - + Show Traffic Трафик - + Binary Двоичный - + Hex Шестандцатиричный - + + 32-bit Integer + 32-бит целое + + + + + Swapped 32-bit Integer + Перевернутое 32-бит целое + + + + Unsigned 32-bit Integer + Беззнаковое 32-бит целое + + + + + Swapped Unsigned 32-bit Integer + Перевернутое беззнаковое 32-бит целое + + + + 64-bit Integer + 64-бит целое + + + + Swapped 64-bit Integer + Перевернутое 64-бит целое + + + + Unsigned 64-bit Integer + Беззнаковое 64-бит целое + + + + Swapped Unsigned 64-bit Integer + Перевернутое беззнаковое 64-бит целое + + Unsigned Decimal - Беззнаковый десятичный + Беззнаковый десятичный - Integer - Целый + Целый - Floating Pt - С плавающей точкой + С плавающей точкой - Swapped FP - Перевернутое с плавающей точкой + Перевернутое с плавающей точкой - Dbl Float - Двойной точности + Двойной точности - Swapped Dbl - Перевернутое двойной точности + Перевернутое двойной точности - + Hex Addresses Шестнадцатиричные адреса - + Force Coils Предустановка coils - + Preset Regs Предустановка регистров - + Mask Write Запись по маске - + User Msg Пользовательская команда - + Text Capture Захват в файл - + Capture Off Остановить захват - + Reset Ctrs Сброс счетчиков - + Status Bar Строка состояния - + Dsiplay Bar Панель отображения - + Background Задний план - + Foreground Передний план - + Status Статус - + Font Шрифт - + Cascade Каскадно - + Tile Замостить - - + + MODBUS Scanner Cканер MODBUS - Long Integer - Длинное целое + Длинное целое - Swapped LI - Перевернутое ДЦ + Перевернутое ДЦ - Swapped Long Integer - Перевернутое длинное целое + Перевернутое длинное целое - Unsigned Long Integer - Беззнаковое длинное целое + Беззнаковое длинное целое - Swapped Unsigned LI - Перевернутое беззнаковое ДЦ + Перевернутое беззнаковое ДЦ - Swapped Unsigned Long Integer - Перевернутое беззнаковое длинное целое + Перевернутое беззнаковое длинное целое - - + + Msg Parser Анализатор сообщений - + About Open ModScan... О программе Open ModScan... - + + Unsigned 16-bit Intger + Беззнаковое 16-бит целое + + + + 16-bit Integer + 16-бит целое + + + + + Float + С плавающей точкой + + + + + Swapped Float + Перевернутое с плавающей точкой + + + + + Double + Двойной точности + + + + + Swapped Double + Перевернутое двойной точности + + + Windows... Окна... - + English - + Русский - + Address scan Сканирование адресов - - - - + + + + All files (*) Все файлы (*) - + %1 was not found %1 не найден - + Failed to open %1 Ошибка открытия файла %1 @@ -1857,29 +1921,29 @@ Valid Slave Responses: %2 Некорректный запрос Modbus - - + + Coil Write Failure Ошибка записи в Coil регистр - - + + Register Write Failure Ошибка записи в регистр - + Mask Write Register Failure Ошибка записи в регистр по маске - + Mask Register Write Failure Ошибка записи в регистр по маске - + Connection error. %1 Ошибка подключения. %1 @@ -2178,12 +2242,12 @@ Valid Slave Responses: %2 OutputWidget - + %1: Enter Description %1: Введите описание - + Data Uninitialized Данные не инициализированы