From 242d0095c040d41d64f47f535daddafd0c73b969 Mon Sep 17 00:00:00 2001 From: Alex Spataru Date: Sun, 13 Oct 2024 23:02:45 -0500 Subject: [PATCH] Let user define FFT sampling rate --- app/src/IO/Drivers/Serial.cpp | 2 +- app/src/IO/Manager.cpp | 49 --- app/src/IO/Manager.h | 5 - app/src/JSON/Dataset.cpp | 12 +- app/src/JSON/Dataset.h | 2 + app/src/JSON/ProjectModel.cpp | 18 +- app/src/UI/Widgets/FFTPlot.cpp | 13 +- app/src/UI/Widgets/FFTPlot.h | 1 + app/translations/qm/de_DE.qm | Bin 51627 -> 52435 bytes app/translations/qm/en_US.qm | Bin 29972 -> 30426 bytes app/translations/qm/es_MX.qm | Bin 52224 -> 53044 bytes app/translations/qm/fr_FR.qm | Bin 53170 -> 54024 bytes app/translations/qm/ru_RU.qm | Bin 50751 -> 51559 bytes app/translations/qm/zh_CN.qm | Bin 36458 -> 37022 bytes app/translations/ts/de_DE.ts | 313 ++++++++++--------- app/translations/ts/en_US.ts | 321 +++++++++++--------- app/translations/ts/es_MX.ts | 313 ++++++++++--------- app/translations/ts/fr_FR.ts | 313 ++++++++++--------- app/translations/ts/ru_RU.ts | 313 ++++++++++--------- app/translations/ts/zh_CN.ts | 313 ++++++++++--------- examples/HexadecimalADC/HexadecimalADC.json | 6 + 21 files changed, 1092 insertions(+), 902 deletions(-) diff --git a/app/src/IO/Drivers/Serial.cpp b/app/src/IO/Drivers/Serial.cpp index 9782431c..167dca89 100644 --- a/app/src/IO/Drivers/Serial.cpp +++ b/app/src/IO/Drivers/Serial.cpp @@ -775,7 +775,7 @@ void IO::Drivers::Serial::readSettings() for (int i = 0; i < list.count(); ++i) m_baudRateList.append(list.at(i)); - // Sort baud rate list + // Sort baud rate list #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) for (auto i = 0; i < m_baudRateList.count() - 1; ++i) { diff --git a/app/src/IO/Manager.cpp b/app/src/IO/Manager.cpp index 342ae3eb..13ed874b 100644 --- a/app/src/IO/Manager.cpp +++ b/app/src/IO/Manager.cpp @@ -64,7 +64,6 @@ IO::Manager::Manager() , m_startSequence(QStringLiteral("/*")) , m_finishSequence(QStringLiteral("*/")) , m_separatorSequence(QStringLiteral(",")) - , m_samplingRate(0) { // Set initial settings setMaxBufferSize(1024 * 1024); @@ -146,14 +145,6 @@ int IO::Manager::maxBufferSize() const return m_maxBufferSize; } -/** - * Returns the calculated sampling rate of the data - */ -qreal IO::Manager::samplingRate() const -{ - return m_samplingRate; -} - /** * Returns a pointer to the currently selected driver. * @@ -282,10 +273,6 @@ void IO::Manager::connectDevice() else disconnectDevice(); - // Restart sampling rate timer - m_samplingRate = 0; - m_samplingRateTimer.start(); - // Update UI Q_EMIT connectedChanged(); } @@ -310,10 +297,6 @@ void IO::Manager::disconnectDevice() m_dataBuffer.clear(); m_dataBuffer.reserve(maxBufferSize()); - // Stop sampling rate timer - m_samplingRate = 0; - m_samplingRateTimer.invalidate(); - // Update UI Q_EMIT driverChanged(); Q_EMIT connectedChanged(); @@ -341,9 +324,6 @@ void IO::Manager::processPayload(const QByteArray &payload) { if (!payload.isEmpty()) { - // Update sampling rate - updateSamplingRate(); - // Update received bytes indicator m_receivedBytes += payload.size(); if (m_receivedBytes >= UINT64_MAX) @@ -642,32 +622,6 @@ void IO::Manager::clearTempBuffer() m_dataBuffer.clear(); } -/** - * Calculates the sampling rate of the processed data - */ -void IO::Manager::updateSamplingRate() -{ - // Measure the time elapsed since the last call - qint64 elapsedTime = m_samplingRateTimer.restart(); - if (elapsedTime > 0) - { - // Calculate the new sampling rate from the elapsed time. - // The elapsed time is in milliseconds, so we convert it to Hz (samples per - // second). - float newSamplingRate = 1000.0f / static_cast(elapsedTime); - - // Apply an exponential moving average (EMA) to smooth the sampling rate. - // The smoothing factor is made time-dependent: 'factor' is based on the - // elapsed time, converted to seconds (elapsedTime * 1e-3). We also cap - // 'factor' at 0.5 to prevent the system from overreacting to large timing - // variations. This helps balance responsiveness to larger timing shifts and - // smoothing during periods of stability. - const float factor = qMin(elapsedTime * 1e-3, 0.5f); - m_samplingRate - = (factor * newSamplingRate) + ((1.0f - factor) * m_samplingRate); - } -} - /** * Changes the target device pointer. Deletion should be handled by the * interface implementation, not by this class. @@ -695,9 +649,6 @@ void IO::Manager::onDataReceived(const QByteArray &data) if (!driver()) disconnectDevice(); - // Update sampling rate - updateSamplingRate(); - // Read data & append it to buffer auto bytes = data.length(); diff --git a/app/src/IO/Manager.h b/app/src/IO/Manager.h index 0018b1f7..df71ccf2 100644 --- a/app/src/IO/Manager.h +++ b/app/src/IO/Manager.h @@ -145,7 +145,6 @@ public: [[nodiscard]] bool configurationOk(); [[nodiscard]] int maxBufferSize() const; - [[nodiscard]] qreal samplingRate() const; [[nodiscard]] HAL_Driver *driver(); [[nodiscard]] SelectedDriver selectedDriver() const; @@ -172,7 +171,6 @@ public slots: private slots: void readFrames(); void clearTempBuffer(); - void updateSamplingRate(); void setDriver(HAL_Driver *driver); void onDataReceived(const QByteArray &data); @@ -192,8 +190,5 @@ private: QString m_finishSequence; QString m_separatorSequence; SelectedDriver m_selectedDriver; - - qreal m_samplingRate; - QElapsedTimer m_samplingRateTimer; }; } // namespace IO diff --git a/app/src/JSON/Dataset.cpp b/app/src/JSON/Dataset.cpp index 757a731e..64d5c97a 100644 --- a/app/src/JSON/Dataset.cpp +++ b/app/src/JSON/Dataset.cpp @@ -37,6 +37,7 @@ JSON::Dataset::Dataset(const int groupId, const int datasetId) , m_alarm(0) , m_ledHigh(1) , m_fftSamples(1024) + , m_fftSamplingRate(100) , m_groupId(groupId) , m_datasetId(datasetId) { @@ -154,6 +155,14 @@ int JSON::Dataset::fftSamples() const return qMax(1, m_fftSamples); } +/** + * Returns the sampling rate for the FFT transform + */ +int JSON::Dataset::fftSamplingRate() const +{ + return m_fftSamplingRate; +} + /** * @return The index of the group to which the dataset belongs to, used by * the project model to easily identify which group/dataset to update @@ -207,6 +216,7 @@ QJsonObject JSON::Dataset::serialize() const object.insert(QStringLiteral("widget"), m_widget); object.insert(QStringLiteral("ledHigh"), m_ledHigh); object.insert(QStringLiteral("fftSamples"), m_fftSamples); + object.insert(QStringLiteral("fftSamplingRate"), m_fftSamplingRate); return object; } @@ -233,7 +243,7 @@ bool JSON::Dataset::read(const QJsonObject &object) m_widget = object.value(QStringLiteral("widget")).toString(); m_ledHigh = object.value(QStringLiteral("ledHigh")).toDouble(); m_fftSamples = object.value(QStringLiteral("fftSamples")).toInt(); - + m_fftSamplingRate = object.value(QStringLiteral("fftSamplingRate")).toInt(); if (m_value.isEmpty()) m_value = QStringLiteral("--.--"); diff --git a/app/src/JSON/Dataset.h b/app/src/JSON/Dataset.h index 050eb18c..8e183b07 100644 --- a/app/src/JSON/Dataset.h +++ b/app/src/JSON/Dataset.h @@ -84,6 +84,7 @@ public: [[nodiscard]] double alarm() const; [[nodiscard]] double ledHigh() const; [[nodiscard]] int fftSamples() const; + [[nodiscard]] int fftSamplingRate() const; [[nodiscard]] int groupId() const; [[nodiscard]] int datasetId() const; @@ -117,6 +118,7 @@ private: double m_alarm; double m_ledHigh; int m_fftSamples; + int m_fftSamplingRate; int m_groupId; int m_datasetId; diff --git a/app/src/JSON/ProjectModel.cpp b/app/src/JSON/ProjectModel.cpp index a4befb6e..09563cbc 100644 --- a/app/src/JSON/ProjectModel.cpp +++ b/app/src/JSON/ProjectModel.cpp @@ -84,7 +84,8 @@ typedef enum kDatasetView_Min, /**< Represents the dataset minimum value item. */ kDatasetView_Max, /**< Represents the dataset maximum value item. */ kDatasetView_Alarm, /**< Represents the dataset alarm value item. */ - kDatasetView_FFT_Samples /**< Represents the FFT window size item. */ + kDatasetView_FFT_Samples, /**< Represents the FFT window size item. */ + kDatasetView_FFT_SamplingRate, /**< Represents the FFT sampling rate item. */ } DatasetItem; // clang-format on @@ -2315,6 +2316,18 @@ void JSON::ProjectModel::buildDatasetModel(const JSON::Dataset &dataset) fftWindow->setData(tr("Samples for FFT calculation"), ParameterDescription); m_datasetModel->appendRow(fftWindow); + // Add FFT sampling rate + auto fftSamplingRate = new QStandardItem(); + fftSamplingRate->setEditable(true); + fftSamplingRate->setData(IntField, WidgetType); + fftSamplingRate->setData(100, PlaceholderValue); + fftSamplingRate->setData(dataset.fftSamplingRate(), EditableValue); + fftSamplingRate->setData(tr("FFT Sampling Rate"), ParameterName); + fftSamplingRate->setData(kDatasetView_FFT_SamplingRate, ParameterType); + fftSamplingRate->setData(tr("Sampling rate (Hz) for FFT calculation"), + ParameterDescription); + m_datasetModel->appendRow(fftSamplingRate); + // Add LED panel checkbox auto led = new QStandardItem(); led->setEditable(true); @@ -2759,6 +2772,9 @@ void JSON::ProjectModel::onDatasetItemChanged(QStandardItem *item) case kDatasetView_FFT_Samples: m_selectedDataset.m_fftSamples = m_fftSamples.at(value.toInt()).toInt(); break; + case kDatasetView_FFT_SamplingRate: + m_selectedDataset.m_fftSamplingRate = value.toInt(); + break; default: break; } diff --git a/app/src/UI/Widgets/FFTPlot.cpp b/app/src/UI/Widgets/FFTPlot.cpp index 48894cef..a7b233a2 100644 --- a/app/src/UI/Widgets/FFTPlot.cpp +++ b/app/src/UI/Widgets/FFTPlot.cpp @@ -20,7 +20,6 @@ * THE SOFTWARE. */ -#include "IO/Manager.h" #include "UI/Dashboard.h" #include "Misc/ThemeManager.h" #include "UI/Widgets/FFTPlot.h" @@ -60,6 +59,9 @@ Widgets::FFTPlot::FFTPlot(int index) --size; m_size = size; + // Obtain sampling rate from dataset + m_samplingRate = dataset.fftSamplingRate(); + // Allocate FFT and sample arrays m_fft.reset(new float[m_size]); m_samples.reset(new float[m_size]); @@ -94,9 +96,6 @@ void Widgets::FFTPlot::updateData() auto plotData = UI::Dashboard::instance().fftPlotValues(); if (plotData.count() > m_index) { - // Obtain sampling rate from dashboard - const auto samplingRate = IO::Manager::instance().samplingRate(); - // Obtain samples from data auto data = plotData.at(m_index); for (int i = 0; i < m_size; ++i) @@ -115,7 +114,7 @@ void Widgets::FFTPlot::updateData() const qreal im = m_fft[m_size / 2 + i]; const qreal magnitude = sqrt(re * re + im * im); const qreal frequency - = static_cast(i) * samplingRate / static_cast(m_size); + = static_cast(i) * m_samplingRate / static_cast(m_size); points[i] = QPointF(frequency, magnitude); if (magnitude > maxMagnitude) maxMagnitude = magnitude; @@ -130,13 +129,13 @@ void Widgets::FFTPlot::updateData() const qreal dB = (magnitude > 0) ? 20 * log10(magnitude) : -INFINITY; // Avoid log10(0) const qreal frequency - = static_cast(i) * samplingRate / static_cast(m_size); + = static_cast(i) * m_samplingRate / static_cast(m_size); points[i] = QPointF(frequency, dB); } // Plot obtained data m_curve.setSamples(points); - m_plot.setAxisScale(QwtPlot::xBottom, 0, samplingRate / 2); + m_plot.setAxisScale(QwtPlot::xBottom, 0, m_samplingRate / 2); m_plot.replot(); } } diff --git a/app/src/UI/Widgets/FFTPlot.h b/app/src/UI/Widgets/FFTPlot.h index e41aeee1..1f60c96f 100644 --- a/app/src/UI/Widgets/FFTPlot.h +++ b/app/src/UI/Widgets/FFTPlot.h @@ -52,6 +52,7 @@ private slots: private: int m_size; ///< Size of the FFT data array. + int m_samplingRate; ///< Sampling rate for the FFT data. int m_index; ///< Index of the FFT plot data. QwtPlot m_plot; ///< Plot widget for FFT. QwtPlotCurve m_curve; ///< Curve for the FFT data. diff --git a/app/translations/qm/de_DE.qm b/app/translations/qm/de_DE.qm index da74869af6af0b5f8ec56fb30e754d52e87f1ad9..8b4b9cd4646488f8dafe92f7db4418d307f1f572 100644 GIT binary patch delta 3635 zcmaJ@2Ut{R7Clqm%)F@}Iz$i{(V&!QM3mS?Y@ie!ks_k>;s8n$v7iEiB_KXPi~<&# zpn@POf+P_Mq8p7G<7zCy5@TgG(WoT47bctCZ@=u$e8YLX_wN1gJ@?%E|J9t}@(#gP zbL%evW*p#@N$3HDKG$O|qsQ_~gbRS&Rk<_F`HjxG;pVOfF9Y-1fkPbNRSHa80W4|- z^3LnA;v8@*0dV*X!Yq2{=xGSc=^b0O9xDe!*w_VBa=91Osax|QeDX1Ha2=5P-D(;8^a zU0C$A7)TtB2$M9xIUE@t0|9quY&cUz6tXD%_y|m~jzLKgah0?IWxn;auqi55Z37Bb zTo>OwHB^FT`CMStJG3oPQBmD-CYILqaltv$Z-JECxGtgRZuj+AwH3FtB$E0jJiJ5e zMhVb$su_rWfZtWCD83mytHUvX#Yx`C&ig=&3(p~>2cPq1GXi2VlIK@P!kGVndXIs|Obl1~v%(Vd+E>eIR%#^d!%h1ux_J0wu|U zcTTlH!b(oXsDoB46S{X#1mvrQ^S+t}tT7V?*%7}d4hSRe?gNfx3w2LP2ZmRLDHFA% zqXJ<{Z2(YpSD1Q_nl$LLFsm>R@Ejq`e-cc=OcEBlP#v8-^_a7W%VdV7?%OXsIIS>9NRw5%zSX?dOd7B}!xYV#fMn3t%N>>@IWw@mgkLM+`UzkqNJx^AM?1 zKh-kx#!*ErImUYcRc^@vCfJ!0YrMroY;7b#3}%wVQvmgIJyshsTPogBobRScD#kIl50U^AH#2wK zwJ^d74Rc551&n2xm&=7f*iP7dZHv=-AB!>e%(7uO9Uw2iBt7 zqp39IQql71Ufd}boO%uTMvFxUEUA=!+*Pr;bcI4}TUAQ&59Hp9hq)$P z5^G9iCFVA{BgOSC{mI--d}J4miM%)B=9UoZqxa$#hh@Mh6Y-a-bReLS z`&?q4n!jIs=M)tyv`pM}(TR$1TB2V5Ej|^ z?0yIuxstq9xfqA~VUo%@mjD-yr0VWH+BtShYFjcW0FC5C+z4Q0f#g&->D04H(jH80 z!}XQ?;69&pEatYe7GpT}o`>eV!omvZbH3sOj}8M`J`2q>f3^^1al(T!|+ z90xRy`2*|OOxOdC6WA?Dmr2QvY~c>F*PdicE1#1eFSg8#NQoZ8R;1R^$k@yt)XoJm zO4;TIt$=wH+i{_da#<}ku-q1pL%8d1f1+_g-4YjQe~|E2VP6h0D#SluVWBTB-bQVp)tm6=o`{$3rt@8C|5t@xRMT z@`?D3fwH}W%1CU+vVAuw61!uveZLXzPvqLkO|g~iR`@!~FG|+=JewN0LH2YQiMn9A z?CHb4K;1sMAd3RA50m#RnnPRhdHI0XX+X^>x$R_2;D8@zp-}r3bjT-OctLZlOOI}@ zdd%!6pF5x2T07~nIi8U6x6#Sxc5R{_+9UVU(uu_{SC0pc{tx-(OfTAC+T~Y!-{a)>f+>kHzIt49MgF*wG%{za!XVokSbSY! zvYoQBv3{)>TuB?>aW}<;K2%;&lVbMQ*T_+b!ZV-39G|DqmhoszGMuAwn6&AUVs{1y zG(6*Cl_pAEKfwE?;`^gc+>IvUJVrVKexGIdm@CkcrDPG#2qOLS7wM}f1Dky{Gkm0Oac8%hVKc&j@UQZ*-K~*_nDluiK zIyAnJ`a#0ws7(3IKh+;lz43M&fa&y|hmYWdAS56V@$@&2FadN(qz@g7U^spHJdHLm zdZ{ilCR{T&Fo9baU{+ri-f3hp`>zb4!BEUZ3amNfm5xSMf11VxCWLB+&P=hcpTBar z^B_Ai*3mbV44e>*2wFW9G4x*`66rb!I_|Kc(OkvM$dFJ?piZX=Ob(3~Q$z|cm$74~ z2F6DO#RkTO@Q7$k#1t})M95#b8wwwCnn$H%ZjYx)2ECqQV{|KeJS9i|uNeRB!}q^^4EhfrJ#qY%kNUMO zLMCD|Jc+Yds!%+Z5K}$;^>AiIKToZ9i(P{^kGDMzA zP0IQ%`cNq**;LBMv>7vIZLz$wNz;p=jrX>5{<+RM&+qyD?)$o~`@VnQ<;sqUvIF`l zX#hJ1a7-oi0D_Mg@xVwUmh=+(0SESHEYwRIJu}wpU60=fmUjSErGQs4FmD?W*b0a} zMl9_Hx?=#l&%mUKK>c+vrL@LMXT-8uU{3b~Wu+NiI>Y{QFb}5#$1}k^quqALfq5AK z_$$F$WYYgFVBgyVI1nx<0rnWcu2?{)IvX+gD%g+~itw}%t1g3$4gyBj8PVn&u(7ny zp2tSavH`oN2AKLD*qnB#kkR+=7gRflkrJJB-)=EgGS70~D=f@z!<)~)SP_p8OhM;|;mPB<&XC$5L{S=o+UkA1g;I@LEFYYyBMG?9^$s{LS@Zc_;yP*dC z=bM4>m-t7U0942IJQL@IIi z0^;;i;Z+y#@pkFxhC*Pao7gYY85$U=+ebuW&O+(hLu&z_4r#pB2RKzFP4xH#2z8L| zuB-;Ki={axw}4Sy(xV%u0qND!(%~GSJt#fq+D9^smUeVLCW%9(mppb84WCP2j3WBy zN6NUzEYWsFrWqi*3L|85I!K<4-^*Nvc|%NQhS)aTlzHY415TRC!W7QH*k`g`A;iEb zb6L%mARzOlto9te>;6bq`%?p@nk#lNlgF=-{W-yrA{r@s$}FLs@5`P>4F~e~$X+?t z0@3NBmesA@n#{Nl&I5!*X8DB$K;m>}?Ns8oshJ7AR|GWVGvR&YgCRGW_<5e>qY5Uz zHUOx2#u$FR3am9SX*rp|5*sG#;W`Rt8I$8eIyx>fVtSOA%32!=o0-NBODLKc=7+Pb zKw|=Pt8fSLYQp^TTRRYNh52tgJ^$=aBOY#JUad%>8o13$cTNRT99WrOGLZKJD@&yJ z54#&NZz9XQsYt7Hto|CM5gW};`L+eH;Mu8N7lEh{cHYHJ5bZcKNtx)u=?r^A*yVFb z(Fr2!J%*IqxRPDxOo=r z=dx)Ab;R48cLF_cG~xXFNZ(Jhxz+R65#HxQ?AHLQ@43*|BY;)moY+nsRyu>r&wi6< z9as5|H@T^jJ9#aP@|wss-kStxtX}r-7gTAvrk`S{VzamlzYnG6d4v1;U6Q6`Ece)+ ztn0a$duB?MA9*5|oqtXxF-p!IpFoWuLcA&0^IONsttyKtemn8C+}bs|SMK>-PX(}B z?)7c})qAhpZ`uvYx=g;>Z#MZXRldPT3M^`uhbbE9wE6OFRzzo9oIIVUG;)jO>25=S zqRnEQLT`EC19^SRD4H!VnfxnlGWjW3Jg3kbGMnXh z&y!feOXdCFI+6%C6}q_V^mvHE^bV17aI@m=H7t?ND{Kcy+&o`}(~WQ<*+$`B_ms&0 zO%Zfy0ib?M5o{6>-NO!3ThElOi)A z19MQ@tSDc44R9H!sJ!}}1={By7itvJR@z11n&~T;4 zr~zPSr`WGF9kN5Y;XyD>y+CDRBDLhmQqi2(Ih}SmPnqMm}LYzh=-5Nb5G@ zu`k6)l?9(RlMi;I(<=kS0+o)h6#4ZYC#m;mi05dt9W{JwYXen`3*V->N4@8S5f3Nx z-Sd-ybrJkM4O#c2Y*8!dT>ZY{|N5L72L4bptW|6{S#fuTN}1C}t!krcYy^2` z=N8q}uurIERjU@|lXFL(QF(;5(?p6@`J{RQs}*9TpqJ)*i~9wgWtFcgrJtNM_a9Y3 z7OhH)Q58-sA){ETitY$B@0(Obe-oCciCuzz_7Qtk_xc@_f=<=*IGu`bjjGR@44LJl z>U%I8sI?JfX>_=4h%n;FQX2FAg4O&9z_AE%np)?Zbw`-jH9)OvbefVOwm;pdX0^YEy$m$g(2o z?S=|jTPIP~aYE4xx{g&$7S2ebse{A{7msRyeXYX9*A#Tvb>WiV2^yluh40=l6BsT0 zx{iXi_c3DPZ^9qtr0UWGYLoOS#M~~m*&&L4%5(Lka+*meSE(I_l0e)U^`ftD0Yd{# z)Jw7`oVl55&k_l>u#sY*#@h1KOZCwda(sP)`t;GK0CQA*hB-%fi&5%M2OHo+H}#K= zQFICYOFXC18&=;`zq~_!s4mtpQ#R3zI;^p%AxRtuG?sD_dfi!#H^KeheJv5 zF`8}Ti)n_h*Thf0N|R%jCOK9{oIlZ|Ra~Ph#RyIIwK3%7Cz`{PgDHKz=5TO2utTN! z+KK2I->bRVLlb$;GtC{_Ho8U54$<^1m`P2bQ;gJ_1~_PkZ=_%DmD(|vyMbXzTKjEV z=q6OFU7JFZC$G?MzC~e1-O#3a@1&NpP+RWsA7b;Ywt8+3*?P3LF|P-B?+0zC*Li@i u(cWpj3%I@7KuzGe==R09ddB3IcfCz$&#?Mq39p^%r+xLBsXu;UGWUPjwykym diff --git a/app/translations/qm/en_US.qm b/app/translations/qm/en_US.qm index c3136ed6d09d1c2ea84b5b882fcc614d4a1c820b..bc6bbb374071746ca3a826703879b389c7f554e3 100644 GIT binary patch delta 3278 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 BrO^NY delta 3034 zcmXX|d0Z2B7Jo@*l9|aQp$J3~2q=mH1(i$WQV@|FIph@N@<2RF6^pBz^+4&Ntvg(; zR;@}!Ta^Oh$8E)3kOI0&Yg=9KD%w^Hi@F7?SlKU4`RB__e#d*?@Atho*ZX7@k7VyV z7|V%Re4iP1F5M`|(N`&Gl;_? zEQxuMMKsk&?8FMZzd`JbcZeJg5F1uY6j?~@f-pP}o6*OS*u^bGu@+{`dY9NY5VX49 zjQSslEx|dFt!9j0L+m>zh^#G%t!XC`Vq47rWL=R~$!z3N*QM>UVB<6juR2E~e}7=c zNt(CL4=EVT7@ba$Zkv&UkJK-7;hiYbr;;f8iDZx)WG+&$+{TpNN2y&n!g{6|V`ot6 zg%1#DC8b^XCsA6M8M6i{eF-)@3Y6aKO|)PSWvC|*1$a}&;{Opvl~Cqp5R<)>GPj(> zzDJbZx0fjJGA*^;LNv~w%Ho`eCi&8~&Z9*0Zc)|RDjH8g=c#6D6H(|b+V>F{3)(@o zX^jXVhYoM}JJEcT^h|D8mP=oX2}HA7sC~JP$n6q!uEO3ZUe%cDVzBDN+O*?=6Ux4-Y<}O<&WTA$)o@) zt+Lvmzk#PRWz83Yh-7K9e;p|!@_Qib^fnNUmt;L>d~vK%_TL7u7rIXrF?ulx+(C4v6GeqKFukLS%VN5#c$4*Aztx!B3 zHyd95RWZQCNlBb3n>46FUTQ*=tPF zS7AgU*-Y+a1yNofv$W?R$oPdR>Vs7{1G7FT5mw7#*4KlqjA6!f{}Pes?@W131(B^W zg{kb#LuEf>Y9b)AW3L&bw@B}??xvIzO!K^2aOKSW=S&;UAH!Tbun8OvFhBgMYAIL0mzP zSmQS>M6VrSCwF%t-X=DvYb8kmN?VgP8@EA*{#C=q{{*V6PqPUh!XHs%*(85dlZBp5 zv4gCBUTj_{Qq5b&E`9$rD7?*FlK;#Fo~`-Z^#-u?pYoyaVDDn zr5Uqqm8Wj4K`|FAzj|be{kxTSd>~Bfpz?{|TPXT4<)9vfCy!StT7M%oxyPxLpN)f( z_0k=cgAm-MayxnmMjDV*oO@*8ZdKxM4v4x%mF$y+UeKh<@c14%o>DE!n2B({QY}l9 z6S>S*6>?3uE=g7D2J(UnRXYWwkYTv*dC>7+JhDn*Cn0c z^fHsw!5K_O)xB2e;N7n3{|5R7`EoYvzJs-5IQ>m95NF9v%3(oh9XI_cbW8H%LcT8| z8tuZxHVh!d7%u;O7?IMCE3jCPZhn?4Iv3vR^?_#ic$d$S_~c$(X?Cj>HSe zeqR4t2fyrL0cKwnzi}gavVX2*5Nty7Z}MAX3V@QcwP5| zlO(}kTMXS?C4<_<=plq`z-s%$LT2`1sPMM1aMxa7jF2+M2-VA>o|12R*~_PyAH4J!>nNtQ2~*@TPx@ zq!Vo-J)Q~AK1ThMq?R2)g`^Cq*&=u?B0$a8oI@+JRokzCPr_`}lMDZfe0$WV1`1Gp|&AV0urYOUXlHlOF#-4C;Og?#7tWWxpB24PwFq95+g3#sUF|Oh;W36Z+o3gX&&5hN$UbJ4Sox+i1gjDcKA(!<-xj}+ zy@7%lFLv$MVh%E5*D#`<@l-sY@j2wUFMj(6G4|s9JVa}!H)BY<_)8rmb&c0p>@5J>K-`GPr%S$9g)890r|`Ksndb1^4Wv37UCPV6hvUJLB%SGpD-K|kwq%OLq&gYNZf2s7Zht~_Nka{f+N7dQuG z&DR|ds6qHY>YDf5B^vv+t~0rni1}T2v+W+y#PiEg{yCCE(dfpPx_wg`zYV;oZtROV RH=%LE>S^-EUyAz`{|9U>SLpx% diff --git a/app/translations/qm/es_MX.qm b/app/translations/qm/es_MX.qm index 828bc498911aa70d36073653ae4ac075bc895b6c..69417e17ee0558b95e2408acf32f2af1052b8a30 100644 GIT binary patch delta 3752 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 K)s>B&;(r5Mu}Ay> delta 3043 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 diff --git a/app/translations/qm/ru_RU.qm b/app/translations/qm/ru_RU.qm index 56a683218ca18a184fe01112451665a9559b9070..dd35ad6a95863d65b1b38df085bd18902f3bdd3d 100644 GIT binary patch delta 3665 zcmb7GXINC%7F{!Q@65e3cLoIuYunSC{2-FS)Q$8Q)n`p$+mtc;z0A)#qm$Zg8F<_oK0aaguc}>xB z)nMLD2SP4^wOLQkYrqa&1-Rye9a9FZa0EMlLVAG<2t}#aJ ze+BGZinC&?5k(&CDq?E47Hml)R4CZo@egW7ipdhKbd{HwD{;49bsXc0&!GLM11lzB zd?tz1cYqOBy@8KIHc)y}Y?0U~bMoQiQUt7S6|JN?>69VjNU7FPb_XHN6vXbl5%c#V zSoikOy7+U(26w53#$ z(s0apz70s_5ofU!@aTgaKWo5eBbJ}50+u(RIHMT7koF@=oa%r@N3eY>iIz4UWudhs z)-R~YS_iEEQ+y+}ivJnMgaBZEH5zA`0RH7TmrUt{>T#j_H6U{_ZgKRz&qO0uH%9Rm{X;=M^0(e#km983aq){=qu9s#pLC4-{c@quWNkt#)!vM1jG zDpN_r1$RKYL2`0W4lR$9oEvNfcos+=d_4q+5hedVMCxUok-Sdo2`uR(dAFWOM~{-U z_5KssI$A363I@`TON9@Yh`zbBd)+SbBrkQ)e+vxdr5+*VBy%sR=OR+4Hd^YNG8n!n z?kxpd8mzX`F=DoSI4Me5|GOkT-)z+yrM zQ}is7=;@deZ>q98XT;UcVgcLVu%nJ?7+*$W>6jZ|p9boGU~cYO0uq~wy;>ISHY42M*GnS7fUg=h> z-FL@z5?~M(SAq$E20LfeqM14q4fW4RWJ?((h!a zSW;o*HnEXjwAThNHg4@va*!E2SK$eC*=fXzx9sYQ540|rt++@|s@%fvKleMZxsW|H zj^bPAu#L+f0lT`e&10z{Ho34DE@!|2<+<#|HX>JQ!QS0_h8lAgdw)`UB9XnHNEUTz zVqax4KxC%)QLgLxWwBhkqz@3VUH;j0dYm;$-uqV>@hO%MA9bE;(7qV{+MrQ5`Dp4SrrM@Mebp;sjBH7@G>7;1+`F1phKVA-!+;(0Inypo&!BUxeRH{84? zZ_*-7dj)lP=lQl@{A6lyjA`$7_0R2di{EM1>RQi!Dm6=^hK^pj!iJeB~?MG^w=V zY_Y4##y;hDrDs+;&Fs_4X)`LQJZqF+6mBErl;LfI=tN5~;+{$|mR`?kQbzkyvPvgq zbUEqMCB=xgZ;eudZc(TbPgDK9lT}I1R2YvYBUVpR z<+P9uhaFXIFKVRy3aVYb%Bbb9sCM5bCiXJb?mr33eZ(dTv+2F+PV5re-&EDT7x{FO zS*f1)CpU`&RL`H91N+wsvOFT<7$tPs`Z=A*KM9s^mjX4{1qY9wz@9MCO0AtL9uwRz zwE{z`jp%*Ih)WxUfXNirCfA5Z-V)OOZI259Eh~W>XCXL{?k|(y7_mw#gd8HdGm?db z3}(;fId*@`Q(xvIvW8q%-Nh+P{c+4)a$BmPzQWJR%O! z^j989R`19WiQgPCS!1C|>_S%{U-gd-WYg-GVu8lW(58NOoBUH#s$uMsfZ{Zb&3>wq zd%4D5K|YvyL1Vv$2CsUcX52GV@`y)w-L+lzD)`AxHIu8ib=sL9)Ng=WTH zP4N{=YKC)~&9>2W?wr+Zj?O3j$~514l5kdSn(G(0(Tzf>`QaX&_4YFu&248&G(@kt zH)b#$iZeB>iPHhe*CsG0<+wE_yy;1rT5m)@6RmyX9FvF~vcr;VCUb5Q-;@%QyeZjq z05qFaju=gXZZz39oNntI>cs++?$V=k#FqO0wYN;HgC;pMwu}=qit%LJ>CXvzW)L%! zKD#m=%wT#llo>+bk0l%mJ;u^+5JwFHx+bCX*s($S!0_2AiSbFX`hf8CXz^aCWo=tz zu=(JizZJJHW5$eyo!F9TXJ+#$Vk$+{_Z`2$u2w&9s@EV(#=3)+FVUJnM4gG|U_y7o zp`S>p$HzxS>%$Wh_2KiP)5L>cb(J`Ymrr(a8}PrEX(xRVLQC8C6bidfi?xAq$(j0y zVhH&ZuTw|73z^;?v`klf;9kw6!l!OpyN<8zv)F delta 3055 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 diff --git a/app/translations/qm/zh_CN.qm b/app/translations/qm/zh_CN.qm index c8ab41627ef1704558fb489c7389e01b88d59a5f..849c849e370f27d5796060a7e98757f93c64620a 100644 GIT binary patch delta 3445 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 DxsU75 delta 3028 zcmXX|3s_X;7F{!Q&Y77rXJ&jt_!yE%10N)yhA1k82#TnHfDp(_9wI1j5G3EIY0?p; z@{NeuLjxbTQY;k#Ej80ynrTQcOhfIeT`jxI=JI`fYi7>*_rLdAYw!Qxx4hMV+(7+43q(g|^9AipoRW572M=QIIH8ao!ILd;76tZ{a<-Gf-j zIPt-DO!*n&8YbMA&uf|iIq8J`L*Y?1N8_MPSgWqo__-(CLeR#Oc>4Db=E;~;{F_<)>%`cj?+3;^h0zTBlNAbW71GWpLvssZbZzP zPl5R_*|D%4v(mWsg;SVyYXp#0g;>+`z~pMg&UwnHBjT2jn4(m~Ej`F}T}ZgS6$ssc z^gc_0!8uqSHURMK!iv_tKx$!L2m%RbZ@m9OEwhI3z zIHJq|!i{L2YXwHdp*4s5`W(iYz88V%D{#fY=bnvr%=5st@Gzjb5uG=<@5Cx}9j6l} zoyT8Rx~0fNGw{P~pywHlSNo4ZuubEg@)V0TQ$!tkoUWPGkk9x|nu67@LWc$I>gzg( zkV$Jbts|U)p?x(SM@KPkkmk1r@)qf-d64Y_L>n}ZHZbkLG|gkzKY_XDwVHrPAnadS z<;gi<##`FH2X->&Xt!s0P`Z5W?p_jL+^Bswok+jiD4ldy zByDf$EcZy)ykB*`EtDtdfiAdb6x3xxchAyGy6~+%frWZqrXc|6QL0-phYXZY*6sT| z1xRVq?LWq~URk>R-%+Z_617DbG@w>@$7KSYyGM6lmV3F zi)o(o!uP*41AeQ8pPTtSeT5w}T!kkymvc@`6}3x-05QWwUF(fu#F(X+N zp0;COjcB{TD#8YfZeKP5j-KL>b8WyBKhdv^E>cHGPMUFQnB-6q|DG7(OGSGJh*ABh zT+mK2Ie>+gWsB+SKO#T%Vxit2Fn8K9Z-w|;{S$Wl&tm;q8Y5p8_qG0qsk|*V1Zf!O zoY=hLM<8dE*fx;{&-he4bG`t`-6WoU%v9#@7q7oh1BPA^Z%hqGPn7KxZ)8ORu3NYqT zrGpnTSyz#CsKXTj78=m0JF;GS;7HCh zkLz{E{{TiW*GuoYP|FDuKukb77`k+5C6l)G7jq_N5%ssR(-6; zC04ykKRb3b)48tCh|vPWTlATR102*>^d*ByXV`uHI+R*|w^f8#jC3MkNbeK~={ z%VcmUy2!`94UShyO7e4t7ZOF1US{yTM{zUWF!*1}BFRC9sSWp;^+-d?=|I2`V@T~* z3e4JQ$T}Us@2-Y<-_k7ER}IB2!Q^I{Vd-XnioMvd@^L4}#5;x!WmWJ+alB#A^b3GT zh+%KX4`kcXu)k?JNxfnCICnV5joxtlF^%f|rJ*I6ZIjex_2G z_0h(<{w#iyzp=iefr@$>-w&U`&D+!>+2)eE#n{v3#-dR-F-0J~ciH5$TUK z^{{LUnb0CTc(U^7M{=KSTs@#w?*D+V&8w9?8YoTbSlN4LKHz@cjw9Oam>(~DU!l+E zPLq8txh(B~>TDY5KIJRfzl^Uxe^-u6sHY;4@+(zaiISZ7*qi6oemmwLS945*j6QPe zWNx1KvAWIVAm_EqX<-LBwVl;tj5YJ9eB#6bvf3%1v~+N)ME)P|$=Aj&!yOzLs5fceVFP97o5UtyV_vlkCjlcKBS*3Pdg zy|+x~AzGsh9`8bl)~Ft4hgqpvir=|=SCiApvrZX_a9A2m40Mn`o zmSOJYznQl$r`=2bZT@IG_0irke?&0?;(b?k6p*oWqC59RXyxk^1|ajpn8Ke|dU z6iF7rEt~Tvz%pPYz=OXWKk*x=JG8!z;ujY}>b$9Rpk*Ia({^0xLna}6+cSba(gcn!K}Oey44`v*rWgfBJK3umAu6 diff --git a/app/translations/ts/de_DE.ts b/app/translations/ts/de_DE.ts index 5af0c646..f7ec2967 100644 --- a/app/translations/ts/de_DE.ts +++ b/app/translations/ts/de_DE.ts @@ -136,12 +136,12 @@ CSV-Exportdatei nicht gefunden! - + CSV File Error CSV-Dateifehler - + Cannot open CSV file for writing! CSV-Datei kann nicht zum Schreiben geöffnet werden! @@ -1073,228 +1073,228 @@ Verwende die Schaltflächen in der Symbolleiste oben, um einen Datensatz zu dies JSON::ProjectModel - + New Project Neues Projekt - + Do you want to save your changes? Möchten Sie Ihre Änderungen speichern? - + You have unsaved modifications in this project! Sie haben ungespeicherte Änderungen in diesem Projekt! - + Project error Projektfehler - + Project title cannot be empty! Der Projekttitel darf nicht leer sein! - + Save JSON project JSON-Projekt speichern - + File open error Dateiöffnungsfehler - - + + Untitled Project Unbenanntes Projekt - + Select JSON file JSON-Datei auswählen - + Do you want to delete group "%1"? Möchten Sie die Gruppe "%1" löschen? - - - + + + This action cannot be undone. Do you wish to proceed? Diese Aktion kann nicht rückgängig gemacht werden. Möchten Sie fortfahren? - + Do you want to delete action "%1"? Möchten Sie die Aktion "%1" löschen? - + Do you want to delete dataset "%1"? Möchten Sie den Datensatz "%1" löschen? - - - + + + %1 (Copy) %1 (Kopie) - + New Dataset Neuer Datensatz - + New Plot Neues Diagramm - + New FFT Plot Neues FFT-Diagramm - + New Bar Widget Neues Balken-Widget - + New Gauge Neue Anzeige - + New Compass Neuer Kompass - + New LED Indicator Neue LED-Anzeige - + New Action Neue Aktion - + Are you sure you want to change the group-level widget? Sind Sie sicher, dass Sie das Gruppen-Widget ändern möchten? - + Existing datasets for this group will be deleted Bestehende Datensätze für diese Gruppe werden gelöscht - - + + Accelerometer %1 Beschleunigungsmesser %1 - - + + Gyro %1 Gyroskop %1 - + Latitude Breitengrad - + Longitude Längengrad - + Altitude Höhe - + Frame Parser Function Frame-Parser-Funktion - - - - + + + + Title Titel - + Project name/description Projektname/Beschreibung - + Separator Sequence Trennzeichen-Sequenz - + String used to split items in a frame Zeichenfolge zur Trennung von Elementen in einem Frame - + Frame Start Delimeter Start-Trennzeichen des Frames - + String marking the start of a frame Zeichenfolge, die den Start eines Frames markiert - + Frame End Delimeter Ende-Trennzeichen des Frames - + String marking the end of a frame Zeichenfolge, die das Ende eines Frames markiert - + Data Conversion Method Datenkonvertierungsmethode - + Input data format for frame parser Eingabedatenformat für den Frame-Parser - + Thunderforest API Key Thunderforest API-Schlüssel - - - - - + + + + + None @@ -1303,294 +1303,304 @@ Verwende die Schaltflächen in der Symbolleiste oben, um einen Datensatz zu dies Erforderlich für das GPS-Karten-Widget - + Required for Thunderforest maps Erforderlich für Thunderforest-Karten - + MapTiler API Key MapTiler-API-Schlüssel - + Required for satellite maps Erforderlich für Satellitenkarten - + Untitled Group Unbenannte Gruppe - + Name or description of the group Name oder Beschreibung der Gruppe - - + + Widget Widget - + Group display widget (optional) Gruppenanzeige-Widget (optional) - + Untitled Action Unbenannte Aktion - + Name or description of the action Name oder Beschreibung der Aktion - + Icon Symbol - + Default Icon Standard-Symbol - + Icon to display in the dashboard Symbol, das im Dashboard angezeigt wird - + TX Data TX-Daten - + Command Befehl - + Data to transmit when the action is triggered. Daten, die gesendet werden, wenn die Aktion ausgelöst wird. - + EOL Sequence EOL-Sequenz - + End-of-line (EOL) sequence to use Zu verwendende End-of-Line (EOL)-Sequenz - + Untitled Dataset Unbenannter Datensatz - + Name or description of the dataset Name oder Beschreibung des Datensatzes - + Frame Index Frame-Index - + Position in the frame Position im Frame - + Measurement Unit Maßeinheit - + Volts, Amps, etc. Volt, Ampere, etc. - + Unit of measurement (optional) Maßeinheit (optional) - + Display widget (optional) Anzeigewidget (optional) - + Minimum Value Minimalwert - - + + Required for bar/gauge widgets Erforderlich für Balken-/Anzeigenwidgets - + Maximum Value Maximalwert - + Alarm Value Alarmwert - + Triggers alarm in bar widgets and LED panels Löst einen Alarm in Balken-Widgets und LED-Panels aus - + Oscilloscope Plot Oszilloskop-Diagramm - + Plot data in real-time Plotten von Echtzeitdaten - + FFT Plot FFT-Diagramm - + Plot frequency-domain data Frequenzbereichsdaten plotten - + FFT Window Size FFT-Fenstergröße - + Samples for FFT calculation Samples für die FFT-Berechnung - + + FFT Sampling Rate + FFT-Abtastrate + + + + Sampling rate (Hz) for FFT calculation + Abtastrate (Hz) für die FFT-Berechnung + + + Show in LED Panel Im LED-Panel anzeigen - + Quick status monitoring Schnelle Statusüberwachung - + LED High (On) Value LED-High (Ein)-Wert - + Threshold for LED on Schwellenwert für LED an - + Normal (UTF8) Normal (UTF8) - + Hexadecimal Hexadezimal - + Base64 Base64 - + Data Grid - + GPS Map GPS-Karte - + Gyroscope Gyroskop - + Multiple Plot - + Accelerometer Beschleunigungsmesser - + Bar Balken - + Gauge Anzeige - + Compass Kompass - + New Line (\n) Neue Zeile (\n) - + Carriage Return (\r) Wagenrücklauf (\r) - + NL + CR (\n\r) NL + CR (\n\r) - + CR + NL (\r\n) CR + NL (\r\n) - + No Nein - + Linear Plot Lineares Diagramm - + Logarithmic Plot Logarithmisches Diagramm @@ -3069,7 +3079,27 @@ Verwende die Schaltflächen in der Symbolleiste oben, um einen Datensatz zu dies UI::Dashboard - + + Show both X and Y axes + Beide Achsen (X und Y) anzeigen + + + + Show only X axis + Nur X-Achse anzeigen + + + + Show only Y axis + Nur Y-Achse anzeigen + + + + Hide all axes + Alle Achsen ausblenden + + + Status Panel Statusanzeige @@ -3113,95 +3143,100 @@ Verwende die Schaltflächen in der Symbolleiste oben, um einen Datensatz zu dies ViewOptions - + Widget Setup Widget-Einstellungen - + Visualization Options Visualisierungsoptionen - + Points: Punkte: - + Decimal places: Dezimalstellen: - + Columns: Spalten: - + Data Grids Datengitter - + Multiple Data Plots Mehrere Datenplots - + LED Panels LED-Anzeigen - + FFT Plots FFT-Diagramme - + Data Plots Datendiagramme - + Bars Balken - + Gauges Anzeigen - + Compasses Kompasse - + Gyroscopes Gyroskope - + Accelerometers Beschleunigungsmesser - + GPS GPS - + Clear Dashboard Data Dashboard-Daten löschen - + Display Console Window Konsolenfenster anzeigen + + + Adjust Plot Scales & Positions + Plotskalen & Positionen anpassen + WidgetGrid @@ -3214,12 +3249,12 @@ Verwende die Schaltflächen in der Symbolleiste oben, um einen Datensatz zu dies Widgets::FFTPlot - + Frequency (Hz) Frequenz (Hz) - + Magnitude (dB) Magnitude (dB) diff --git a/app/translations/ts/en_US.ts b/app/translations/ts/en_US.ts index c7d351b5..517f4abc 100644 --- a/app/translations/ts/en_US.ts +++ b/app/translations/ts/en_US.ts @@ -136,12 +136,12 @@ - + CSV File Error - + Cannot open CSV file for writing! @@ -1017,520 +1017,530 @@ Use the toolbar buttons above to add a dataset to this group. JSON::ProjectModel - + New Project - + Do you want to save your changes? - + You have unsaved modifications in this project! - + Project error - + Project title cannot be empty! - + Save JSON project - + File open error - - + + Untitled Project - + Select JSON file - + Do you want to delete group "%1"? - - - + + + This action cannot be undone. Do you wish to proceed? - + Do you want to delete action "%1"? - + Do you want to delete dataset "%1"? - - - + + + %1 (Copy) - + New Dataset - + New Plot - + New FFT Plot - + New Bar Widget - + New Gauge - + New Compass - + New LED Indicator - + New Action - + Are you sure you want to change the group-level widget? - + Existing datasets for this group will be deleted - - + + Accelerometer %1 - - + + Gyro %1 - + Latitude - + Longitude - + Altitude - + Frame Parser Function - - - - + + + + Title - + Project name/description - + Separator Sequence - + String used to split items in a frame - + Frame Start Delimeter - + String marking the start of a frame - + Frame End Delimeter - + String marking the end of a frame - + Data Conversion Method - + Input data format for frame parser - + Thunderforest API Key - - - - - + + + + + None - + Required for Thunderforest maps - + MapTiler API Key - + Required for satellite maps - + Untitled Group - + Name or description of the group - - + + Widget - + Group display widget (optional) - + Untitled Action - + Name or description of the action - + Icon - + Default Icon - + Icon to display in the dashboard - + TX Data - + Command - + Data to transmit when the action is triggered. - + EOL Sequence - + End-of-line (EOL) sequence to use - + Untitled Dataset - + Name or description of the dataset - + Frame Index - + Position in the frame - + Measurement Unit - + Volts, Amps, etc. - + Unit of measurement (optional) - + Display widget (optional) - + Minimum Value - - + + Required for bar/gauge widgets - + Maximum Value - + Alarm Value - + Triggers alarm in bar widgets and LED panels - + Oscilloscope Plot - + Plot data in real-time - + FFT Plot - + Plot frequency-domain data - + FFT Window Size - + Samples for FFT calculation - - - Show in LED Panel - - - Quick status monitoring + FFT Sampling Rate - - LED High (On) Value + + Sampling rate (Hz) for FFT calculation + Show in LED Panel + + + + + Quick status monitoring + + + + + LED High (On) Value + + + + Threshold for LED on - + Normal (UTF8) - + Hexadecimal - + Base64 - + Data Grid - + GPS Map - + Gyroscope - + Multiple Plot - + Accelerometer - + Bar - + Gauge - + Compass - + New Line (\n) - + Carriage Return (\r) - + NL + CR (\n\r) - + CR + NL (\r\n) - + No - + Linear Plot - + Logarithmic Plot @@ -2511,7 +2521,27 @@ Use the toolbar buttons above to add a dataset to this group. UI::Dashboard - + + Show both X and Y axes + + + + + Show only X axis + + + + + Show only Y axis + + + + + Hide all axes + + + + Status Panel @@ -2555,95 +2585,100 @@ Use the toolbar buttons above to add a dataset to this group. ViewOptions - + Widget Setup - + Visualization Options - + Points: - + Decimal places: - + Columns: - + Data Grids - + Multiple Data Plots - + LED Panels - + FFT Plots - + Data Plots - + Bars - + Gauges - + Compasses - + Gyroscopes - + Accelerometers - + GPS - + Clear Dashboard Data - + Display Console Window + + + Adjust Plot Scales & Positions + + WidgetGrid @@ -2656,12 +2691,12 @@ Use the toolbar buttons above to add a dataset to this group. Widgets::FFTPlot - + Frequency (Hz) - + Magnitude (dB) diff --git a/app/translations/ts/es_MX.ts b/app/translations/ts/es_MX.ts index 826fb74d..45f207e9 100644 --- a/app/translations/ts/es_MX.ts +++ b/app/translations/ts/es_MX.ts @@ -136,12 +136,12 @@ ¡No se puede encontrar el archivo de exportación CSV! - + CSV File Error Error de archivo CSV - + Cannot open CSV file for writing! ¡No se puede abrir el archivo CSV para escribir! @@ -1073,228 +1073,228 @@ Usa los botones de la barra de herramientas de arriba para agregar un conjunto d JSON::ProjectModel - + New Project Nuevo Proyecto - + Do you want to save your changes? ¿Quieres guardar los cambios? - + You have unsaved modifications in this project! ¡Tienes modificaciones sin guardar en este proyecto! - + Project error Error del proyecto - + Project title cannot be empty! ¡El título del proyecto no puede estar vacío! - + Save JSON project Guardar proyecto JSON - + File open error Error al abrir el archivo - - + + Untitled Project Proyecto sin título - + Select JSON file Seleccionar archivo JSON - + Do you want to delete group "%1"? ¿Deseas eliminar el grupo "%1"? - - - + + + This action cannot be undone. Do you wish to proceed? Esta acción no se puede deshacer. ¿Deseas continuar? - + Do you want to delete action "%1"? ¿Quieres eliminar la acción «%1»? - + Do you want to delete dataset "%1"? ¿Deseas eliminar el conjunto de datos "%1"? - - - + + + %1 (Copy) %1 (Copia) - + New Dataset Nuevo Conjunto de Datos - + New Plot Nueva Gráfica - + New FFT Plot Nueva Gráfica FFT - + New Bar Widget Nuevo Widget de Barras - + New Gauge Nuevo Medidor - + New Compass Nueva Brújula - + New LED Indicator Nuevo Indicador LED - + New Action Nueva Acción - + Are you sure you want to change the group-level widget? ¿Estás seguro de que quieres cambiar el widget a nivel de grupo? - + Existing datasets for this group will be deleted Los conjuntos de datos existentes para este grupo serán eliminados - - + + Accelerometer %1 Acelerómetro %1 - - + + Gyro %1 Giro %1 - + Latitude Latitud - + Longitude Longitud - + Altitude Altitud - + Frame Parser Function Analizador de Tramas - - - - + + + + Title Título - + Project name/description Nombre/Descripción del proyecto - + Separator Sequence Secuencia Separadora - + String used to split items in a frame Cadena utilizada para dividir elementos en una trama - + Frame Start Delimeter Delimitador de Inicio de Trama - + String marking the start of a frame Cadena que marca el inicio de una trama - + Frame End Delimeter Delimitador de Fin de Trama - + String marking the end of a frame Cadena que marca el fin de una trama - + Data Conversion Method Método de Conversión de Datos - + Input data format for frame parser Formato de datos de entrada para el analizador de tramas - + Thunderforest API Key Clave API de Thunderforest - - - - - + + + + + None Ninguno @@ -1303,294 +1303,304 @@ Usa los botones de la barra de herramientas de arriba para agregar un conjunto d Requerido para el widget de mapa GPS - + Required for Thunderforest maps Requerido para mapas de Thunderforest - + MapTiler API Key Clave API de MapTiler - + Required for satellite maps Requerido para mapas satelitales - + Untitled Group Grupo Sin Título - + Name or description of the group Nombre o descripción del grupo - - + + Widget Widget - + Group display widget (optional) Widget de visualización de grupo (opcional) - + Untitled Action Acción sin título - + Name or description of the action Nombre o descripción de la acción - + Icon Icono - + Default Icon Icono Predeterminado - + Icon to display in the dashboard Icono para mostrar en el panel - + TX Data Datos TX - + Command Comando - + Data to transmit when the action is triggered. Datos a transmitir cuando se activa la acción. - + EOL Sequence Secuencia EOL - + End-of-line (EOL) sequence to use Secuencia de fin de línea (EOL) a utilizar - + Untitled Dataset Conjunto de Datos Sin Título - + Name or description of the dataset Nombre o descripción del conjunto de datos - + Frame Index Índice de Trama - + Position in the frame Posición en la trama - + Measurement Unit Unidad de Medida - + Volts, Amps, etc. Voltios, Amperios, etc. - + Unit of measurement (optional) Unidad de medida (opcional) - + Display widget (optional) Widget de visualización (opcional) - + Minimum Value Valor Mínimo - - + + Required for bar/gauge widgets Requerido para widgets de barras/medidores - + Maximum Value Valor Máximo - + Alarm Value Valor de Alarma - + Triggers alarm in bar widgets and LED panels Activa la alarma en widgets de barras y paneles LED - + Oscilloscope Plot Gráfico de Osciloscopio - + Plot data in real-time Graficar datos en tiempo real - + FFT Plot Gráfico FFT - + Plot frequency-domain data Graficar datos en el dominio de la frecuencia - + FFT Window Size Tamaño de Ventana FFT - + Samples for FFT calculation Muestras para el cálculo de FFT - + + FFT Sampling Rate + Tasa de muestreo FFT + + + + Sampling rate (Hz) for FFT calculation + Tasa de muestreo (Hz) para el cálculo de la FFT + + + Show in LED Panel Mostrar en el Panel LED - + Quick status monitoring Monitoreo rápido de estado - + LED High (On) Value Valor Alto (Encendido) del LED - + Threshold for LED on Umbral para encender el LED - + Normal (UTF8) Normal (UTF8) - + Hexadecimal Hexadecimal - + Base64 Base64 - + Data Grid Cuadrícula de Datos - + GPS Map Mapa GPS - + Gyroscope Giroscopio - + Multiple Plot - + Accelerometer Acelerómetro - + Bar Barra - + Gauge - + Compass Brújula - + New Line (\n) Línea Nueva (\n) - + Carriage Return (\r) Retorno de Carro (\r) - + NL + CR (\n\r) LN + RC (\n\r) - + CR + NL (\r\n) RC + LN (\r\n) - + No No - + Linear Plot Gráfico Lineal - + Logarithmic Plot Gráfico Logarítmico @@ -3069,7 +3079,27 @@ Usa los botones de la barra de herramientas de arriba para agregar un conjunto d UI::Dashboard - + + Show both X and Y axes + Mostrar ambos ejes X e Y + + + + Show only X axis + Mostrar solo el eje X + + + + Show only Y axis + Mostrar solo el eje Y + + + + Hide all axes + Ocultar todos los ejes + + + Status Panel Panel de estado @@ -3113,95 +3143,100 @@ Usa los botones de la barra de herramientas de arriba para agregar un conjunto d ViewOptions - + Widget Setup Configuración de Widgets - + Visualization Options Opciones de visualización - + Points: Puntos: - + Decimal places: Lugares decimales: - + Columns: Columnas: - + Data Grids Cuadrículas de Datos - + Multiple Data Plots Gráficas de Datos Múltiples - + LED Panels Paneles LED - + FFT Plots Gráficas FFT - + Data Plots Gráficas de Datos - + Bars Barras - + Gauges Medidores - + Compasses Brújulas - + Gyroscopes Giroscopios - + Accelerometers Acelerómetros - + GPS GPS - + Clear Dashboard Data Limpiar Tablero - + Display Console Window Mostrar Consola + + + Adjust Plot Scales & Positions + Ajustar escalas y posiciones + WidgetGrid @@ -3214,12 +3249,12 @@ Usa los botones de la barra de herramientas de arriba para agregar un conjunto d Widgets::FFTPlot - + Frequency (Hz) Frecuencia (Hz) - + Magnitude (dB) Magnitud (dB) diff --git a/app/translations/ts/fr_FR.ts b/app/translations/ts/fr_FR.ts index f2be73bc..3d0baf06 100644 --- a/app/translations/ts/fr_FR.ts +++ b/app/translations/ts/fr_FR.ts @@ -136,12 +136,12 @@ Impossible de trouver le fichier d'exportation CSV ! - + CSV File Error Erreur de fichier CSV - + Cannot open CSV file for writing! Impossible d'ouvrir le fichier CSV pour l'écriture ! @@ -1026,520 +1026,530 @@ Utilisez les boutons de la barre d'outils ci-dessus pour ajouter un ensembl JSON::ProjectModel - + New Project Nouveau projet - + Do you want to save your changes? Voulez-vous enregistrer vos modifications ? - + You have unsaved modifications in this project! Vous avez des modifications non enregistrées dans ce projet  ! - + Project error Erreur de projet - + Project title cannot be empty! Le titre du projet ne peut pas être vide  ! - + Save JSON project Enregistrer le projet JSON - + File open error Erreur d'ouverture de fichier - - + + Untitled Project Projet sans titre - + Select JSON file Sélectionner un fichier JSON - + Do you want to delete group "%1"? Voulez-vous supprimer le groupe "%1" ? - - - + + + This action cannot be undone. Do you wish to proceed? Cette action est irréversible. Voulez-vous continuer ? - + Do you want to delete action "%1"? Voulez-vous supprimer l'action "%1" ? - + Do you want to delete dataset "%1"? Voulez-vous supprimer le jeu de données "%1" ? - - - + + + %1 (Copy) %1 (Copie) - + New Dataset Nouveau jeu de données - + New Plot Nouvelle courbe - + New FFT Plot Nouvelle courbe FFT - + New Bar Widget Nouveau widget de barre - + New Gauge Nouveau jauge - + New Compass Nouveau compas - + New LED Indicator Nouveau témoin LED - + New Action Nouvelle action - + Are you sure you want to change the group-level widget? Êtes-vous sûr de vouloir changer le widget au niveau du groupe ? - + Existing datasets for this group will be deleted Les jeux de données existants pour ce groupe seront supprimés - - + + Accelerometer %1 Accéléromètre %1 - - + + Gyro %1 Gyroscope %1 - + Latitude Latitude - + Longitude Longitude - + Altitude Altitude - + Frame Parser Function Fonction du parseur de trame - - - - + + + + Title Titre - + Project name/description Nom/description du projet - + Separator Sequence Séquence de séparation - + String used to split items in a frame Chaîne utilisée pour séparer les éléments dans une trame - + Frame Start Delimeter Délimiteur de début de trame - + String marking the start of a frame Chaîne marquant le début d'une trame - + Frame End Delimeter Délimiteur de fin de trame - + String marking the end of a frame Chaîne marquant la fin d'une trame - + Data Conversion Method Méthode de conversion des données - + Input data format for frame parser Format des données d'entrée pour le parseur de trame - + Thunderforest API Key Clé API Thunderforest - - - - - + + + + + None Aucune - + Required for Thunderforest maps Nécessaire pour les cartes Thunderforest - + MapTiler API Key Clé API MapTiler - + Required for satellite maps Nécessaire pour les cartes satellites - + Untitled Group Groupe sans titre - + Name or description of the group Nom ou description du groupe - - + + Widget Widget - + Group display widget (optional) Widget d'affichage du groupe (optionnel) - + Untitled Action Action sans titre - + Name or description of the action Nom ou description de l'action - + Icon Icône - + Default Icon Icône par défaut - + Icon to display in the dashboard Icône à afficher dans le tableau de bord - + TX Data Données TX - + Command Commande - + Data to transmit when the action is triggered. Données à transmettre lorsque l'action est déclenchée. - + EOL Sequence Séquence EOL - + End-of-line (EOL) sequence to use Séquence de fin de ligne (EOL) à utiliser - + Untitled Dataset Jeu de données sans titre - + Name or description of the dataset Nom ou description du jeu de données - + Frame Index Indice de trame - + Position in the frame Position dans la trame - + Measurement Unit Unité de mesure - + Volts, Amps, etc. Volts, Ampères, etc. - + Unit of measurement (optional) Unité de mesure (optionnel) - + Display widget (optional) Widget d'affichage (optionnel) - + Minimum Value Valeur minimale - - + + Required for bar/gauge widgets Requis pour les widgets barre/jauge - + Maximum Value Valeur maximale - + Alarm Value Valeur d'alarme - + Triggers alarm in bar widgets and LED panels Déclenche une alarme dans les widgets barre et panneaux LED - + Oscilloscope Plot Tracé d'oscilloscope - + Plot data in real-time Tracer des données en temps réel - + FFT Plot Tracé FFT - + Plot frequency-domain data Tracer les données en domaine fréquentiel - + FFT Window Size Taille de la fenêtre FFT - + Samples for FFT calculation Échantillons pour le calcul FFT - + + FFT Sampling Rate + Taux d’échantillonnage FFT + + + + Sampling rate (Hz) for FFT calculation + Taux d’échantillonnage (Hz) pour le calcul FFT + + + Show in LED Panel Afficher sur le panneau LED - + Quick status monitoring Surveillance rapide de l'état - + LED High (On) Value Valeur haute (allumée) du LED - + Threshold for LED on Seuil pour LED allumée - + Normal (UTF8) Normal (UTF8) - + Hexadecimal Hexadécimal - + Base64 Base64 - + Data Grid Grille de données - + GPS Map Carte GPS - + Gyroscope Gyroscope - + Multiple Plot Tracé multiple - + Accelerometer Accéléromètre - + Bar Barre - + Gauge Jauge - + Compass Boussole - + New Line (\n) Nouvelle ligne (\n) - + Carriage Return (\r) Retour chariot (\r) - + NL + CR (\n\r) NL + RC (\n\r) - + CR + NL (\r\n) RC + NL (\r\n) - + No Non - + Linear Plot Tracé linéaire - + Logarithmic Plot Tracé logarithmique @@ -2532,7 +2542,27 @@ Utilisez les boutons de la barre d'outils ci-dessus pour ajouter un ensembl UI::Dashboard - + + Show both X and Y axes + Afficher les axes X et Y + + + + Show only X axis + Afficher uniquement l’axe X + + + + Show only Y axis + Afficher uniquement l’axe Y + + + + Hide all axes + Masquer tous les axes + + + Status Panel Panneau de Statut @@ -2576,95 +2606,100 @@ Utilisez les boutons de la barre d'outils ci-dessus pour ajouter un ensembl ViewOptions - + Widget Setup Configuration des Widgets - + Visualization Options Options de Visualisation - + Points: Points : - + Decimal places: Décimales : - + Columns: Colonnes : - + Data Grids Grilles de Données - + Multiple Data Plots Graphiques Multiples - + LED Panels Panneaux LED - + FFT Plots Graphiques FFT - + Data Plots Graphiques de Données - + Bars Barres - + Gauges Jauges - + Compasses Boussoles - + Gyroscopes Gyroscopes - + Accelerometers Accéléromètres - + GPS GPS - + Clear Dashboard Data Effacer les Données du Tableau de Bord - + Display Console Window Afficher la Fenêtre de Console + + + Adjust Plot Scales & Positions + Ajuster échelles et positions + WidgetGrid @@ -2677,12 +2712,12 @@ Utilisez les boutons de la barre d'outils ci-dessus pour ajouter un ensembl Widgets::FFTPlot - + Frequency (Hz) Fréquence (Hz) - + Magnitude (dB) Magnitude (dB) diff --git a/app/translations/ts/ru_RU.ts b/app/translations/ts/ru_RU.ts index fed88ca0..caa14178 100644 --- a/app/translations/ts/ru_RU.ts +++ b/app/translations/ts/ru_RU.ts @@ -136,12 +136,12 @@ Не удалось найти файл экспорта CSV! - + CSV File Error Ошибка файла CSV - + Cannot open CSV file for writing! Не удалось открыть файл CSV для записи! @@ -1077,228 +1077,228 @@ Use the toolbar buttons above to add a dataset to this group. JSON::ProjectModel - + New Project Новый проект - + Do you want to save your changes? Вы хотите сохранить изменения? - + You have unsaved modifications in this project! У вас есть несохраненные изменения в этом проекте! - + Project error Ошибка проекта - + Project title cannot be empty! Название проекта не может быть пустым! - + Save JSON project Сохранить проект JSON - + File open error Ошибка открытия файла - - + + Untitled Project Безымянный проект - + Select JSON file Выберите файл JSON - + Do you want to delete group "%1"? Вы хотите удалить группу "%1"? - - - + + + This action cannot be undone. Do you wish to proceed? Это действие не может быть отменено. Вы хотите продолжить? - + Do you want to delete action "%1"? Вы хотите удалить действие «%1»? - + Do you want to delete dataset "%1"? Вы хотите удалить набор данных "%1"? - - - + + + %1 (Copy) %1 (Копия) - + New Dataset Новый набор данных - + New Plot Новый график - + New FFT Plot Новый график FFT - + New Bar Widget Новый виджет полосы - + New Gauge Новый измерительный прибор - + New Compass Новый компас - + New LED Indicator Новый LED индикатор - + New Action Новое действие - + Are you sure you want to change the group-level widget? Вы уверены, что хотите изменить виджет группы? - + Existing datasets for this group will be deleted Существующие наборы данных для этой группы будут удалены - - + + Accelerometer %1 Акселерометр %1 - - + + Gyro %1 Гироскоп %1 - + Latitude Широта - + Longitude Долгота - + Altitude Высота - + Frame Parser Function Функция разбора фреймов - - - - + + + + Title Заголовок - + Project name/description Название/описание проекта - + Separator Sequence Последовательность разделителей - + String used to split items in a frame Строка, используемая для разделения элементов в кадре - + Frame Start Delimeter Разделитель начала фрейма - + String marking the start of a frame Строка, обозначающая начало фрейма - + Frame End Delimeter Разделитель конца фрейма - + String marking the end of a frame Строка, обозначающая конец фрейма - + Data Conversion Method Метод преобразования данных - + Input data format for frame parser Формат входных данных для разбора фреймов - + Thunderforest API Key API-ключ Thunderforest - - - - - + + + + + None Нет @@ -1307,294 +1307,304 @@ Use the toolbar buttons above to add a dataset to this group. Требуется для виджета GPS карты - + Required for Thunderforest maps Требуется для карт Thunderforest - + MapTiler API Key API-ключ MapTiler - + Required for satellite maps Требуется для спутниковых карт - + Untitled Group Безымянная группа - + Name or description of the group Название или описание группы - - + + Widget Виджет - + Group display widget (optional) Виджет отображения группы (опционально) - + Untitled Action Безымянное действие - + Name or description of the action Имя или описание действия - + Icon Иконка - + Default Icon Иконка по умолчанию - + Icon to display in the dashboard Иконка для отображения на панели управления - + TX Data Данные для передачи - + Command Команда - + Data to transmit when the action is triggered. Данные для передачи при выполнении действия. - + EOL Sequence Последовательность EOL - + End-of-line (EOL) sequence to use Последовательность конца строки (EOL) для использования - + Untitled Dataset Безымянный набор данных - + Name or description of the dataset Название или описание набора данных - + Frame Index Индекс фрейма - + Position in the frame Позиция в фрейме - + Measurement Unit Единица измерения - + Volts, Amps, etc. Вольты, Амперы и т.д. - + Unit of measurement (optional) Единица измерения (опционально) - + Display widget (optional) Виджет отображения (опционально) - + Minimum Value Минимальное значение - - + + Required for bar/gauge widgets Требуется для виджетов шкал/графиков - + Maximum Value Максимальное значение - + Alarm Value Значение тревоги - + Triggers alarm in bar widgets and LED panels Запускает тревогу в виджетах шкал и светодиодных панелях - + Oscilloscope Plot График осциллографа - + Plot data in real-time Построение данных в реальном времени - + FFT Plot - + Plot frequency-domain data Построение данных в частотной области - + FFT Window Size Размер окна FFT - + Samples for FFT calculation Образцы для расчета FFT - + + FFT Sampling Rate + Частота дискретизации FFT + + + + Sampling rate (Hz) for FFT calculation + Частота дискретизации (Гц) для расчета FFT + + + Show in LED Panel Отображать на светодиодной панели - + Quick status monitoring Быстрый мониторинг состояния - + LED High (On) Value Высокое значение LED (включено) - + Threshold for LED on Порог включения LED - + Normal (UTF8) Обычный (UTF8) - + Hexadecimal Шестнадцатеричный - + Base64 Base64 - + Data Grid Таблица данных - + GPS Map GPS карта - + Gyroscope Гироскоп - + Multiple Plot Множественный график - + Accelerometer Акселерометр - + Bar Гистограмма - + Gauge - + Compass Компас - + New Line (\n) Новая строка (\n) - + Carriage Return (\r) Возврат каретки (\r) - + NL + CR (\n\r) НС + ВК (\n\r) - + CR + NL (\r\n) ВК + НС (\r\n) - + No Нет - + Linear Plot Линейный график - + Logarithmic Plot Логарифмический график @@ -3073,7 +3083,27 @@ Use the toolbar buttons above to add a dataset to this group. UI::Dashboard - + + Show both X and Y axes + Показать обе оси (X и Y) + + + + Show only X axis + Показать только ось X + + + + Show only Y axis + Показать только ось Y + + + + Hide all axes + Скрыть все оси + + + Status Panel Панель состояния @@ -3117,95 +3147,100 @@ Use the toolbar buttons above to add a dataset to this group. ViewOptions - + Widget Setup Настройка виджета - + Visualization Options Параметры визуализации - + Points: Точки: - + Decimal places: Десятичные знаки: - + Columns: Колонки: - + Data Grids Таблицы данных - + Multiple Data Plots Несколько графиков данных - + LED Panels Светодиодные панели - + FFT Plots Графики FFT - + Data Plots Графики данных - + Bars Столбцы - + Gauges Шкалы - + Compasses Компас - + Gyroscopes Гироскопы - + Accelerometers Акселерометры - + GPS GPS - + Clear Dashboard Data Очистить данные панели - + Display Console Window Показать окно консоли + + + Adjust Plot Scales & Positions + Настроить масштабы и положения + WidgetGrid @@ -3218,12 +3253,12 @@ Use the toolbar buttons above to add a dataset to this group. Widgets::FFTPlot - + Frequency (Hz) Частота (Гц) - + Magnitude (dB) Величина (дБ) diff --git a/app/translations/ts/zh_CN.ts b/app/translations/ts/zh_CN.ts index 4a2f4f7c..30c670cc 100644 --- a/app/translations/ts/zh_CN.ts +++ b/app/translations/ts/zh_CN.ts @@ -136,12 +136,12 @@ 找不到 CSV 导出文件! - + CSV File Error CSV 文件错误 - + Cannot open CSV file for writing! 无法打开 CSV 文件进行写入! @@ -1073,228 +1073,228 @@ Use the toolbar buttons above to add a dataset to this group. JSON::ProjectModel - + New Project 新项目 - + Do you want to save your changes? 是否保存更改? - + You have unsaved modifications in this project! 您在此项目中有未保存的修改! - + Project error 项目错误 - + Project title cannot be empty! 项目标题不能为空! - + Save JSON project 保存 JSON 项目 - + File open error 文件打开错误 - - + + Untitled Project 未命名项目 - + Select JSON file 选择 JSON 文件 - + Do you want to delete group "%1"? 您要删除组 "%1" 吗? - - - + + + This action cannot be undone. Do you wish to proceed? 此操作无法撤销。是否继续? - + Do you want to delete action "%1"? 您要删除操作 "%1" 吗? - + Do you want to delete dataset "%1"? 您要删除数据集 "%1" 吗? - - - + + + %1 (Copy) %1 (副本) - + New Dataset 新数据集 - + New Plot 新图表 - + New FFT Plot 新 FFT 图表 - + New Bar Widget 新柱状图组件 - + New Gauge 新仪表 - + New Compass 新指南针 - + New LED Indicator 新 LED 指示器 - + New Action 新操作 - + Are you sure you want to change the group-level widget? 您确定要更改组级组件吗? - + Existing datasets for this group will be deleted 该组的现有数据集将被删除 - - + + Accelerometer %1 加速度计 %1 - - + + Gyro %1 陀螺仪 %1 - + Latitude 纬度 - + Longitude 经度 - + Altitude 高度 - + Frame Parser Function 帧解析函数 - - - - + + + + Title 标题 - + Project name/description 项目名称/描述 - + Separator Sequence 分隔符序列 - + String used to split items in a frame 用于在帧中拆分项目的字符串 - + Frame Start Delimeter 帧起始分隔符 - + String marking the start of a frame 标记帧起始的字符串 - + Frame End Delimeter 帧结束分隔符 - + String marking the end of a frame 标记帧结束的字符串 - + Data Conversion Method 数据转换方法 - + Input data format for frame parser 帧解析器的输入数据格式 - + Thunderforest API Key Thunderforest API 密钥 - - - - - + + + + + None @@ -1303,294 +1303,304 @@ Use the toolbar buttons above to add a dataset to this group. GPS 地图组件所需 - + Required for Thunderforest maps Thunderforest 地图所需 - + MapTiler API Key MapTiler API 密钥 - + Required for satellite maps 卫星地图所需 - + Untitled Group 未命名组 - + Name or description of the group 组名称或描述 - - + + Widget 组件 - + Group display widget (optional) 组显示组件(可选) - + Untitled Action 未命名操作 - + Name or description of the action 操作名称或描述 - + Icon 图标 - + Default Icon 默认图标 - + Icon to display in the dashboard 仪表板中显示的图标 - + TX Data 发送数据 - + Command 命令 - + Data to transmit when the action is triggered. 操作触发时传输的数据。 - + EOL Sequence 行尾序列 - + End-of-line (EOL) sequence to use 要使用的行尾(EOL)序列 - + Untitled Dataset 未命名数据集 - + Name or description of the dataset 数据集名称或描述 - + Frame Index 帧索引 - + Position in the frame 在帧中的位置 - + Measurement Unit 测量单位 - + Volts, Amps, etc. 伏特,安培等。 - + Unit of measurement (optional) 测量单位(可选) - + Display widget (optional) 显示组件(可选) - + Minimum Value 最小值 - - + + Required for bar/gauge widgets 柱状图/仪表组件所需 - + Maximum Value 最大值 - + Alarm Value 报警值 - + Triggers alarm in bar widgets and LED panels 在柱状图组件和 LED 面板中触发警报 - + Oscilloscope Plot 示波器图 - + Plot data in real-time 实时绘制数据 - + FFT Plot - + Plot frequency-domain data 绘制频域数据 - + FFT Window Size FFT 窗口大小 - + Samples for FFT calculation FFT 计算的样本 - + + FFT Sampling Rate + FFT采样率 + + + + Sampling rate (Hz) for FFT calculation + 用于FFT计算的采样率(Hz) + + + Show in LED Panel 在 LED 面板中显示 - + Quick status monitoring 快速状态监控 - + LED High (On) Value LED 高电平(开)值 - + Threshold for LED on LED 开启阈值 - + Normal (UTF8) 普通(UTF8) - + Hexadecimal 十六进制 - + Base64 Base64 - + Data Grid 数据网格 - + GPS Map - + Gyroscope 陀螺仪 - + Multiple Plot - + Accelerometer 加速度计 - + Bar 条形图 - + Gauge 仪表 - + Compass 指南针 - + New Line (\n) 换行符(\n) - + Carriage Return (\r) 回车符(\r) - + NL + CR (\n\r) 换行符 + 回车符(\n\r) - + CR + NL (\r\n) 回车符 + 换行符(\r\n) - + No - + Linear Plot 线性图 - + Logarithmic Plot 对数图 @@ -3065,7 +3075,27 @@ Use the toolbar buttons above to add a dataset to this group. UI::Dashboard - + + Show both X and Y axes + 显示X轴和Y轴 + + + + Show only X axis + 仅显示X轴 + + + + Show only Y axis + 仅显示Y轴 + + + + Hide all axes + 隐藏所有坐标轴 + + + Status Panel 状态面板 @@ -3109,95 +3139,100 @@ Use the toolbar buttons above to add a dataset to this group. ViewOptions - + Widget Setup 小部件设置 - + Visualization Options 可视化选项 - + Points: 点数: - + Decimal places: 小数位数: - + Columns: 列数: - + Data Grids 数据网格 - + Multiple Data Plots 多数据绘图 - + LED Panels LED面板 - + FFT Plots FFT绘图 - + Data Plots 数据绘图 - + Bars 柱状图 - + Gauges 仪表盘 - + Compasses 指南针 - + Gyroscopes 陀螺仪 - + Accelerometers 加速度计 - + GPS GPS - + Clear Dashboard Data 清除仪表盘数据 - + Display Console Window 显示控制台窗口 + + + Adjust Plot Scales & Positions + 调整图表的比例和位置 + WidgetGrid @@ -3210,12 +3245,12 @@ Use the toolbar buttons above to add a dataset to this group. Widgets::FFTPlot - + Frequency (Hz) 频率(Hz) - + Magnitude (dB) 幅度(dB) diff --git a/examples/HexadecimalADC/HexadecimalADC.json b/examples/HexadecimalADC/HexadecimalADC.json index 84ceee0f..2cd5042b 100644 --- a/examples/HexadecimalADC/HexadecimalADC.json +++ b/examples/HexadecimalADC/HexadecimalADC.json @@ -12,6 +12,7 @@ "alarm": 0, "fft": true, "fftSamples": 1024, + "fftSamplingRate": 500, "graph": false, "index": 1, "led": false, @@ -28,6 +29,7 @@ "alarm": 0, "fft": true, "fftSamples": 1024, + "fftSamplingRate": 500, "graph": false, "index": 2, "led": false, @@ -44,6 +46,7 @@ "alarm": 0, "fft": true, "fftSamples": 1024, + "fftSamplingRate": 500, "graph": false, "index": 3, "led": false, @@ -60,6 +63,7 @@ "alarm": 0, "fft": true, "fftSamples": 1024, + "fftSamplingRate": 500, "graph": false, "index": 4, "led": false, @@ -76,6 +80,7 @@ "alarm": 0, "fft": true, "fftSamples": 1024, + "fftSamplingRate": 500, "graph": false, "index": 5, "led": false, @@ -92,6 +97,7 @@ "alarm": 0, "fft": true, "fftSamples": 1024, + "fftSamplingRate": 500, "graph": false, "index": 6, "led": false,