RBW Cal
RBW Cal, traces again
This commit is contained in:
parent
3057a73b20
commit
5490709654
@ -169,7 +169,7 @@ static uint16_t chunkIndex;
|
||||
autoSweepFreqStep = ( setting.BandscopeSpan ) / sweepPoints;
|
||||
offsetFreqIncrement = autoSweepFreqStep; // 2500 Hz for 200kHz span, 80 points per sweep
|
||||
|
||||
bandwidth = rcvr.SetRBW ( setting.BandscopeRBW10, &delaytime ); // Set it in the receiver Si4432
|
||||
bandwidth = rcvr.SetRBW ( setting.BandscopeRBW10, &delaytime, &bpfIndex ); // Set it in the receiver Si4432
|
||||
|
||||
//Serial.printf("set rcvr Freq get:%u, tempIF:%u\n", rcvr.GetFrequency(), tempIF);
|
||||
rcvr.SetFrequency ( setting.IF_Freq + 1300 ); // Set the RX Si4432 to the IF frequency, offset a bit
|
||||
@ -185,7 +185,7 @@ static uint16_t chunkIndex;
|
||||
}
|
||||
|
||||
// pre-calculate adjustment for RSSI values
|
||||
dBadjust = (double)setting.Attenuate - 120.0 + setting.LevelOffset - setting.ExternalGain;
|
||||
dBadjust = (double)setting.Attenuate - 120.0 + setting.LevelOffset - setting.ExternalGain + bpfCalibrations[bpfIndex];
|
||||
Serial.printf("Bandscope dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n",
|
||||
dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain);
|
||||
|
||||
|
@ -76,7 +76,7 @@ static uint16_t chunkIndex;
|
||||
|
||||
vbw = autoSweepFreqStep / 1000.0; // Set the video resolution
|
||||
|
||||
bandwidth = rcvr.SetRBW ( 106.0, &delaytime ); // Set it in the receiver Si4432. delaytime is returned
|
||||
bandwidth = rcvr.SetRBW ( 106.0, &delaytime, &bpfIndex ); // Set it in the receiver Si4432. delaytime is returned
|
||||
|
||||
sweepPoints = displayPoints; // At least the right number of points for the display
|
||||
|
||||
@ -85,7 +85,7 @@ static uint16_t chunkIndex;
|
||||
att.SetAtten ( 0 ); // Set the internal attenuator
|
||||
|
||||
// pre-calculate adjustment for RSSI values
|
||||
dBadjust = -120.0 + setting.LevelOffset - setting.ExternalGain;
|
||||
dBadjust = -120.0 + setting.LevelOffset - setting.ExternalGain + bpfCalibrations[bpfIndex] ;
|
||||
Serial.printf("IFSweep dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n",
|
||||
dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain);
|
||||
|
||||
|
@ -123,7 +123,7 @@ static uint16_t bpfCalFirstSweepDone;
|
||||
/*
|
||||
* Use the RBW setting. If zero then it is meaningless, use smallest instead
|
||||
*/
|
||||
bandwidth = rcvr.SetRBW ( currentRBW10, &delaytime ); // Set it in the receiver Si4432. delaytime is returned
|
||||
bandwidth = rcvr.SetRBW ( currentRBW10, &delaytime, &bpfIndex ); // Set it in the receiver Si4432. delaytime is returned
|
||||
|
||||
sweepPoints = displayPoints;
|
||||
|
||||
|
@ -111,7 +111,7 @@ static uint32_t tgIF; // Track gen IF - SA IF plus any offset if both SI4432
|
||||
|
||||
if ( requiredRBW10 != old_requiredRBW10 )
|
||||
{
|
||||
bandwidth = rcvr.SetRBW ( requiredRBW10, &delaytime ); // Set it in the receiver Si4432
|
||||
bandwidth = rcvr.SetRBW ( requiredRBW10, &delaytime, &bpfIndex ); // Set it in the receiver Si4432
|
||||
old_requiredRBW10 = requiredRBW10;
|
||||
}
|
||||
|
||||
@ -143,9 +143,9 @@ static uint32_t tgIF; // Track gen IF - SA IF plus any offset if both SI4432
|
||||
}
|
||||
|
||||
// pre-calculate adjustment for RSSI values
|
||||
dBadjust = (double)setting.Attenuate - 120.0 + setting.LevelOffset - setting.ExternalGain;
|
||||
//Serial.printf("SweepLo dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n",
|
||||
// dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain);
|
||||
dBadjust = (double)setting.Attenuate - 120.0 + setting.LevelOffset - setting.ExternalGain + bpfCalibrations[bpfIndex];
|
||||
Serial.printf("SweepLo dBadjust = %f; leveloffset = %f; attenuate = %i, ext gain = %f\n",
|
||||
dBadjust, setting.LevelOffset, setting.Attenuate, setting.ExternalGain);
|
||||
|
||||
resetAverage = changedSetting;
|
||||
|
||||
|
19
cmd.cpp
19
cmd.cpp
@ -70,6 +70,7 @@ extern uint8_t myStorage[SCREEN_WIDTH+1];
|
||||
|
||||
extern float bandwidth; // The current bandwidth (not * 10)
|
||||
extern unsigned long delaytime; // In microseconds
|
||||
extern uint16_t bpfIndex; // RBW bandpass Filter in use
|
||||
extern unsigned long offsetDelayTime; // In microseconds
|
||||
|
||||
extern unsigned long wiFiTargetTime;
|
||||
@ -395,17 +396,23 @@ int16_t index = 0; // Index to the buffer
|
||||
while ( Serial.available () ) // While data to read
|
||||
{
|
||||
c = toupper ( Serial.read () ); // Get next character
|
||||
Serial.print(c); // Echo
|
||||
Serial.printf("(%02X)", c); // debug
|
||||
|
||||
if (( c == '\r' ) || ( c == '\n' )) // End of the line?
|
||||
if (( c == '\r' ) || ( c == '\n' )) // End of the line?
|
||||
{
|
||||
inBuff[index++] = '\0'; // Replace with a null
|
||||
|
||||
Serial.println("EOL"); // debug
|
||||
return ParseCommand ( inBuff ); // Process the command and return result
|
||||
}
|
||||
else // Not the end of the line
|
||||
inBuff[index++] = c; // Save the character
|
||||
|
||||
inBuff[index] = '\0'; // Make next character a null
|
||||
}
|
||||
|
||||
return ParseCommand ( inBuff ); // Process the command and return result
|
||||
return false;
|
||||
// return ParseCommand ( inBuff ); // Process the command and return result
|
||||
}
|
||||
|
||||
|
||||
@ -1797,6 +1804,10 @@ uint8_t reg69; // Ditto
|
||||
Serial.println("Starting bpf calibration");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("bpfCal only works in RX_SWEEP (RBW test) mode");
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
@ -3204,7 +3215,7 @@ int16_t tempBw = bw;
|
||||
|
||||
setting.BandscopeRBW10 = bw;
|
||||
|
||||
tempBw = rcvr.SetRBW ( bw, &delaytime );
|
||||
tempBw = rcvr.SetRBW ( bw, &delaytime, &bpfIndex );
|
||||
|
||||
if ( tempBw != oldRBW )
|
||||
{
|
||||
|
@ -206,7 +206,7 @@
|
||||
</select>
|
||||
<br />
|
||||
<label class="setting-label">Level:</label>
|
||||
<input class="value-input" type="number" id="setTrackGenPower" placeholder="setTrackGenPower" maxlength = "6" min="-60" max="20" value="0" />
|
||||
<input class="value-input" type="number" id="setTrackGenPower" placeholder="setTrackGenPower" maxlength = "6" min="-60" max="10" value="0" />
|
||||
dBm
|
||||
</div>
|
||||
<div class="setting" >
|
||||
@ -242,6 +242,9 @@
|
||||
<div class="setting" >
|
||||
<label for="levelOffset" class="setting-label">Offset:</label>
|
||||
<input class="value-display" type="text" disabled="1" id="levelOffset" size="1" value="10" />
|
||||
dB
|
||||
<label for="filterCal" class="setting-label">RBW Cal:</label>
|
||||
<input class="value-display" type="text" disabled="1" id="filterCal" size="1" value="0" />
|
||||
dB
|
||||
</div>
|
||||
<div class="setting" >
|
||||
@ -356,6 +359,7 @@ var setAtten = document.getElementById('setAtten');
|
||||
var setExtern = document.getElementById('setExtern');
|
||||
var setActPower = document.getElementById('setActPower');
|
||||
var levelOffset = document.getElementById('levelOffset');
|
||||
var filterCal = document.getElementById('filterCal');
|
||||
var setRefOut = document.getElementById('setRefOut');
|
||||
var sweepPoints = document.getElementById('sweepPoints');
|
||||
var sweepTime = document.getElementById('sweepTime');
|
||||
@ -399,6 +403,7 @@ var oldSweepCenter = -1;
|
||||
var oldSetRefOut = -2;
|
||||
var oldSetRBW = -10;
|
||||
var oldLevelOffset = 1000;
|
||||
var oldFilterCal = 1000;
|
||||
var oldAttenuation = 1000;
|
||||
var oldExternalGain = 1000;
|
||||
var oldDrive = -1;
|
||||
@ -535,14 +540,24 @@ var chartSA = new CanvasJS.Chart("chartSA",
|
||||
},
|
||||
axisY2: [
|
||||
{
|
||||
title: "RSSI",
|
||||
// title: "RSSI",
|
||||
title:"",
|
||||
tickLength: 0,
|
||||
lineThickness:0,
|
||||
margin:0,
|
||||
titleFontSize: 24,
|
||||
valueFormatString: " ",
|
||||
minimum: 0,
|
||||
maximum: 255
|
||||
},
|
||||
{
|
||||
title: "Gain",
|
||||
// title: "Gain",
|
||||
title:"",
|
||||
tickLength: 0,
|
||||
lineThickness:0,
|
||||
margin:0,
|
||||
titleFontSize: 24,
|
||||
valueFormatString: " ",
|
||||
minimum: 0,
|
||||
maximum: 50
|
||||
}],
|
||||
@ -555,14 +570,58 @@ var chartSA = new CanvasJS.Chart("chartSA",
|
||||
//console.log(e);
|
||||
if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
|
||||
e.dataSeries.visible = false;
|
||||
|
||||
if (e.dataSeries.name == "RSSI") { // turn off the RSSI axis and ticks
|
||||
chartSA.axisY2[0].options.title ="";
|
||||
chartSA.axisY2[0].options.tickLength = 0;
|
||||
chartSA.axisY2[0].options.lineThickness = 0;
|
||||
chartSA.axisY2[0].options.margin = 0;
|
||||
chartSA.axisY2[0].options.valueFormatString = " ";
|
||||
// chartSA.axisY2[0].labelFormatter = function(e) { return ""; }
|
||||
}
|
||||
if (e.dataSeries.name == "gain") { // turn off the gain axis and ticks
|
||||
chartSA.axisY2[1].options.title ="";
|
||||
chartSA.axisY2[1].options.tickLength = 0;
|
||||
chartSA.axisY2[1].options.lineThickness = 0;
|
||||
chartSA.axisY2[1].options.margin = 0;
|
||||
chartSA.axisY2[1].options.valueFormatString = " ";
|
||||
// chartSA.axisY2[1].labelFormatter = function(e) { return ""; }
|
||||
}
|
||||
|
||||
} else {
|
||||
e.dataSeries.visible = true;
|
||||
|
||||
if (e.dataSeries.name == "RSSI") { // turn on the RSSI axis and ticks
|
||||
|
||||
chartSA.axisY2[0].options.title ="RSSI";
|
||||
chartSA.axisY2[0].options.tickLength = 5;
|
||||
chartSA.axisY2[0].options.lineThickness = 2;
|
||||
chartSA.axisY2[0].options.margin = 2;
|
||||
chartSA.axisY2[0].options.valueFormatString = "###";
|
||||
// chartSA.axisY2[0].labelFormatter = function(e)
|
||||
// {
|
||||
// return CanvasJS.formatNumber(e.value);
|
||||
// }
|
||||
}
|
||||
if (e.dataSeries.name == "gain") { // turn on the gain axis and ticks
|
||||
|
||||
chartSA.axisY2[1].options.title ="gain";
|
||||
chartSA.axisY2[1].options.tickLength = 5;
|
||||
chartSA.axisY2[1].options.lineThickness = 2;
|
||||
chartSA.axisY2[1].options.margin = 2;
|
||||
chartSA.axisY2[1].options.valueFormatString = "##";
|
||||
// chartSA.axisY2[1].labelFormatter = function(e)
|
||||
// {
|
||||
// return CanvasJS.formatNumber(e.value);
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
e.chart.render();
|
||||
chartSA.render();
|
||||
}
|
||||
},
|
||||
data: [
|
||||
data: [
|
||||
{
|
||||
type: "line",
|
||||
name: "dB",
|
||||
@ -1018,7 +1077,7 @@ function handleSettings (settings)
|
||||
setCenter.disabled = true;
|
||||
setSpan.disabled = true;
|
||||
setRBW.disabled = false;
|
||||
setRefOut.disabled = true;
|
||||
setRefOut.disabled = false;
|
||||
setSpur.disabled = true;
|
||||
setTrackGen.disabled = true;
|
||||
setTGFreq.disabled = true;
|
||||
@ -1036,7 +1095,7 @@ function handleSettings (settings)
|
||||
setCenter.disabled = true;
|
||||
setSpan.disabled = true;
|
||||
setRBW.disabled = true;
|
||||
setRefOut.disabled = true;
|
||||
setRefOut.disabled = false;
|
||||
setSpur.disabled = true;
|
||||
setTrackGen.disabled = true;
|
||||
setTGFreq.disabled = true;
|
||||
@ -1105,6 +1164,7 @@ function handleSettings (settings)
|
||||
|
||||
|
||||
levelOffset.value = settings.levelOffset;
|
||||
filterCal.value = settings.filterCal;
|
||||
// console.log("levelOffset=" + settings.levelOffset);
|
||||
|
||||
if (settings.start/1000 != oldSweepStart) {
|
||||
@ -1315,6 +1375,8 @@ function handleChunkData (data)
|
||||
var dataStart = data.StartIndex;
|
||||
|
||||
var b = parseInt(levelOffset.value) + parseInt(setAtten.value) - 120 - parseFloat(setExtern.value);
|
||||
// If RX Sweep (test of rbw filters) then don't add the correction from calibration
|
||||
if (setMode.value != 8) b = b + parseFloat(filterCal.value);
|
||||
|
||||
var a = 1/setAverage.value;
|
||||
|
||||
|
@ -328,7 +328,7 @@ const char* unit[4] = { "RX", "TX", "TGIF", "TGLO" }; // For debugging
|
||||
delay ( 1 ); // Slight pause
|
||||
}
|
||||
|
||||
Serial.printf ( "Si4432 Reset failed - _cs = %i\n", _cs );
|
||||
Serial.printf ( "%s Si4432 Reset failed - _cs = %i\n", unit[_type], _cs );
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -599,10 +599,11 @@ void Si4432::SetOffset ( int32_t offset )
|
||||
* and returns the actual value chosen as well as the required delay to allow the
|
||||
* FIR filter in the SI4432 to settle (in microseconds) Delay time is longer for
|
||||
* narrower bandwidths.
|
||||
* The filter index is also returned.
|
||||
* Filters flagged as DO_NOT_USE will not be chosen
|
||||
*/
|
||||
|
||||
float Si4432::SetRBW ( float reqBandwidth10, unsigned long* delaytime_p ) // "reqBandwidth" in kHz * 10
|
||||
float Si4432::SetRBW ( float reqBandwidth10, unsigned long* delaytime_p, uint16_t* filter_p ) // "reqBandwidth" in kHz * 10
|
||||
{
|
||||
int filter = _bpfCount-1; // Elements in the "bandpassFilters" array
|
||||
|
||||
@ -668,6 +669,7 @@ float Si4432::SetRBW ( float reqBandwidth10, unsigned long* delaytime_p ) // "re
|
||||
_dt = _bandpassFilters[filter].settleTime;
|
||||
|
||||
*delaytime_p = _dt;
|
||||
*filter_p = filter;
|
||||
return _bw;
|
||||
}
|
||||
|
||||
|
2
si4432.h
2
si4432.h
@ -187,7 +187,7 @@ void SetOffset ( int32_t offset ); // Offset based on number of offset incre
|
||||
void SetPowerReference ( int freq ); // Set the GPIO output for the LO
|
||||
void SetDrive ( uint8_t level ); // Sets the drive level
|
||||
|
||||
float SetRBW ( float reqBandwidth10, unsigned long* delaytime_p ); // "reqBandwidth" in kHz * 10
|
||||
float SetRBW ( float reqBandwidth10, unsigned long* delaytime_p, uint16_t* filter_p ); // "reqBandwidth" in kHz * 10
|
||||
|
||||
void SetPreampGain ( int gain ); // Sets preamp gain
|
||||
int GetPreampGain (); // Get current gain register
|
||||
|
21
simpleSA.ino
21
simpleSA.ino
@ -416,6 +416,7 @@ double dBadjust; // Sum of attenuation, external gain, calibration offset
|
||||
uint16_t bpfCalibrate; // set true if a SI4432 bandpass filter calibration run is taking place
|
||||
uint16_t bpfCount; // no of bandpass filters available
|
||||
double bpfCalibrations[MAX_SI4432_FILTERS]; // temporary storage for calibration values
|
||||
uint16_t bpfIndex; // Index for current rbw filter
|
||||
|
||||
/*
|
||||
* Variables for offset frequency tuning (used in Bandscope mode)
|
||||
@ -700,12 +701,14 @@ bool fsStatus = false; // True if SPIFFS loads ok
|
||||
"RX SI4432 failed",
|
||||
"to initialise", NULL, NULL );
|
||||
|
||||
bandwidth = rcvr.SetRBW ( setting.Bandwidth10, &delaytime ); // Set initial bandwidth and delaytime
|
||||
bandwidth = rcvr.SetRBW ( setting.Bandwidth10, &delaytime, &bpfIndex ); // Set initial bandwidth, delaytime and filter
|
||||
SetRX ( 0 ); // RX in receive, LO in transmit
|
||||
rcvr.SetPreampGain ( setting.PreampGain );
|
||||
bpfCount = rcvr.GetBandpassFilterCount(); // no of RBW filters available
|
||||
|
||||
ReadBpfCalibration(); // Get bandpass filter (RBW) calibrations
|
||||
printBpfCal(); // and display the values
|
||||
|
||||
|
||||
|
||||
// If the tracking generator IF SI4432 is defined, then check to see if it is connected
|
||||
@ -2132,3 +2135,19 @@ void printSPIFFS()
|
||||
file = root.openNextFile(); // Move to the next file
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Print out the bpf calibration values
|
||||
*/
|
||||
void printBpfCal()
|
||||
{
|
||||
|
||||
Serial.println("Bandpass Filter Calibration values:\n");
|
||||
|
||||
for (int i = 0; i< bpfCount; i++)
|
||||
{
|
||||
Serial.printf("filter: %i, rbw10=%i , cal=%f \n", i, rcvr.GetBandpassFilter10(i), bpfCalibrations[i] );
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ extern unsigned long sweepMicros; // To report the scan time
|
||||
|
||||
|
||||
extern uint16_t bpfCount; // Number of elements in the bandpassFilters array
|
||||
extern double bpfCalibrations[MAX_SI4432_FILTERS]; // temporary storage for calibration values
|
||||
extern uint16_t bpfIndex; // Index for current rbw filter
|
||||
extern int updateSidebar; // Flag to indicate no of clients has changed
|
||||
extern void ClearDisplay ();
|
||||
extern void DisplayError ( uint8_t severity, const char *l1, const char *l2, const char *l3, const char *l4 );
|
||||
@ -581,6 +583,7 @@ void onGetSweep ( AsyncWebServerRequest *request )
|
||||
root["attenuation"] = setting.Attenuate;
|
||||
root["extGain"] = setting.ExternalGain;
|
||||
root["levelOffset"] = setting.LevelOffset;
|
||||
root["filterCal"] = bpfCalibrations[bpfIndex];
|
||||
root["setRBW"] = setting.Bandwidth10;
|
||||
root["bandwidth"] = bandwidth;
|
||||
root["RefOut"] = setting.ReferenceOut;
|
||||
@ -627,6 +630,7 @@ void onGetSettings (AsyncWebServerRequest *request)
|
||||
root["attenuation"] = setting.Attenuate;
|
||||
root["extGain"] = setting.ExternalGain;
|
||||
root["levelOffset"] = setting.LevelOffset;
|
||||
root["filterCal"] = bpfCalibrations[bpfIndex];
|
||||
root["setRBW"] = setting.Bandwidth10;
|
||||
root["bandwidth"] = bandwidth;
|
||||
root["RefOut"] = setting.ReferenceOut;
|
||||
@ -682,6 +686,7 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
|
||||
jsonDocument["attenuation"] = setting.Attenuate;
|
||||
jsonDocument["extGain"] = setting.ExternalGain;
|
||||
jsonDocument["levelOffset"] = setting.LevelOffset;
|
||||
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
|
||||
jsonDocument["setRBW"] = setting.Bandwidth10;
|
||||
jsonDocument["bandwidth"] = bandwidth;
|
||||
jsonDocument["RefOut"] = setting.ReferenceOut;
|
||||
@ -740,6 +745,7 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
|
||||
jsonDocument["attenuation"] = setting.Attenuate;
|
||||
jsonDocument["extGain"] = setting.ExternalGain;
|
||||
jsonDocument["levelOffset"] = setting.LevelOffset;
|
||||
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
|
||||
jsonDocument["setRBW"] = setting.Bandwidth10;
|
||||
jsonDocument["bandwidth"] = bandwidth;
|
||||
jsonDocument["RefOut"] = setting.ReferenceOut;
|
||||
@ -796,6 +802,7 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
|
||||
jsonDocument["attenuation"] = setting.Attenuate;
|
||||
jsonDocument["extGain"] = setting.ExternalGain;
|
||||
jsonDocument["levelOffset"] = 0;
|
||||
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
|
||||
jsonDocument["setRBW"] = setting.Bandwidth10;
|
||||
jsonDocument["bandwidth"] = bandwidth;
|
||||
jsonDocument["RefOut"] = setting.ReferenceOut;
|
||||
@ -852,6 +859,7 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
|
||||
jsonDocument["attenuation"] = setting.Attenuate;
|
||||
jsonDocument["extGain"] = setting.ExternalGain;
|
||||
jsonDocument["levelOffset"] = setting.LevelOffset;
|
||||
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
|
||||
jsonDocument["setRBW"] = setting.Bandwidth10;
|
||||
jsonDocument["bandwidth"] = bandwidth;
|
||||
jsonDocument["RefOut"] = setting.ReferenceOut;
|
||||
@ -909,6 +917,7 @@ static DynamicJsonDocument jsonDocument ( capacity ); // buffer for json data to
|
||||
jsonDocument["attenuation"] = setting.Attenuate;
|
||||
jsonDocument["extGain"] = setting.ExternalGain;
|
||||
jsonDocument["levelOffset"] = setting.LevelOffset;
|
||||
jsonDocument["filterCal"] = bpfCalibrations[bpfIndex];
|
||||
jsonDocument["setRBW"] = setting.Bandwidth10;
|
||||
jsonDocument["bandwidth"] = bandwidth;
|
||||
jsonDocument["RefOut"] = setting.ReferenceOut;
|
||||
|
Loading…
Reference in New Issue
Block a user