How to use the SPECTRAN V6 via Matlab

Quote from mm_dev on 31/08/2023, 13:46Quote from CYW on 30/08/2023, 16:05The exact same Matlab code works perfectly if the "HTTP Server" block connects to the "IQ Power Spectrum" block, as shown in the mission file attached in this post. In other words, the code works for the mission attached in post # 80 but show the error message for the mission attached in post# 78. Therefore, it seems to me that somehow the output of the "IQ Power Spectrum" block is different from the output of the "Spectrum" block, and hence it is an issue about the data type of these 2 blocks.
Wrong. The general output format of both blocks is the same (JSON structure that has a "samples" field which is an array of arrays of numbers). So either for some reason you're receiving a different format, or matlab for some reason is unpacking the data differently than before (going by documentation, it tries to analyze the result to unpack it for convenience). Quite possible that you're not getting any data at all. So there would be nothing to fix in your code (other than proper error handling). That is why it is relevant to see what is actually returned by the send function.
Quote from CYW on 30/08/2023, 16:05The exact same Matlab code works perfectly if the "HTTP Server" block connects to the "IQ Power Spectrum" block, as shown in the mission file attached in this post. In other words, the code works for the mission attached in post # 80 but show the error message for the mission attached in post# 78. Therefore, it seems to me that somehow the output of the "IQ Power Spectrum" block is different from the output of the "Spectrum" block, and hence it is an issue about the data type of these 2 blocks.
Wrong. The general output format of both blocks is the same (JSON structure that has a "samples" field which is an array of arrays of numbers). So either for some reason you're receiving a different format, or matlab for some reason is unpacking the data differently than before (going by documentation, it tries to analyze the result to unpack it for convenience). Quite possible that you're not getting any data at all. So there would be nothing to fix in your code (other than proper error handling). That is why it is relevant to see what is actually returned by the send function.

