From 85271c398ee6a30478275576a65b3de0ce0eefba Mon Sep 17 00:00:00 2001 From: Phil Taylor Date: Sun, 8 Aug 2021 17:14:48 +0100 Subject: [PATCH] Add proper s-meter calibration --- rigcommander.cpp | 2 +- rigctld.cpp | 112 +++++++++++++++++++++++++++++------------------ rigctld.h | 49 +++++++++++++++++++++ 3 files changed, 119 insertions(+), 44 deletions(-) diff --git a/rigcommander.cpp b/rigcommander.cpp index e20b7aa..a36915a 100644 --- a/rigcommander.cpp +++ b/rigcommander.cpp @@ -1317,7 +1317,7 @@ void rigCommander::parseLevels() unsigned char tens = (payloadIn[3] & 0xf0) >> 4; unsigned char units = (payloadIn[3] & 0x0f); - unsigned char level = (100*hundreds) + (10*tens) + units; + unsigned char level = ((unsigned char)100*hundreds) + (10*tens) + units; //qInfo(logRig()) << "Level is: " << (int)level << " or " << 100.0*level/255.0 << "%"; diff --git a/rigctld.cpp b/rigctld.cpp index c16fdec..784f9cc 100644 --- a/rigctld.cpp +++ b/rigctld.cpp @@ -534,119 +534,113 @@ void rigCtlClient::socketReadyRead() else if (command.length() > 1 && (command[0] == "l" || command[0] == "get_level")) { QString resp; - float value = 0; + int value = 0; if (longReply) { resp.append("Level Value: "); } + if (command[1] == "STRENGTH") { - value = (float)rigState->sMeter; - if (value > 240) - value = value - 176; - else if (value > 120) - value = value - 120; - else if (value > 90) - value = value - 102; - else if (value > 60) - value = value - 84; - else if (value > 30) - value = value - 66; - else if (value > 10) - value = value - 58; - else if (value > 0) - value = value - 54; + if (rigCaps.model == model7610) + value = getCalibratedValue(rigState->sMeter, IC7610_STR_CAL); + else if (rigCaps.model == model7850) + value = getCalibratedValue(rigState->sMeter, IC7850_STR_CAL); + else + value = getCalibratedValue(rigState->sMeter, IC7300_STR_CAL); + qInfo(logRigCtlD()) << "Calibration IN:" << rigState->sMeter << "OUT" << value; + resp.append(QString("%1").arg(value)); } else if (command[1] == "AF") { - value = (float)rigState->afGain / 255; + resp.append(QString("%1").arg((float)rigState->afGain / 255.0)); } else if (command[1] == "RF") { - value = (float)rigState->rfGain / 255; + resp.append(QString("%1").arg((float)rigState->rfGain / 255.0)); } else if (command[1] == "SQL") { - value = (float)rigState->squelch / 255; + resp.append(QString("%1").arg((float)rigState->squelch / 255.0)); } else if (command[1] == "COMP") { - value = (float)rigState->compLevel / 255; + resp.append(QString("%1").arg((float)rigState->compLevel / 255.0)); } else if (command[1] == "MICGAIN") { - value = (float)rigState->micGain / 255; - emit parent->setMicGain(value); + resp.append(QString("%1").arg((float)rigState->micGain / 255.0)); } else if (command[1] == "MON") { - value = (float)rigState->monitorLevel / 255; + resp.append(QString("%1").arg((float)rigState->monitorLevel / 255.0)); } else if (command[1] == "VOXGAIN") { - value = (float)rigState->voxGain / 255; + resp.append(QString("%1").arg((float)rigState->voxGain / 255.0)); } else if (command[1] == "ANTIVOX") { - value = (float)rigState->antiVoxGain / 255; + resp.append(QString("%1").arg((float)rigState->antiVoxGain / 255.0)); } else if (command[1] == "RFPOWER") { - value = (float)rigState->txPower / 255; + resp.append(QString("%1").arg((float)rigState->txPower / 255.0)); } else if (command[1] == "PREAMP") { - value = (float)rigState->preamp * 10; + resp.append(QString("%1").arg((float)rigState->preamp / 255.0)); } else if (command[1] == "ATT") { - value = (float)rigState->attenuator; + resp.append(QString("%1").arg((float)rigState->attenuator / 255.0)); + } + else { + resp.append(QString("%1").arg(value)); } - - resp.append(QString("%1").arg(value)); response.append(resp); } else if (command.length() > 2 && (command[0] == "L" || command[0] == "set_level")) { - int value; + unsigned char value; setCommand = true; if (command[1] == "AF") { value = command[2].toFloat() * 255; emit parent->setAfGain(value); - rigState->afGain = (unsigned char)value; + rigState->afGain = value; } else if (command[1] == "RF") { value = command[2].toFloat() * 255; emit parent->setRfGain(value); - rigState->rfGain = (unsigned char)value; + rigState->rfGain = value; } else if (command[1] == "SQL") { value = command[2].toFloat() * 255; emit parent->setSql(value); - rigState->squelch = (unsigned char)value; + rigState->squelch = value; } else if (command[1] == "COMP") { value = command[2].toFloat() * 255; emit parent->setCompLevel(value); - rigState->compLevel = (unsigned char)value; + rigState->compLevel = value; } else if (command[1] == "MICGAIN") { value = command[2].toFloat() * 255; emit parent->setMicGain(value); - rigState->micGain = (unsigned char)value; + rigState->micGain = value; } else if (command[1] == "MON") { value = command[2].toFloat() * 255; emit parent->setMonitorLevel(value); - rigState->monitorLevel = (unsigned char)value; + rigState->monitorLevel = value; } else if (command[1] == "VOXGAIN") { value = command[2].toFloat() * 255; emit parent->setVoxGain(value); - rigState->voxGain = (unsigned char)value; + rigState->voxGain = value; } else if (command[1] == "ANTIVOX") { value = command[2].toFloat() * 255; emit parent->setAntiVoxGain(value); - rigState->antiVoxGain = (unsigned char)value; + rigState->antiVoxGain = value; } else if (command[1] == "ATT") { value = command[2].toFloat(); - emit parent->setAttenuator((unsigned char)value); - rigState->attenuator = (unsigned char)value; + emit parent->setAttenuator(value); + rigState->attenuator = value; } else if (command[1] == "PREAMP") { value = command[2].toFloat()/10; - emit parent->setPreamp((unsigned char)value); - rigState->preamp = (unsigned char)value; + emit parent->setPreamp(value); + rigState->preamp = value; } qInfo(logRigCtlD()) << "Setting:" << command[1] << command[2] << value; @@ -1045,4 +1039,36 @@ QString rigCtlClient::getAntName(unsigned char ant) default: ret = "ANT_UNK"; break; } return ret; +} + +int rigCtlClient::getCalibratedValue(unsigned char meter,cal_table_t cal) { + + int interp; + + int i = 0; + for (i = 0; i < cal.size; i++) { + if (meter < cal.table[i].raw) + { + break; + } + } + + if (i == 0) + { + return cal.table[0].val; + } + else if (i >= cal.size) + { + return cal.table[i - 1].val; + } + else if (cal.table[i].raw == cal.table[i - 1].raw) + { + return cal.table[i].val; + } + + interp = ((cal.table[i].raw - meter) + * (cal.table[i].val - cal.table[i - 1].val)) + / (cal.table[i].raw - cal.table[i - 1].raw); + + return cal.table[i].val - interp; } \ No newline at end of file diff --git a/rigctld.h b/rigctld.h index b7f4ee3..f8f9f8d 100644 --- a/rigctld.h +++ b/rigctld.h @@ -103,6 +103,54 @@ static struct }; +struct cal_table { + int size; /*!< number of plots in the table */ + struct { + int raw; /*!< raw (A/D) value, as returned by \a RIG_LEVEL_RAWSTR */ + int val; /*!< associated value, basically the measured dB value */ + } table[32]; /*!< table of plots */ +}; + +typedef struct cal_table cal_table_t; + +#define IC7610_STR_CAL { 16, \ + { \ + { 0, -54 }, /* S0 */ \ + { 11, -48 }, \ + { 21, -42 }, \ + { 34, -36 }, \ + { 50, -30 }, \ + { 59, -24 }, \ + { 75, -18 }, \ + { 93, -12 }, \ + { 103, -6 }, \ + { 124, 0 }, /* S9 */ \ + { 145, 10 }, \ + { 160, 20 }, \ + { 183, 30 }, \ + { 204, 40 }, \ + { 222, 50 }, \ + { 246, 60 } /* S9+60dB */ \ + } } + +#define IC7850_STR_CAL { 3, \ + { \ + { 0, -54 }, /* S0 */ \ + { 120, 0 }, /* S9 */ \ + { 241, 60 } /* S9+60 */ \ + } } + +#define IC7300_STR_CAL { 7, \ + { \ + { 0, -54 }, \ + { 10, -48 }, \ + { 30, -36 }, \ + { 60, -24 }, \ + { 90, -12 }, \ + { 120, 0 }, \ + { 241, 64 } \ + } } + class rigCtlD : public QTcpServer { Q_OBJECT @@ -191,6 +239,7 @@ private: unsigned char getAntennas(); quint64 getRadioModes(); QString getAntName(unsigned char ant); + int getCalibratedValue(unsigned char meter,cal_table_t cal); };