Re: Issues with TinySA USB Connection in C#
Can one of you check if old FW version has the same problem?
And if not, at what FW release this problem started?
--
Designer of the tinySA For more info go to
|
Re: Issues with TinySA USB Connection in C#
On Mon, Jan 6, 2025 at 08:36 AM, <voloshyn.v.v@...> wrote:
I tried to implement the same behavior using this Python script: . I created a small script and ran it, but it stopped working after a few hundred operation.
That's surprising.? Python's serial port driver is much better implemented than the one for C#.? Both NanoVNASaver and QtTinySA are robust applications using Python and I have not heard of similar problems using them for long term operations.
?
Try this Python class for the tinySA Ultra at .
It appears well written with additional delays for read and write operations, and is based on the NanoVNASaver serial port script.?
?
Herb
|
Re: Issues with TinySA USB Connection in C#
I tried to implement the same behavior using this Python script: . I created a small script and ran it, but it stopped working after a few hundred operation.?
?
import time
import TinySAModule
def start_server():
? ?
? ? nv = TinySAModule.tinySA()
? ? print("Connecting to TinySA...")
? ?
? ? i = 0
? ? try:
? ? ? ? while True:
? ? ? ? ? ? i=i+1
? ? ? ? ? ? print(i)
? ? ? ? ? ?
? ? ? ? ? ? nv.send_command("frequencies\r")
? ? ? ? ? ? frequencies = nv.fetch_data() ?
? ? ? ? ? ? time.sleep(0.2)
? ? ? ? ? ? nv.send_command("data 1\r")
? ? ? ? ? ? data1 = nv.fetch_data()
? ? ? ? ? ? time.sleep(0.2)
? ? ? ? ? ? nv.send_command("data 2\r")
? ? ? ? ? ? data2 = nv.fetch_data()
? ? ? ? ? ? time.sleep(0.2)
? ? ? ? ? ? nv.send_command("marker 1\r")
? ? ? ? ? ? marker = nv.fetch_data()
? ? ? ? ? ? time.sleep(0.2)
? ? ? ? ?
? ? ? ? ? ? packet = f"{frequencies},{data1},{data2},{marker}\n" ? ? ? ? ? ? ? ? ?
? ? except KeyboardInterrupt:
? ? ? ? print("Server stopped.")
? ? except Exception as e:
? ? ? ? print(f"An error occurred: {e}")
? ? finally: ? ? ?
? ? ? ? nv.disconnect()
? ? ? ? nv.close()
? ? ? ?
if __name__ == "__main__":
? ? start_server()
?
It looks strange because when I send only the 'marker 1' command from the C# program, it worked for a few days without stopping.
?
|
Re: Mesure IMD with Two Tone and TinySA Ultra
Hi:
?
As noted elsewhere, you'll need more attenuation in a form that can handle the power. I usually start my test chain with a 50db 100 watt attenuator and then add others as needed.
?
The neat built in function in the TinySA is really useful, but most amateur (and commercial) radio specifications for IMD are described in terms of the individual distortion components and how far below the "carrier" level they are in "dbc" the worst ones are - you may still need to examine the spectrum manually to determine the numbers you want.
?
The ARRL has a document describing how they conduct these measurements in their review labs and this is the usual way of arriving at the numbers used in their IMD measurements. It's important to set up the levels correctly for the tests.
?
?
I also have a number of short videos about doing this with other equipment (since the time the original TinySA lacked the resolution for doing this using the ARRL specs), but they might still be of some help in understanding the overall process.
?
?
hopefully this is not confusing the issue...
?
M
?
?
|
Re: Screen replacement for TinySA Ultra
Okay, again, thanks for the support.
|
Re: Screen replacement for TinySA Ultra
This version uses BOE's IPS LCD. We do not sell this LCD externally yet. Please contact your supplier for support.
|
Re: Screen replacement for TinySA Ultra
Thanks for the reply. The HW version is v0.4.5.1.1.
|
Re: Screen replacement for TinySA Ultra
Please let me know your hardware version or contact your supplier for a replacement.
|
Re: Issues with TinySA USB Connection in C#
On Sun, Jan 5, 2025 at 04:18 AM, <voloshyn.v.v@...> wrote:
The Issue: After running this loop for a few thousand iterations, the program stops receiving data and only returns timeout exceptions.
AI suggested the following:
?
1. **Concurrency Issue**: In the `Loop` method, `UsbService.SendCommandAsync("data 1")` and `UsbService.SendCommandAsync("data 2")` are called without awaiting them. This can lead to concurrency issues if these methods depend on shared resources. You should await these calls if you need their results before proceeding.
?
2. **Potential Deadlock**: The `Loop` method is an `async void` method, which is generally discouraged because it can lead to unhandled exceptions and is difficult to test. It should be changed to `async Task` if possible.
?
I tried your code after making the above suggestions but received the same results as you after 1046 iterations:
?
1035: 1 59 105081195 -4.43e+01 1036: 1 59 105110615 -4.43e+01 1037: 1 59 105067198 -4.48e+01 1038: 1 59 105085882 -4.43e+01 1039: 1 59 105086859 -4.43e+01 1040: 1 59 105088229 -4.48e+01 1041: 1 59 105088229 -4.48e+01 1042: 1 59 105062300 -4.48e+01 1043: 1 59 105085374 -4.48e+01 1044: 1 59 105074980 -4.48e+01 1045: 1 59 105085882 -4.53e+01 1046: 1 59 105104794 -4.48e+01 Error: Read operation timed out. Error: Read operation timed out. Error: Read operation timed out. Error: Read operation timed out. Error: Read operation timed out. Error: Read operation timed out.?
------------------------------------------------------------------------------
using?RJCP.IO.Ports; void?Main() { ????Loop().Wait();?//?Ensure?the?loop?is?awaited }
//?Assuming?these?are?defined?elsewhere string?PortName?=?"COM5"; int?BaudRate?=?9600; SemaphoreSlim?_sendCommandSemaphore?=?new?SemaphoreSlim(1,?1); bool?_isRunning?=?true; ILogger?Logger?=?new?ConsoleLogger();?//?Example?logger?implementation
SerialPortStream?CreateSerialPort(string?portName,?int?baudRate) { ????return?new?SerialPortStream(portName,?baudRate) ????{ ????????Parity?=?Parity.None, ????????StopBits?=?StopBits.One, ????????DataBits?=?8, ????????WriteTimeout?=?500, ????????//ReadTimeout?=?10000, ????????ReadTimeout?=?50000, ????????Handshake?=?Handshake.None ????}; }
public?async?Task<string>?SendCommandAsync(string?command) { ????await?_sendCommandSemaphore.WaitAsync(); ????try ????{ ????????using?(var?serialPortStream?=?CreateSerialPort(PortName,?BaudRate)) ????????{ ????????????if?(!serialPortStream.IsOpen) ????????????{ ????????????????serialPortStream.Open(); ????????????} ???????????? ????????????command?+=?"\r"; ????????????byte[]?commandBytes?=?Encoding.ASCII.GetBytes(command);???????????????????? ???????? ????????????serialPortStream.Write(commandBytes,?0,?commandBytes.Length); ????????????string?echoResponse?=?ReadUntil(serialPortStream,?"\r"); ???????????? ????????????if?(echoResponse.Trim()?==?command.Trim()) ????????????{???????????????????? ????????????????string?data?=?ReadUntil(serialPortStream,?"ch>"); ????????????????data?=?data.TrimEnd("\r\nch>".ToCharArray()); ????????????????return?data; ????????????} ????????????else ????????????{ ????????????????string?errorStr?=?$"Unexpected?echo?response:?{echoResponse}"; ????????????????Logger.Log(errorStr); ????????????????throw?new?InvalidOperationException(errorStr);?//?Throw?an?exception?for?unexpected?response ????????????}???????????????????? ????????} ????} ????finally ????{ ????????_sendCommandSemaphore.Release(); ????} }
private?string?ReadUntil(SerialPortStream?serialPort,?string?terminator) { ????byte[]?buffer?=?new?byte[1];???????????? ????StringBuilder?responseBuilder?=?new?StringBuilder(); ????while?(true) ????{ ????????int?bytesRead?=?serialPort.Read(buffer,?0,?buffer.Length); ????????if?(bytesRead?>?0) ????????{ ????????????char?currentChar?=?(char)buffer[0]; ????????????responseBuilder.Append(currentChar); ????????????if?(responseBuilder.Length?>=?terminator.Length?&&? ????????????????responseBuilder.ToString().EndsWith(terminator)) ????????????{???????????????????????? ????????????????return?responseBuilder.ToString(); ????????????} ????????} ????????else ????????{ ????????????throw?new?TimeoutException("Read?operation?timed?out."); ????????} ????} }
private?async?Task?Loop() { ????while?(_isRunning) ????{???????????????? ????????try ????????{ ????????????var?frequenciesString?=?await?SendCommandAsync("frequencies"); ????????????var?dataList1?=?await?SendCommandAsync("data?1"); ????????????var?dataList2?=?await?SendCommandAsync("data?2"); ????????????var?marker?=?await?SendCommandAsync("marker?1"); ???????????? ????????????//Console.WriteLine(frequenciesString); ????????????//Console.WriteLine(dataList2); ????????????Console.WriteLine(marker); ???????????? ????????} ????????catch?(Exception?ex) ????????{ ????????????Logger.Log($"Error:?{ex.Message}"); ????????} ???????? ????????await?Task.Delay(500);? ????} }
//?Example?logger?implementation public?interface?ILogger { ????void?Log(string?message); }
public?class?ConsoleLogger?:?ILogger { ????public?void?Log(string?message) ????{ ????????Console.WriteLine(message); ????} }
------------------------------------------------------------------------------
?
If I come across any additional information I will post it here.
Herb
|
Re: ultra+ trigger options
Thanks for the answer.
?
Was hoping to leave the sa some distance and be alarmed by a beep when it captured something.?
Will try if the output can drive a small piezo speaker.
?
I did notice the 'armed' status message. It might be my logic, but since you have to manually re-arm the single trigger I sort of expected the screen to be cleared to the state at the moment you re-arm it. I work around it by briefly enabling 'auto' so no point, I was just curious if I misunderstood something.
( again, with the sa some distance I can visually determine of something new has been captured this way )
?
regards,
?
Henk
?
?
|
Re: ultra+ trigger options
On Sun, Jan 5, 2025 at 04:28 AM, pa3cqn wrote:
Beep seems to not beep, or do you have to use headphones? Or is this for 407 hardware?
?
Use headphone output
?
-interval blocks the UI, jogwheel as well as screen. You have to press for at least T-interval and release to get the menu to appear, and another T-interval to get to the interval input screen.
?
Let me check
?
-re-arming single does not clear the screen. Might be intentional though.
?
Indeed intentional
Left status panel shows ARMED after rearming
?
?
--
Designer of the tinySA For more info go to
|
Screen replacement for TinySA Ultra
I scratched the screen of my TinySA Ultra, and I want to buy a new screen to replace it. However, I don't know which model to buy. Anyone knows?
|
==
ZS406, oct 21 firmware
==
?
This firmware's trigger menu has some more options than explained in the wiki: beep, interval and autosave.
?
-Beep seems to not beep, or do you have to use headphones? Or is this for 407 hardware?
-interval blocks the UI, jogwheel as well as screen. You have to press for at least T-interval and release to get the menu to appear, and another T-interval to get to the interval input screen.
-re-arming single does not clear the screen. Might be intentional though.
?
Could not find any mentioning of this in the changelog other than that thes options were implemented.
?
Anyone have thoghts on this?
?
Regards?
?
Henk
|
Re: Mesure IMD with Two Tone and TinySA Ultra
Use 30 dB extra attenuation between the -40 dB sniffer and the tinySA input
Set LEVEL/EXT GAIN to -70 dB
Use the MEASURE/OIP3 and enter the two test frequencies (in case of USB: 14245700 Hz and 14246900 Hz, do not use the decimal dot when entering frequencies)
and set the span to 25 kHz
?
?
--
Designer of the tinySA For more info go to
|
Re: Issues with TinySA USB Connection in C#
Let me provide more details about my setup.
I have a USBService class that manages communication with a device using a serial connection. Here’s how I create the USB connection:
SerialPortStream CreateSerialPort(string portName, int baudRate) { ? ? return new SerialPortStream(portName, baudRate) ? ? { ? ? ? ? Parity = Parity.None, ? ? ? ? StopBits = StopBits.One, ? ? ? ? DataBits = 8, ? ? ? ? WriteTimeout = 500, ? ? ? ? ReadTimeout = 10000, ? ? ? ? Handshake = Handshake.None ? ? }; }
To send and receive commands, I use the following method:
public async Task<string> SendCommandAsync(string command) { ? ? await _sendCommandSemaphore.WaitAsync(); ? ? try ? ? { ? ? ? ? using (var serialPortStream = CreateSerialPort(PortName, BaudRate)) ? ? ? ? { ? ? ? ? ? ? if (!serialPortStream.IsOpen) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? serialPortStream.Open(); ? ? ? ? ? ? } ? ? ? ? ? ?? ? ? ? ? ? ? command += "\r"; ? ? ? ? ? ? byte[] commandBytes = Encoding.ASCII.GetBytes(command); ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? serialPortStream.Write(commandBytes, 0, commandBytes.Length); ? ? ? ? ? ? string echoResponse = ReadUntil(serialPortStream, "\r"); ? ? ? ? ? ?? ? ? ? ? ? ? if (echoResponse.Trim() == command.Trim()) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? string data = ReadUntil(serialPortStream, "ch>"); ? ? ? ? ? ? ? ? data = data.TrimEnd("\r\nch>".ToCharArray()); ? ? ? ? ? ? ? ? return data; ? ? ? ? ? ? } ? ? ? ? ? ? else ? ? ? ? ? ? { ? ? ? ? ? ? ? ? string errorStr = $"Unexpected echo response: {echoResponse}"; ? ? ? ? ? ? ? ? Logger.Log(errorStr); ? ? ? ? ? ? ? ? return errorStr; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? } ? ? finally ? ? { ? ? ? ? _sendCommandSemaphore.Release(); ? ? } }
?
Here’s the ReadUntil method used for reading data:
private string ReadUntil(SerialPortStream serialPort, string terminator) { ? ? byte[] buffer = new byte[1]; ? ? ? ? ? ? ? ? ? ? StringBuilder responseBuilder = new StringBuilder(); ? ? while (true) ? ? { ? ? ? ? int bytesRead = serialPort.Read(buffer, 0, buffer.Length); ? ? ? ? if (bytesRead > 0) ? ? ? ? { ? ? ? ? ? ? char currentChar = (char)buffer[0]; ? ? ? ? ? ? responseBuilder.Append(currentChar); ? ? ? ? ? ? if (responseBuilder.ToString().EndsWith(terminator)) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return responseBuilder.ToString(); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? else ? ? ? ? { ? ? ? ? ? ? throw new TimeoutException("Read operation timed out."); ? ? ? ? } ? ? } }
In my application, I run the following loop to receive data continuously:
private async void Loop() { ? ? while (_isRunning) ? ? { ? ? ? ? ? ? ? ? ? ? ? ? try ? ? ? ? { ? ? ? ? ? ? var frequenciesString = await UsbService.SendCommandAsync("frequencies"); ? ? ? ? ? ? var dataList1 = UsbService.SendCommandAsync("data 1"); ? ? ? ? ? ? var dataList2 = UsbService.SendCommandAsync("data 2"); ? ? ? ? ? ? var marker = await UsbService.SendCommandAsync("marker 1"); ? ? ? ? } ? ? ? ? catch (Exception ex) ? ? ? ? { ? ? ? ? ? ? Logger.Log($"Error: {ex.Message}"); ? ? ? ? } ? ? ? ?? ? ? ? ? await Task.Delay(500);? ? ? } }
The Issue: After running this loop for a few thousand iterations, the program stops receiving data and only returns timeout exceptions.
|
Re: Mesure IMD with Two Tone and TinySA Ultra
Firstly, 100 watts is 50 dBm, so the output power after your attenuator (50dBm - 40dB = 10dBm) will exceed the permitted 6 dBm for the TinySA. Although I would highly recommend not to exceed 0dBm at the input, for all signals including harmonics.
|
Mesure IMD with Two Tone and TinySA Ultra
Hi Group, I'm an Ham Radio operator and I need to mesure the IMD for the modulation in SSB. I just built a two tone generator so I can inject 700hz and 1900hz at the same time to mesure the IMD but, I'm at my first steps with RF electonics and the TinySA Ultra. Does anybody can take me by the hand and tell my what setting I need to do with the TinySa Ultra in order to mesure the IMD.? Let's say for the test that I will? transmit at 14.245Mhz USB 100Watts in a dummy load. I built a RF sampler 40db attenuator so I can feed the TinySa without blowing it.? thanks? ?73 from VE2IBN (Canada).
|
Re: How to test and measure THD with Ultra?
|
Re: Issues with TinySA USB Connection in C#
Two quick things you can try.? Firstly Handshake should be None.? Secondly try a Linux machine (real, not a VM).? Admittedly it has been many years since I used Windows but for serial comms it used to be flaky giving the same kind of issue you describe.
?
Assuming those two suggestion don't help then in getting to the bottom of it the first place to start is what is the minimum you have to do restore operation?? Can you resume comms just by restarting you program, disconnect the USB connection, or do you have to power cycle either the PC or TinySA?
?
Often the key to robust serial comms is in how you handle timeouts, but I have never had problems writing to a device, like your WriteAsync() call, so I do wonder if your serial driver is stalling from waiting on the non-existent hardware transmission handshaking you are requesting.
|
Re: Issues with TinySA USB Connection in C#
On Sat, Jan 4, 2025 at 05:28 AM, <voloshyn.v.v@...> wrote:
I'm writing a C# program to receive data from TinySA and analyze it.
I need to retrieve data from these three commands every second:
frequencies
data 1
data 2
The issue is that, from time to time, TinySA does not return data over USB. After this happens, it stops responding to any commands I send over USB.
Check the following:
1. The command is terminated with "\r" (i.e. "frequencies \r").
2. After a write command, the command is echo'd and you have to handle this properly before reading the data.
3. The data is terminated with a 'ch>' prompt which also has to be handled properly.
?
See Erik's tinySA python class for an example of proper read/write functions.
?
Herb
?
|