From a26a3523896a0e5d30d0ce4965a4457b65ae6bf9 Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Mon, 22 Mar 2021 00:11:43 -0700 Subject: [PATCH] Changed frequency parameters to (mostly) unsigned 64-bit ints. This makes all the rounding code very simple and removes many annoying lines of code designed to handle errors induced by using doubles for the frequency. --- commhandler.cpp | 7 +- rigcommander.cpp | 108 +++++++++++++--- rigcommander.h | 12 +- wfmain.cpp | 317 ++++++++++++++++++++++++++++++----------------- wfmain.h | 29 ++++- 5 files changed, 329 insertions(+), 144 deletions(-) diff --git a/commhandler.cpp b/commhandler.cpp index 8021c0d..082f21d 100644 --- a/commhandler.cpp +++ b/commhandler.cpp @@ -84,9 +84,10 @@ void commHandler::sendDataOut(const QByteArray &writeData) qint64 bytesWritten; bytesWritten = port->write(writeData); - qDebug(logSerial()) << "bytesWritten: " << bytesWritten << " length of byte array: " << writeData.length()\ - << " size of byte array: " << writeData.size()\ - << " Wrote all bytes? " << (bool) (bytesWritten == (qint64)writeData.size()); + // TODO: if(log.level == logLevelCrazy){... + //qDebug(logSerial()) << "bytesWritten: " << bytesWritten << " length of byte array: " << writeData.length()\ + // << " size of byte array: " << writeData.size()\ + // << " Wrote all bytes? " << (bool) (bytesWritten == (qint64)writeData.size()); #else port->write(writeData); diff --git a/rigcommander.cpp b/rigcommander.cpp index 3f4127e..91f6372 100644 --- a/rigcommander.cpp +++ b/rigcommander.cpp @@ -500,8 +500,9 @@ void rigCommander::getSpectrumMode() prepDataAndSend(specModePayload); } -void rigCommander::setFrequency(double freq) +void rigCommander::setFrequency(freqt freq) { + //QByteArray freqPayload = makeFreqPayload(freq); QByteArray freqPayload = makeFreqPayload(freq); QByteArray cmdPayload; @@ -512,6 +513,31 @@ void rigCommander::setFrequency(double freq) prepDataAndSend(cmdPayload); } +QByteArray rigCommander::makeFreqPayload(freqt freq) +{ + QByteArray result; + quint64 freqInt = freq.Hz; + + unsigned char a; + int numchars = 5; + for (int i = 0; i < numchars; i++) { + a = 0; + a |= (freqInt) % 10; + freqInt /= 10; + a |= ((freqInt) % 10)<<4; + + freqInt /= 10; + + result.append(a); + //printHex(result, false, true); + } + qDebug(logRig()) << __func__ << ": encoded frequency for Hz: " << freq.Hz <<\ + ", double: " << freq.MHzDouble << " as 64-bit uint: " << freqInt; + printHex(result, false, true); + + return result; +} + QByteArray rigCommander::makeFreqPayload(double freq) { quint64 freqInt = (quint64) (freq * 1E6); @@ -533,7 +559,6 @@ QByteArray rigCommander::makeFreqPayload(double freq) //qDebug(logRig()) << "encoded frequency for " << freq << " as int " << freqInt; //printHex(result, false, true); return result; - } void rigCommander::setMode(unsigned char mode, unsigned char modeFilter) @@ -838,7 +863,7 @@ void rigCommander::parseCommand() case '\x25': if((int)payloadIn[1] == 0) { - emit haveFrequency((double)parseFrequency(payloadIn, 5)); + emit haveFrequency(parseFrequency(payloadIn, 5)); } break; case '\x01': @@ -1726,7 +1751,9 @@ void rigCommander::parseBandStackReg() // "DATA: 1a 01 05 01 60 03 23 14 00 00 03 10 00 08 85 00 08 85 fd " // char band = payloadIn[2]; // char regCode = payloadIn[3]; - float freq = parseFrequency(payloadIn, 7); + freqt freqs = parseFrequency(payloadIn, 7); + float freq = (float)freqs.MHzDouble; + bool dataOn = (payloadIn[11] & 0x10) >> 4; // not sure... char mode = payloadIn[9]; @@ -1993,7 +2020,7 @@ void rigCommander::parseDetailedRegisters1A05() void rigCommander::parseWFData() { - float freqSpan = 0.0; + //float freqSpan = 0.0; switch(payloadIn[1]) { case 0: @@ -2017,9 +2044,9 @@ void rigCommander::parseWFData() // read span in center mode // [1] 0x15 // [2] to [8] is span encoded as a frequency - freqSpan = parseFrequency(payloadIn, 8); - qDebug(logRig()) << "Received 0x15 center span data: for frequency " << freqSpan; - printHex(payloadIn, false, true); + //freqSpan = parseFrequency(payloadIn, 8); + //qDebug(logRig()) << "Received 0x15 center span data: for frequency " << freqSpan; + //printHex(payloadIn, false, true); break; case 0x16: // read edge mode center in edge mode @@ -2258,6 +2285,9 @@ void rigCommander::parseSpectrum() // 11 10 26 31 Minimum wave information w/waveform data // 1 1 0 18 Only Wave Information without waveform data + freqt fStart; + freqt fEnd; + unsigned char sequence = bcdHexToUChar(payloadIn[03]); //unsigned char sequenceMax = bcdHexToDecimal(payloadIn[04]); @@ -2293,8 +2323,10 @@ void rigCommander::parseSpectrum() // wave information spectrumLine.clear(); // For Fixed, and both scroll modes, the following produces correct information: - spectrumStartFreq = parseFrequency(payloadIn, 9); - spectrumEndFreq = parseFrequency(payloadIn, 14); + fStart = parseFrequency(payloadIn, 9); + spectrumStartFreq = fStart.MHzDouble; + fEnd = parseFrequency(payloadIn, 14); + spectrumEndFreq = fEnd.MHzDouble; if(scopeMode == spectModeCenter) { // "center" mode, start is actuall center, end is bandwidth. @@ -2413,6 +2445,10 @@ QByteArray rigCommander::bcdEncodeInt(unsigned int num) void rigCommander::parseFrequency() { + freqt freq; + freq.Hz = 0; + freq.MHzDouble = 0; + // process payloadIn, which is stripped. // float frequencyMhz // payloadIn[04] = ; // XX MHz @@ -2428,24 +2464,43 @@ void rigCommander::parseFrequency() // IC-705 or IC-9700 with higher frequency data available. frequencyMhz += 100*(payloadIn[05] & 0x0f); frequencyMhz += (1000*((payloadIn[05] & 0xf0) >> 4)); + + freq.Hz += (payloadIn[05] & 0x0f) * 1E6 * 100; + freq.Hz += ((payloadIn[05] & 0xf0) >> 4) * 1E6 * 1000; + } + freq.Hz += (payloadIn[04] & 0x0f) * 1E6; + freq.Hz += ((payloadIn[04] & 0xf0) >> 4) * 1E6 * 10; + frequencyMhz += payloadIn[04] & 0x0f; frequencyMhz += 10*((payloadIn[04] & 0xf0) >> 4); + // KHz land: frequencyMhz += ((payloadIn[03] & 0xf0) >>4)/10.0 ; frequencyMhz += (payloadIn[03] & 0x0f) / 100.0; frequencyMhz += ((payloadIn[02] & 0xf0) >> 4) / 1000.0; frequencyMhz += (payloadIn[02] & 0x0f) / 10000.0; - frequencyMhz += ((payloadIn[01] & 0xf0) >> 4) / 100000.0; - frequencyMhz += (payloadIn[01] & 0x0f) / 1000000.0; + frequencyMhz += ((payloadIn[01] & 0xf0) >> 4) / 100000.0; + frequencyMhz += (payloadIn[01] & 0x0f) / 1000000.0; - emit haveFrequency(frequencyMhz); + freq.Hz += payloadIn[01] & 0x0f; + freq.Hz += ((payloadIn[01] & 0xf0) >> 4)* 10; + + freq.Hz += (payloadIn[02] & 0x0f) * 100; + freq.Hz += ((payloadIn[02] & 0xf0) >> 4) * 1000; + + freq.Hz += (payloadIn[03] & 0x0f) * 10000; + freq.Hz += ((payloadIn[03] & 0xf0) >>4) * 100000; + + freq.MHzDouble = frequencyMhz; + + emit haveFrequency(freq); } -float rigCommander::parseFrequency(QByteArray data, unsigned char lastPosition) +freqt rigCommander::parseFrequency(QByteArray data, unsigned char lastPosition) { // process payloadIn, which is stripped. // float frequencyMhz @@ -2458,12 +2513,24 @@ float rigCommander::parseFrequency(QByteArray data, unsigned char lastPosition) float freq = 0.0; + freqt freqs; + freqs.MHzDouble = 0; + freqs.Hz = 0; + + // MHz: freq += 100*(data[lastPosition+1] & 0x0f); freq += (1000*((data[lastPosition+1] & 0xf0) >> 4)); freq += data[lastPosition] & 0x0f; freq += 10*((data[lastPosition] & 0xf0) >> 4); + freqs.Hz += (data[lastPosition] & 0x0f) * 1E6; + freqs.Hz += ((data[lastPosition] & 0xf0) >> 4) * 1E6 * 10; + freqs.Hz += (data[lastPosition+1] & 0x0f) * 1E6 * 100; + freqs.Hz += ((data[lastPosition+1] & 0xf0) >> 4) * 1E6 * 1000; + + + // Hz: freq += ((data[lastPosition-1] & 0xf0) >>4)/10.0 ; freq += (data[lastPosition-1] & 0x0f) / 100.0; @@ -2473,7 +2540,18 @@ float rigCommander::parseFrequency(QByteArray data, unsigned char lastPosition) freq += ((data[lastPosition-3] & 0xf0) >> 4) / 100000.0; freq += (data[lastPosition-3] & 0x0f) / 1000000.0; - return freq; + freqs.Hz += (data[lastPosition-1] & 0x0f); + freqs.Hz += ((data[lastPosition-1] & 0xf0) >> 4) * 10; + + freqs.Hz += (data[lastPosition-2] & 0x0f) * 100; + freqs.Hz += ((data[lastPosition-2] & 0xf0) >> 4) * 1000; + + freqs.Hz += (data[lastPosition-3] & 0x0f) * 10000; + freqs.Hz += ((data[lastPosition-3] & 0xf0) >> 4) * 100000; + + freqs.MHzDouble = (double)freq; + + return freqs; } diff --git a/rigcommander.h b/rigcommander.h index f5bd3ce..ed306ab 100644 --- a/rigcommander.h +++ b/rigcommander.h @@ -45,6 +45,11 @@ enum spectrumMode { spectModeUnknown=0xff }; +struct freqt { + quint64 Hz; + double MHzDouble; +}; + class rigCommander : public QObject { Q_OBJECT @@ -75,7 +80,7 @@ public slots: void setScopeEdge(char edge); void getScopeEdge(); void getScopeMode(); - void setFrequency(double freq); + void setFrequency(freqt freq); void setMode(unsigned char mode, unsigned char modeFilter); void getFrequency(); void getBandStackReg(char band, char regCode); @@ -163,7 +168,7 @@ signals: void discoveredRigID(rigCapabilities rigCaps); void haveSerialPortError(const QString port, const QString errorText); void haveStatusUpdate(const QString text); - void haveFrequency(double frequencyMhz); + void haveFrequency(freqt freqStruct); void haveMode(unsigned char mode, unsigned char filter); void haveDataMode(bool dataModeEnabled); void haveDuplexMode(duplexMode); @@ -222,8 +227,9 @@ private: unsigned int bcdHexToUInt(unsigned char hundreds, unsigned char tensunits); QByteArray bcdEncodeInt(unsigned int); void parseFrequency(); - float parseFrequency(QByteArray data, unsigned char lastPosition); // supply index where Mhz is found + freqt parseFrequency(QByteArray data, unsigned char lastPosition); // supply index where Mhz is found QByteArray makeFreqPayload(double frequency); + QByteArray makeFreqPayload(freqt freq); void parseMode(); void parseSpectrum(); void parseWFData(); diff --git a/wfmain.cpp b/wfmain.cpp index 086d00d..d0372c2 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -259,6 +259,7 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent ui->modeFilterCombo->addItem("Setup...", 99); ui->tuningStepCombo->blockSignals(true); + /* ui->tuningStepCombo->addItem("1 Hz", 0.000001f); ui->tuningStepCombo->addItem("10 Hz", 0.000010f); ui->tuningStepCombo->addItem("100 Hz", 0.000100f); @@ -269,6 +270,20 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent ui->tuningStepCombo->addItem("12.5 kHz", 0.012500f); ui->tuningStepCombo->addItem("100 kHz", 0.100000f); ui->tuningStepCombo->addItem("250 kHz", 0.250000f); + */ + + ui->tuningStepCombo->addItem("1 Hz", (unsigned int) 1); + ui->tuningStepCombo->addItem("10 Hz", (unsigned int) 10); + ui->tuningStepCombo->addItem("100 Hz", (unsigned int) 100); + ui->tuningStepCombo->addItem("1 kHz", (unsigned int) 1000); + ui->tuningStepCombo->addItem("2.5 kHz", (unsigned int) 2500); + ui->tuningStepCombo->addItem("5 kHz", (unsigned int) 5000); + ui->tuningStepCombo->addItem("10 kHz", (unsigned int) 10000); + ui->tuningStepCombo->addItem("12.5 kHz",(unsigned int) 12500); + ui->tuningStepCombo->addItem("100 kHz", (unsigned int) 100000); + ui->tuningStepCombo->addItem("250 kHz", (unsigned int) 250000); + + ui->tuningStepCombo->setCurrentIndex(2); ui->tuningStepCombo->blockSignals(false); @@ -339,6 +354,9 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent ui->serialDeviceListCombo->addItem("Manual...", 256); ui->serialDeviceListCombo->blockSignals(false); + freq.MHzDouble = 0.0; + freq.Hz = 0; + openRig(); qRegisterMetaType(); @@ -346,8 +364,9 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); - connect(rig, SIGNAL(haveFrequency(double)), this, SLOT(receiveFreq(double))); + connect(rig, SIGNAL(haveFrequency(freqt)), this, SLOT(receiveFreq(freqt))); connect(this, SIGNAL(getFrequency()), rig, SLOT(getFrequency())); connect(this, SIGNAL(getMode()), rig, SLOT(getMode())); connect(this, SIGNAL(getDataMode()), rig, SLOT(getDataMode())); @@ -379,7 +398,7 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent connect(this, SIGNAL(setScopeMode(spectrumMode)), rig, SLOT(setSpectrumMode(spectrumMode))); connect(this, SIGNAL(getScopeMode()), rig, SLOT(getScopeMode())); - connect(this, SIGNAL(setFrequency(double)), rig, SLOT(setFrequency(double))); + connect(this, SIGNAL(setFrequency(freqt)), rig, SLOT(setFrequency(freqt))); connect(this, SIGNAL(setScopeEdge(char)), rig, SLOT(setScopeEdge(char))); connect(this, SIGNAL(setScopeSpan(char)), rig, SLOT(setScopeSpan(char))); connect(this, SIGNAL(getScopeMode()), rig, SLOT(getScopeMode())); @@ -1247,105 +1266,163 @@ void wfmain::setTuningSteps() tsPlusShift = 0.0001f; tsPage = 1.0f; tsPageShift = 0.5f; // TODO, unbind this keystroke from the dial - tsWfScroll = 0.0001f; - tsKnobMHz = 0.0001f; + tsWfScroll = 0.0001f; // modified by tuning step selector + tsKnobMHz = 0.0001f; // modified by tuning step selector + + // Units are in Hz: + tsPlusControlHz = 10000; + tsPlusHz = 1000; + tsPlusShiftHz = 100; + tsPageHz = 1000000; + tsPageShiftHz = 500000; // TODO, unbind this keystroke from the dial + tsWfScrollHz = 100; // modified by tuning step selector + tsKnobHz = 100; // modified by tuning step selector + } void wfmain::on_tuningStepCombo_currentIndexChanged(int index) { - tsWfScroll = ui->tuningStepCombo->itemData(index).toFloat(); - tsKnobMHz = ui->tuningStepCombo->itemData(index).toFloat(); + tsWfScroll = (float)ui->tuningStepCombo->itemData(index).toUInt() / 1000000.0; + tsKnobMHz = (float)ui->tuningStepCombo->itemData(index).toUInt() / 1000000.0; + + tsWfScrollHz = ui->tuningStepCombo->itemData(index).toUInt(); + tsKnobHz = ui->tuningStepCombo->itemData(index).toUInt(); } -double wfmain::roundFrequency(double frequency) +quint64 wfmain::roundFrequency(quint64 frequency, unsigned int tsHz) { - return round(frequency*1000000) / 1000000.0; + quint64 rounded = 0; + if(ui->tuningFloorZerosChk->isChecked()) + { + rounded = ((frequency % tsHz) > tsHz/2) ? frequency + tsHz - frequency%tsHz : frequency - frequency%tsHz; + return rounded; + } else { + return frequency; + } +} + +quint64 wfmain::roundFrequencyWithStep(quint64 frequency, int steps, unsigned int tsHz) +{ + quint64 rounded = 0; + + if(steps > 0) + { + frequency = frequency + (quint64)(steps*tsHz); + } else { + frequency = frequency - (quint64)(abs(steps)*tsHz); + } + + if(ui->tuningFloorZerosChk->isChecked()) + { + rounded = ((frequency % tsHz) > tsHz/2) ? frequency + tsHz - frequency%tsHz : frequency - frequency%tsHz; + return rounded; + } else { + return frequency; + } } void wfmain::shortcutMinus() { if(freqLock) return; - freqMhz = roundFrequency(freqMhz - tsPlus); - knobFreqMhz = freqMhz; - emit setFrequency(freqMhz); - issueDelayedCommand(cmdGetFreq); - //ui->freqDial->setValue( ui->freqDial->value() - ui->freqDial->singleStep() ); + freqt f; + f.Hz = roundFrequencyWithStep(freq.Hz, -1, tsPlusHz); + + f.MHzDouble = f.Hz / (double)1E6; + setUIFreq(); + emit setFrequency(f); + issueDelayedCommandUnique(cmdGetFreq); } void wfmain::shortcutPlus() { if(freqLock) return; - knobFreqMhz = roundFrequency(freqMhz + tsPlus); - freqMhz = knobFreqMhz; - emit setFrequency(freqMhz); - issueDelayedCommand(cmdGetFreq); - //ui->freqDial->setValue( ui->freqDial->value() + ui->freqDial->singleStep() ); + freqt f; + f.Hz = roundFrequencyWithStep(freq.Hz, 1, tsPlusHz); + + f.MHzDouble = f.Hz / (double)1E6; + setUIFreq(); + emit setFrequency(f); + issueDelayedCommandUnique(cmdGetFreq); } void wfmain::shortcutShiftMinus() { if(freqLock) return; - freqMhz= roundFrequency(freqMhz-tsPlusShift); - knobFreqMhz = freqMhz; - emit setFrequency(freqMhz); - issueDelayedCommand(cmdGetFreq); - //ui->freqDial->setValue( ui->freqDial->value() - ui->freqDial->pageStep() ); + freqt f; + f.Hz = roundFrequencyWithStep(freq.Hz, -1, tsPlusShiftHz); + + f.MHzDouble = f.Hz / (double)1E6; + setUIFreq(); + emit setFrequency(f); + issueDelayedCommandUnique(cmdGetFreq); } void wfmain::shortcutShiftPlus() { if(freqLock) return; - freqMhz= roundFrequency(freqMhz+tsPlusShift); - knobFreqMhz = freqMhz; - emit setFrequency(freqMhz); - issueDelayedCommand(cmdGetFreq); - //ui->freqDial->setValue( ui->freqDial->value() + ui->freqDial->pageStep() ); + freqt f; + f.Hz = roundFrequencyWithStep(freq.Hz, 1, tsPlusShiftHz); + + f.MHzDouble = f.Hz / (double)1E6; + setUIFreq(); + emit setFrequency(f); + issueDelayedCommandUnique(cmdGetFreq); } void wfmain::shortcutControlMinus() { if(freqLock) return; - freqMhz= roundFrequency(freqMhz-tsPlusControl); - knobFreqMhz = freqMhz; - emit setFrequency(freqMhz); - issueDelayedCommand(cmdGetFreq); - //ui->freqDial->setValue( ui->freqDial->value() - ui->freqDial->pageStep() ); + freqt f; + f.Hz = roundFrequencyWithStep(freq.Hz, -1, tsPlusControlHz); + + f.MHzDouble = f.Hz / (double)1E6; + setUIFreq(); + emit setFrequency(f); + issueDelayedCommandUnique(cmdGetFreq); } void wfmain::shortcutControlPlus() { if(freqLock) return; - freqMhz= roundFrequency(freqMhz+tsPlusControl); - knobFreqMhz = freqMhz; - emit setFrequency(freqMhz); - issueDelayedCommand(cmdGetFreq); - //ui->freqDial->setValue( ui->freqDial->value() + ui->freqDial->pageStep() ); + freqt f; + f.Hz = roundFrequencyWithStep(freq.Hz, 1, tsPlusControlHz); + + f.MHzDouble = f.Hz / (double)1E6; + setUIFreq(); + emit setFrequency(f); + issueDelayedCommandUnique(cmdGetFreq); } void wfmain::shortcutPageUp() { if(freqLock) return; - freqMhz = roundFrequency(freqMhz + tsPage); - knobFreqMhz = freqMhz; - emit setFrequency(freqMhz); - issueDelayedCommand(cmdGetFreq); + freqt f; + f.Hz = freq.Hz + tsPageHz; + + f.MHzDouble = f.Hz / (double)1E6; + setUIFreq(); + emit setFrequency(f); + issueDelayedCommandUnique(cmdGetFreq); } void wfmain::shortcutPageDown() { if(freqLock) return; - freqMhz = roundFrequency(freqMhz - tsPage); - knobFreqMhz = freqMhz; - emit setFrequency(freqMhz); - issueDelayedCommand(cmdGetFreq); + freqt f; + f.Hz = freq.Hz - tsPageHz; + + f.MHzDouble = f.Hz / (double)1E6; + setUIFreq(); + emit setFrequency(f); + issueDelayedCommandUnique(cmdGetFreq); } void wfmain::shortcutF() @@ -1360,6 +1437,17 @@ void wfmain::shortcutM() emit sayMode(); } +void wfmain::setUIFreq(double frequency) +{ + ui->freqLabel->setText(QString("%1").arg(frequency, 0, 'f')); +} + +void wfmain::setUIFreq() +{ + // Call this function, without arguments, if you know that the + // freqMhz variable is already set correctly. + setUIFreq(freq.MHzDouble); +} void wfmain:: getInitialRigState() { @@ -1809,6 +1897,18 @@ void wfmain::issueDelayedCommandPriority(cmds cmd) delayedCommand->start(); } +void wfmain::issueDelayedCommandUnique(cmds cmd) +{ + // Use this function to insert commands where + // multiple (redundant) commands don't make sense. + if(!cmdOutQue.contains(cmd)) + { + cmdOutQue.prepend(cmd); + delayedCommand->start(); + } +} + + void wfmain::receiveRigID(rigCapabilities rigCaps) { // Note: We intentionally request rigID several times @@ -1930,12 +2030,12 @@ void wfmain::insertPeriodicCommand(cmds cmd, unsigned char priority) } } -void wfmain::receiveFreq(double freqMhz) +void wfmain::receiveFreq(freqt freqStruct) { + //qDebug(logSystem()) << "HEY WE GOT A Frequency: " << freqMhz; - ui->freqLabel->setText(QString("%1").arg(freqMhz, 0, 'f')); - this->freqMhz = freqMhz; - this->knobFreqMhz = freqMhz; + ui->freqLabel->setText(QString("%1").arg(freqStruct.MHzDouble, 0, 'f')); + freq = freqStruct; //showStatusBarText(QString("Frequency: %1").arg(freqMhz)); } @@ -2030,10 +2130,10 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e //ui->qcp->addGraph(); plot->graph(0)->setData(x,y); - if((freqMhz < endFreq) && (freqMhz > startFreq)) + if((freq.MHzDouble < endFreq) && (freq.MHzDouble > startFreq)) { // tracer->setGraphKey(freqMhz); - tracer->setGraphKey(knobFreqMhz); + tracer->setGraphKey(freq.MHzDouble); } if(drawPeaks) @@ -2092,13 +2192,15 @@ void wfmain::receiveSpectrumMode(spectrumMode spectMode) void wfmain::handlePlotDoubleClick(QMouseEvent *me) { double x; + freqt freq; //double y; //double px; if(!freqLock) { //y = plot->yAxis->pixelToCoord(me->pos().y()); x = plot->xAxis->pixelToCoord(me->pos().x()); - emit setFrequency(x); + freq.Hz = x*1E6; + emit setFrequency(freq); issueDelayedCommand(cmdGetFreq); showStatusBarText(QString("Going to %1 MHz").arg(x)); } @@ -2107,6 +2209,7 @@ void wfmain::handlePlotDoubleClick(QMouseEvent *me) void wfmain::handleWFDoubleClick(QMouseEvent *me) { double x; + freqt freq; //double y; //x = wf->xAxis->pixelToCoord(me->pos().x()); //y = wf->yAxis->pixelToCoord(me->pos().y()); @@ -2114,7 +2217,8 @@ void wfmain::handleWFDoubleClick(QMouseEvent *me) if(!freqLock) { x = plot->xAxis->pixelToCoord(me->pos().x()); - emit setFrequency(x); + freq.Hz = x*1E6; + emit setFrequency(freq); issueDelayedCommand(cmdGetFreq); showStatusBarText(QString("Going to %1 MHz").arg(x)); } @@ -2142,51 +2246,39 @@ void wfmain::handleWFScroll(QWheelEvent *we) if(freqLock) return; + freqt f; + f.Hz = 0; + f.MHzDouble = 0; + int clicks = we->angleDelta().y() / 120; - float steps = tsWfScroll * clicks; + if(!clicks) + return; + + unsigned int stepsHz = tsWfScrollHz; Qt::KeyboardModifiers key= we->modifiers(); - if (key == Qt::ShiftModifier) + if ((key == Qt::ShiftModifier) && (stepsHz !=1)) { - steps /= 10; + stepsHz /= 10; } else if (key == Qt::ControlModifier) { - steps *=10; + stepsHz *= 10; } - freqMhz = roundFrequency(freqMhz - steps); - knobFreqMhz = freqMhz; - emit setFrequency(freqMhz); - ui->freqLabel->setText(QString("%1").arg(freqMhz, 0, 'f')); - issueDelayedCommand(cmdGetFreq); + f.Hz = roundFrequencyWithStep(freq.Hz, clicks, stepsHz); + f.MHzDouble = f.Hz / (double)1E6; + freq = f; + + emit setFrequency(f); + ui->freqLabel->setText(QString("%1").arg(f.MHzDouble, 0, 'f')); + issueDelayedCommandUnique(cmdGetFreq); } void wfmain::handlePlotScroll(QWheelEvent *we) { - if(freqLock) - return; - - int clicks = we->angleDelta().y() / 120; - - float steps = tsWfScroll * clicks; - - Qt::KeyboardModifiers key= we->modifiers(); - - if (key == Qt::ShiftModifier) - { - steps /= 10; - } else if (key == Qt::ControlModifier) - { - steps *=10; - } - - freqMhz = roundFrequency(freqMhz - steps); - knobFreqMhz = freqMhz; - emit setFrequency(freqMhz); - ui->freqLabel->setText(QString("%1").arg(freqMhz, 0, 'f')); - issueDelayedCommand(cmdGetFreq); + handleWFScroll(we); } void wfmain::on_scopeEnableWFBtn_clicked(bool checked) @@ -2298,11 +2390,13 @@ void wfmain::on_fullScreenChk_clicked(bool checked) void wfmain::on_goFreqBtn_clicked() { + freqt f; bool ok = false; double freq = ui->freqMhzLineEdit->text().toDouble(&ok); if(ok) { - emit setFrequency(freq); + f.Hz = freq*1E6; + emit setFrequency(f); issueDelayedCommand(cmdGetFreq); } ui->freqMhzLineEdit->selectAll(); @@ -2474,8 +2568,11 @@ void wfmain::on_modeSelectCombo_activated(int index) void wfmain::on_freqDial_valueChanged(int value) { int maxVal = ui->freqDial->maximum(); - double stepSize = (double)tsKnobMHz; - double newFreqMhz = 0; + + freqt f; + f.Hz = 0; + f.MHzDouble = 0; + volatile int delta = 0; int directPath = 0; @@ -2536,43 +2633,27 @@ void wfmain::on_freqDial_valueChanged(int value) delta = value - oldFreqDialVal; } - newFreqMhz = knobFreqMhz + ((double)delta * stepSize); + // With the number of steps and direction of steps established, + // we can now adjust the frequeny: - if(ui->tuningFloorZerosChk->isChecked() && (stepSize > (double)0.0000019)) - { - unsigned int Hz = (newFreqMhz - ((int)newFreqMhz))*1E6; - unsigned int MHz = (unsigned int)newFreqMhz; - unsigned int tsHz = ((float)(tsKnobMHz*1000000.0)); - - // The following is necessary because the newFreqMhz calculated prior to this if(..checked..) code is prone to errors from - // multiplying the delta times the stepSize. Basically, an upward step of 100 hz can sometimes come out as 99hz. - // Thus, the following code actually rounds up or down as needed, depending upon the level of "error" when the float and int - // calculations are compared. - if( ((float(Hz)/float(tsHz)) - (float)((int)Hz/(int)tsHz)) > 0.5 ) - { - Hz = ((Hz / tsHz) + 1) * (tsHz); - } else { - Hz = (Hz / tsHz) * (tsHz); - } - - newFreqMhz = MHz + (Hz/1E6); - } - - this->knobFreqMhz = newFreqMhz; // the frequency we think we should be on. + f.Hz = roundFrequencyWithStep(freq.Hz, delta, tsKnobHz); + f.MHzDouble = f.Hz / (double)1E6; + freq = f; oldFreqDialVal = value; - ui->freqLabel->setText(QString("%1").arg(knobFreqMhz, 0, 'f')); + ui->freqLabel->setText(QString("%1").arg(f.MHzDouble, 0, 'f')); - this->freqMhz = knobFreqMhz; - emit setFrequency(newFreqMhz); + emit setFrequency(f); } void wfmain::receiveBandStackReg(float freq, char mode, bool dataOn) { // read the band stack and apply by sending out commands - setFrequency(freq); + freqt f; + f.Hz = freq * 1E6; + setFrequency(f); int filterSelection = ui->modeFilterCombo->currentData().toInt(); setMode(mode, (unsigned char)filterSelection); // make sure this is what you think it is @@ -2656,7 +2737,9 @@ void wfmain::on_band60mbtn_clicked() // Channel 5: 5403.5 kHz // Really not sure what the best strategy here is, don't want to // clutter the UI with 60M channel buttons... - setFrequency(5.3305); + freqt f; + f.Hz = (5.3305) * 1E6; + setFrequency(f); } void wfmain::on_band80mbtn_clicked() @@ -2728,8 +2811,8 @@ void wfmain::on_fStoBtn_clicked() if(ok && (preset_number >= 0) && (preset_number < 100)) { // TODO: keep an enum around with the current mode - mem.setPreset(preset_number, freqMhz, (mode_kind)ui->modeSelectCombo->currentIndex()); - showStatusBarText( QString("Storing frequency %1 to memory location %2").arg( freqMhz ).arg(preset_number) ); + mem.setPreset(preset_number, freq.MHzDouble, (mode_kind)ui->modeSelectCombo->currentIndex()); + showStatusBarText( QString("Storing frequency %1 to memory location %2").arg( freq.MHzDouble ).arg(preset_number) ); } else { showStatusBarText(QString("Could not store preset to %1. Valid preset numbers are 0 to 99").arg(preset_number)); } diff --git a/wfmain.h b/wfmain.h index 48b197e..02474b8 100644 --- a/wfmain.h +++ b/wfmain.h @@ -41,7 +41,7 @@ public: signals: void getFrequency(); - void setFrequency(double freq); + void setFrequency(freqt freq); void getMode(); void setMode(unsigned char modeIndex, unsigned char modeFilter); void setDataMode(bool dataOn); @@ -153,7 +153,7 @@ private slots: void handlePttLimit(); // hit at 3 min transmit length void receiveCommReady(); - void receiveFreq(double); + void receiveFreq(freqt); void receiveMode(unsigned char mode, unsigned char filter); void receiveSpectrumData(QByteArray spectrum, double startFreq, double endFreq); void receiveSpectrumMode(spectrumMode spectMode); @@ -476,8 +476,7 @@ private: double oldLowerFreq; double oldUpperFreq; - double freqMhz; - double knobFreqMhz; + freqt freq; float tsKnobMHz; enum cmds {cmdNone, cmdGetRigID, cmdGetRigCIV, cmdGetFreq, cmdGetMode, cmdGetDataMode, cmdSetDataModeOn, cmdSetDataModeOff, @@ -539,11 +538,22 @@ private: void useColors(); // set the plot up void setDefPrefs(); // populate default values to default prefs void setTuningSteps(); - double roundFrequency(double frequency); + //double roundFrequency(double frequency); + //double roundFrequency(double frequency, unsigned int tsHz); + //double roundFrequencyWithStep(double oldFreq, int steps, + // unsigned int tsHz); + + quint64 roundFrequency(quint64 frequency, unsigned int tsHz); + quint64 roundFrequencyWithStep(quint64 oldFreq, int steps,\ + unsigned int tsHz); + + void setUIFreq(double frequency); + void setUIFreq(); void changeTxBtn(); void issueDelayedCommand(cmds cmd); void issueDelayedCommandPriority(cmds cmd); + void issueDelayedCommandUnique(cmds cmd); void changeSliderQuietly(QSlider *slider, int value); void processModLevel(rigInput source, unsigned char level); @@ -600,7 +610,13 @@ private: float tsPageShift; float tsWfScroll; - + unsigned int tsPlusHz; + unsigned int tsPlusShiftHz; + unsigned int tsPlusControlHz; + unsigned int tsPageHz; + unsigned int tsPageShiftHz; + unsigned int tsWfScrollHz; + unsigned int tsKnobHz; SERVERCONFIG serverConfig; @@ -608,6 +624,7 @@ private: }; Q_DECLARE_METATYPE(struct rigCapabilities) +Q_DECLARE_METATYPE(struct freqt) Q_DECLARE_METATYPE(struct udpPreferences) Q_DECLARE_METATYPE(enum rigInput) Q_DECLARE_METATYPE(enum duplexMode)