Quote from Jaime on 25/01/2024, 09:21Quote from DevSF on 17/08/2021, 15:44jhexa, you had multiple errors in your code. If the received packets have all the same amount of samples, following code should work:
res=webread('http://localhost:54664/stream?format=raw16&limit=10');
j = strfind(char(res)',char([125 10 30])) + 2;
header = jsondecode(char(res(1:(j(1)-2)))');
disp(header);
I=[]; Q=[];
size = header.samples*4;for i=1:length(j)
values = typecast(res(j(i):(j(i) + size -1)), 'int16');
I = [I (double( values(1:2:size/2) )/header.scale)];
Q = [Q (double( values(2:2:size/2) )/header.scale)];
endIQData = I(1:end,1)+1i*Q(1:end,1);
fftsize = 1024+4;if(fftsize > 1)
fftWindow = hann(fftsize)*2;
y = fftshift( fft( IQData(1:fftsize).*fftWindow, fftsize ) ) ;y = abs(y/fftsize).^2;
y = y/50;
y = 10*log10( y / 0.001 );x = linspace(header.startFrequency, header.endFrequency, fftsize);
%figure
plot(x,y);
xlabel('Frequency in Hz');
ylabel('Power in dBm');
title('Spectrum of RTSA IQ Data');
else
disp('No data to plot');
endAs far as I can tell, the strfind [125 10 30] looks for the '}\n\x1e' substring to divide different samples. If I ask the Aaronia for several samples, let's say I am using the url: http://localhost:54664/stream?limit=15&format=float32. Because of randomness, I could get in the j index variable values corresponding to that substring that does not correspond to the sample separator. Is there any way to tackle this apart from adding values to that substring such as addding the last part of the metadata before the actual binary samples start: "samples":65536}\n\x1e
Quote from DevSF on 17/08/2021, 15:44jhexa, you had multiple errors in your code. If the received packets have all the same amount of samples, following code should work:
res=webread('http://localhost:54664/stream?format=raw16&limit=10');
j = strfind(char(res)',char([125 10 30])) + 2;
header = jsondecode(char(res(1:(j(1)-2)))');
disp(header);
I=[]; Q=[];
size = header.samples*4;for i=1:length(j)
values = typecast(res(j(i):(j(i) + size -1)), 'int16');
I = [I (double( values(1:2:size/2) )/header.scale)];
Q = [Q (double( values(2:2:size/2) )/header.scale)];
endIQData = I(1:end,1)+1i*Q(1:end,1);
fftsize = 1024+4;if(fftsize > 1)
fftWindow = hann(fftsize)*2;
y = fftshift( fft( IQData(1:fftsize).*fftWindow, fftsize ) ) ;y = abs(y/fftsize).^2;
y = y/50;
y = 10*log10( y / 0.001 );x = linspace(header.startFrequency, header.endFrequency, fftsize);
%figure
plot(x,y);
xlabel('Frequency in Hz');
ylabel('Power in dBm');
title('Spectrum of RTSA IQ Data');
else
disp('No data to plot');
end
As far as I can tell, the strfind [125 10 30] looks for the '}\n\x1e' substring to divide different samples. If I ask the Aaronia for several samples, let's say I am using the url: http://localhost:54664/stream?limit=15&format=float32. Because of randomness, I could get in the j index variable values corresponding to that substring that does not correspond to the sample separator. Is there any way to tackle this apart from adding values to that substring such as addding the last part of the metadata before the actual binary samples start: "samples":65536}\n\x1e

Quote from mm_dev on 25/01/2024, 14:28Quote from Jaime on 25/01/2024, 09:21As far as I can tell, the strfind [125 10 30] looks for the '}\n\x1e' substring to divide different samples.
Not quite. That call is for isolating the JSON header from the payload. You should use the information in the parsed header to calculate the number of values in the payload. Combined with the fixed size of values when using a binary output format that should also provide you with the position of the header of the next packet, which can then be used as an offset to apply the same logic on it.
In other words: You must actually parse the packets in sequential order.
Quote from Jaime on 25/01/2024, 09:21
As far as I can tell, the strfind [125 10 30] looks for the '}\n\x1e' substring to divide different samples.
Not quite. That call is for isolating the JSON header from the payload. You should use the information in the parsed header to calculate the number of values in the payload. Combined with the fixed size of values when using a binary output format that should also provide you with the position of the header of the next packet, which can then be used as an offset to apply the same logic on it.
In other words: You must actually parse the packets in sequential order.

Quote from Jud123 on 13/03/2025, 16:19Hi,
I'm currently facing a couple of issues while trying to control the Spectran V6 Sweep Zoom block via MATLAB using the HTTP server.
- When I access the configuration page at
http://localhost:54664/remoteconfig
, I've noticed that sometimes the Spectran V6 Sweep Zoom does not appear, and at other times it does. I am uncertain what could be causing this inconsistency.- Additionally, I've encountered another problem: I found that the last two settings, Clean Spurious (CSN) and Enable DC Mask, are not accessible through the server and I cannot change them. Does anyone have insights or solutions regarding these issues?
Thanks!
Hi,
I'm currently facing a couple of issues while trying to control the Spectran V6 Sweep Zoom block via MATLAB using the HTTP server.
- When I access the configuration page at
http://localhost:54664/remoteconfig
, I've noticed that sometimes the Spectran V6 Sweep Zoom does not appear, and at other times it does. I am uncertain what could be causing this inconsistency. - Additionally, I've encountered another problem: I found that the last two settings, Clean Spurious (CSN) and Enable DC Mask, are not accessible through the server and I cannot change them. Does anyone have insights or solutions regarding these issues?
Thanks!

Quote from DevUS on 18/03/2025, 10:39The remoteconfig endpoint is asynchronous. It triggers a request for remote config information to all blocks in the chain, and returns the result of the immediate response combined with the delayed response from the previous request. Information that is older than 15seconds is discarded. A safe option is to request the remoteconfig every e.g. 5 seconds or to fire two requests with a one second delay.
The remoteconfig endpoint is asynchronous. It triggers a request for remote config information to all blocks in the chain, and returns the result of the immediate response combined with the delayed response from the previous request. Information that is older than 15seconds is discarded. A safe option is to request the remoteconfig every e.g. 5 seconds or to fire two requests with a one second delay.