开云体育

ctrl + shift + ? for shortcuts
© 2025 开云体育

Issues with TinySA USB Connection in C#


 

Hi,
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.

I suspect this might be because I need to set the correct parameters during the connection process with TinySA over USB. Unfortunately, I couldn’t find the required parameters in the documentation to properly connect to TinySA using USB.

Could you please let me know the correct way to establish a USB connection with TinySA?

I've tried several methods, and the following setup has been the most stable so far:

?

PortName = "COM3"; ? ? ? ? ?
BaudRate = 115200;

new SerialPortStream(portName, baudRate)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Parity = Parity.None,
? ? ? ? ? ? ? ? StopBits = StopBits.One,
? ? ? ? ? ? ? ? DataBits = 8,
? ? ? ? ? ? ? ? WriteTimeout = 500,
? ? ? ? ? ? ? ? ReadTimeout = 5000,
? ? ? ? ? ? ? ? Handshake = Handshake.DtrRts
? ? ? ? ? ? };?
?
await serialPortStream.WriteAsync(commandBytes, 0, commandBytes.Length);
?

Thanks in advance!


 

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
?


 

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.


 

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.


 

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


 

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.
?


 

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


 

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


 

I have this verion of TinySAUltra
?
tinySA4_v3.1.1-0-g216dfe30
HW Version:V0.4.5.1
?
I created this script which use this Python class for the tinySA Ultra at??.

import
time
import datetime
import TinySAModule

def start_server():
? ?
? ? device = TinySAModule.tinySA()
? ? device.open()
? ? version = device.get_version()
? ? print(version)
? ? run_server(device)

def run_server(device):
? ? i = 0
? ? while True:
? ? ? ? try:
? ? ? ? ? ? i=i+1 ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? freq_data = device.get_freq_data()
? ? ? ? ? ? time.sleep(0.2)

? ? ? ? ? ? data1= device._data(1)
? ? ? ? ? ? time.sleep(0.2)

? ? ? ? ? ? data2= device._data(2)
? ? ? ? ? ? time.sleep(0.2)

? ? ? ? ? ? marker = device.get_marker_value()
? ? ? ? ? ? time.sleep(0.2)
? ? ? ? ? ?
? ? ? ? ? ? timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") ? ? ? ? ? ?
? ? ? ? ? ? print(f"{timestamp}: {i}: {marker} ")
? ? ? ? ? ?
? ? ? ? ?
? ? ? ? except Exception as e:
? ? ? ? ? ? print(f"An error occurred: {e}")
? ? ? ? ? ? device._send_command("reset\r")
? ? ? ? ? ? print(f"reseted")
? ? ? ? ? ? run_server(device) ? ? ? ? ?

if __name__ == "__main__":
? ? start_server()

After few iterations I get this error
2025-01-07 14:44:08: 51: (-56.9, 2412312214.0)?
An error occurred: could not convert string to float: '1 236 2412310036 -5.67e+01'
reseted
An error occurred: Write timeout
Traceback (most recent call last):
? File "C:\Source\TinyPyton\TinySAServer1.py", line 19, in run_server
? ? freq_data = device.get_freq_data()
? File "C:\Source\TinyPyton\TinySAModule.py", line 240, in get_freq_data
? ? return self._fetch_frequencies()
? ? ? ? ? ?~~~~~~~~~~~~~~~~~~~~~~~^^
? File "C:\Source\TinyPyton\TinySAModule.py", line 129, in _fetch_frequencies
? ? x.append(float(line))
? ? ? ? ? ? ?~~~~~^^^^^^
ValueError: could not convert string to float: '1 236 2412310036 -5.67e+01'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
? File "C:\Source\TinyPyton\TinySAServer1.py", line 19, in run_server
? ? freq_data = device.get_freq_data()
? File "C:\Source\TinyPyton\TinySAModule.py", line 240, in get_freq_data
? ? return self._fetch_frequencies()
? ? ? ? ? ?~~~~~~~~~~~~~~~~~~~~~~~^^
? File "C:\Source\TinyPyton\TinySAModule.py", line 124, in _fetch_frequencies
? ? self._send_command("frequencies\r")
? ? ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
? File "C:\Source\TinyPyton\TinySAModule.py", line 81, in _send_command
? ? self.serial.write(cmd.encode())
? ? ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
? File "C:\Users\User\AppData\Local\Programs\Python\Python313\Lib\site-packages\serial\serialwin32.py", line 325, in write
? ? raise SerialTimeoutException('Write timeout')
serial.serialutil.SerialTimeoutException: Write timeout
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
? File "C:\Source\TinyPyton\TinySAServer1.py", line 42, in <module>
? ? start_server()
? ? ~~~~~~~~~~~~^^
? File "C:\Source\TinyPyton\TinySAServer1.py", line 11, in start_server
? ? run_server(device)
? ? ~~~~~~~~~~^^^^^^^^
? File "C:\Source\TinyPyton\TinySAServer1.py", line 39, in run_server
? ? run_server(device)
? ? ~~~~~~~~~~^^^^^^^^
? File "C:\Source\TinyPyton\TinySAServer1.py", line 37, in run_server
? ? device._send_command("reset\r")
? ? ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
? File "C:\Source\TinyPyton\TinySAModule.py", line 83, in _send_command
? ? _ = self.serial.readline() ?# discard empty line
? File "C:\Users\User\AppData\Local\Programs\Python\Python313\Lib\site-packages\serial\serialwin32.py", line 275, in read
? ? raise SerialException("ClearCommError failed ({!r})".format(ctypes.WinError()))
serial.serialutil.SerialException: ClearCommError failed (PermissionError(13, 'The device does not recognize the command.', None, 22))


 

i have the same orre on the latest version of TinySA firmware
tinySA4_v1.4-192-g73fe677
HW Version:V0.4.5.1 ? ? ?
2025-01-07 18:23:07: 1: (-66.8, 97976963.0)?
2025-01-07 18:23:09: 2: (-65.0, 32418392.0)?
2025-01-07 18:23:12: 3: (-65.3, 97881867.0)?
2025-01-07 18:23:14: 4: (-64.8, 98086843.0)?
2025-01-07 18:23:16: 5: (-63.0, 33212113.0)?
2025-01-07 18:23:18: 6: (-63.8, 98083796.0)?
2025-01-07 18:23:20: 7: (-63.5, 34743875.0)?
2025-01-07 18:23:22: 8: (-64.8, 98208663.0)?
2025-01-07 18:23:24: 9: (-63.5, 33492749.0)?
2025-01-07 18:23:27: 10: (-65.0, 32733354.0)?
2025-01-07 18:23:29: 11: (-65.2, 98325254.0)?
2025-01-07 18:23:31: 12: (-70.7, 371754465.0)?
2025-01-07 18:23:33: 13: (-65.2, 98178823.0)?
2025-01-07 18:23:35: 14: (-66.7, 98162583.0)?
2025-01-07 18:23:37: 15: (-63.5, 32824419.0)?
2025-01-07 18:23:40: 16: (-63.0, 33520768.0)?
2025-01-07 18:24:12: 17: (-65.2, 98137148.0)?
An error occurred: could not convert string to float: '1 19 33606812 -6.10e+01'
reseted
An error occurred: Write timeout
Traceback (most recent call last):
? File "C:\Source\TinyPyton\TinySAServer1.py", line 18, in run_server
? ? freq_data = device.get_freq_data()
? File "C:\Source\TinyPyton\TinySAModule.py", line 240, in get_freq_data
? ? return self._fetch_frequencies()
? ? ? ? ? ?~~~~~~~~~~~~~~~~~~~~~~~^^
? File "C:\Source\TinyPyton\TinySAModule.py", line 129, in _fetch_frequencies
? ? x.append(float(line))
? ? ? ? ? ? ?~~~~~^^^^^^
ValueError: could not convert string to float: '1 19 33606812 -6.10e+01'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
? File "C:\Source\TinyPyton\TinySAServer1.py", line 18, in run_server
? ? freq_data = device.get_freq_data()
? File "C:\Source\TinyPyton\TinySAModule.py", line 240, in get_freq_data
? ? return self._fetch_frequencies()
? ? ? ? ? ?~~~~~~~~~~~~~~~~~~~~~~~^^
? File "C:\Source\TinyPyton\TinySAModule.py", line 124, in _fetch_frequencies
? ? self._send_command("frequencies\r")
? ? ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
? File "C:\Source\TinyPyton\TinySAModule.py", line 81, in _send_command
? ? self.serial.write(cmd.encode())
? ? ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
? File "C:\Users\User\AppData\Local\Programs\Python\Python313\Lib\site-packages\serial\serialwin32.py", line 325, in write
? ? raise SerialTimeoutException('Write timeout')
serial.serialutil.SerialTimeoutException: Write timeout
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
? File "C:\Source\TinyPyton\TinySAServer1.py", line 41, in <module>
? ? start_server()
? ? ~~~~~~~~~~~~^^
? File "C:\Source\TinyPyton\TinySAServer1.py", line 11, in start_server
? ? run_server(device)
? ? ~~~~~~~~~~^^^^^^^^
? File "C:\Source\TinyPyton\TinySAServer1.py", line 38, in run_server
? ? run_server(device)
? ? ~~~~~~~~~~^^^^^^^^
? File "C:\Source\TinyPyton\TinySAServer1.py", line 36, in run_server
? ? device._send_command("reset\r")
? ? ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
? File "C:\Source\TinyPyton\TinySAModule.py", line 83, in _send_command
? ? _ = self.serial.readline() ?# discard empty line
? File "C:\Users\User\AppData\Local\Programs\Python\Python313\Lib\site-packages\serial\serialwin32.py", line 275, in read
? ? raise SerialException("ClearCommError failed ({!r})".format(ctypes.WinError()))
serial.serialutil.SerialException: ClearCommError failed (PermissionError(13, 'The device does not recognize the command.', None, 22))


 

I have the same error on this version also
tinySA4_v1.4-99-g8bfcfd7
HW Version:V0.4.5.1 ? ?


 

Anyone that can test which older version does not have this problem?
Just to rule out I introduced a concurrency bug in some release
--
Designer of the tinySA
For more info go to


 

I think i foound version when this error appeared.
?
I see exception on this version and newer.
tinySA4_v1.3-438-gd7f97cd
HW Version:167
2025-01-09 14:26:29: 843: (-50.75, 30159987.0)?
An error occurred: could not convert string to float: '1 17 30974320 -50.75'
reseted
?
And on this version it work stable more then 1500 iterations and keep working.
tinySA4_v1.3-435-g391dca6
HW Version:167


 

Many, many thanks
This is exactly when a change was made to a part of the code that uses multiple threads.
I will need some time investigate this.
--
Designer of the tinySA
For more info go to


 

On Thu, Jan 9, 2025 at 05:23 AM, <voloshyn.v.v@...> wrote:
I see exception on this version and newer.
tinySA4_v1.3-438-gd7f97cd
HW Version:167
2025-01-09 14:26:29: 843: (-50.75, 30159987.0)?
An error occurred: could not convert string to float: '1 17 30974320 -50.75'
reseted
?
?
I did some testing over the past day and suspect that in the tight loop that you are running, without doing anything with the amplitude or frequency data, the console 'frequency' and 'data' commands eventually cannot keep up with the data flow and are causing the USB port to lock-up until the tinySA is rebooted.
?
I am not receiving any errors other than, " The operation has timed out", after a variable number of iterations occurring in either the "frequencies", "data 1" or "data 2" console commands.?
?
When only querying the "marker 1" console command in a tight loop I did not receive any time out errors over the course of 6hrs and over 22,000 iterations:
?
Read Marker Value Only
2025-01-09 06:01:10: 1: (-38.8, 105072304)
2025-01-09 06:01:11: 2: (-38.8, 105039346)
2025-01-09 06:01:11: 3: (-38.8, 105038222)
2025-01-09 06:01:12: 4: (-39.3, 105043709)
2025-01-09 06:01:13: 5: (-39.8, 105063102)
2025-01-09 06:01:13: 6: (-39.8, 105038222)
2025-01-09 06:01:14: 7: (-39.8, 105038222)
2025-01-09 06:01:15: 8: (-40.3, 105038222)
..........
2025-01-09 09:58:55: 22107: (-40.3, 105031589)
2025-01-09 09:58:56: 22108: (-40.3, 105059756)
2025-01-09 09:58:57: 22109: (-40.3, 105053965)
2025-01-09 09:58:57: 22110: (-40.3, 105031589)
2025-01-09 09:58:58: 22111: (-40.8, 105031589)
2025-01-09 09:58:59: 22112: (-40.3, 105040357)
2025-01-09 09:58:59: 22113: (-40.3, 105052993)
?
If instead of constantly querying "frequencies", I queried "sweep" and used the returned start, stop and points values to create a frequency array using a "LinSpace" like function, then I did not receive any time out errors over the course of 2hrs and over 5,500 iterations:
?
Read Marker and LinSpace Frequency array Values?
2025-01-09 12:07:55: 1: (-42.8, 105102399)
2025-01-09 12:07:56: 2: (-42.8, 105109582)
2025-01-09 12:07:58: 3: (-42.8, 105073001)
2025-01-09 12:07:59: 4: (-42.8, 105095900)
2025-01-09 12:08:00: 5: (-42.8, 105064811)
2025-01-09 12:08:01: 6: (-42.8, 105076975)
2025-01-09 12:08:03: 7: (-42.8, 105059756)
2025-01-09 12:08:04: 8: (-42.3, 105080071)
2025-01-09 12:08:05: 9: (-42.3, 105053965)
..........
2025-01-09 14:06:10: 5497: (-39.8, 105056503)
2025-01-09 14:06:12: 5498: (-39.8, 105055678)
2025-01-09 14:06:13: 5499: (-39.8, 105082261)
2025-01-09 14:06:14: 5500: (-39.8, 105080641)
2025-01-09 14:06:16: 5501: (-40.3, 105053075)
2025-01-09 14:06:17: 5502: (-39.8, 105104557)
2025-01-09 14:06:18: 5503: (-39.8, 105104557)
?
The "data 1" console command is a holdover from its NanoVNA origins and not of particular use.? The "data 2" console command returns the current trace data but in a tight loop the scanraw command is preferred.? QtTinySA uses the scanraw command to provide a fast and responsive graphical display of trace data.
?
If instead of constantly querying "data 1", I rather queried "scanraw", then I did not receive any time out errors over the course of 4hrs and over 5,600 iterations:
?
Read Marker, LinSpace Frequency array, and Scanraw Values?
2025-01-09 15:02:08: 1: (-38.3, 105035153)
2025-01-09 15:02:11: 2: (-37.3, 105023508)
2025-01-09 15:02:13: 3: (-37.8, 105023508)
2025-01-09 15:02:16: 4: (-38.3, 105013851)
2025-01-09 15:02:18: 5: (-40.2, 105084851)
2025-01-09 15:02:21: 6: (-40.2, 105067951)
2025-01-09 15:02:23: 7: (-40.2, 105067951)
2025-01-09 15:02:26: 8: (-40.3, 105019701)
..........
2025-01-09 19:02:30: 5657: (-38.3, 105005274)
2025-01-09 19:02:32: 5658: (-38.8, 105010397)
2025-01-09 19:02:35: 5659: (-38.3, 105010397)
2025-01-09 19:02:37: 5660: (-38.8, 105011863)
2025-01-09 19:02:40: 5661: (-38.3, 105011863)
2025-01-09 19:02:42: 5662: (-38.3, 105011863)
2025-01-09 19:02:45: 5663: (-38.3, 104978805)
?
Erik has indicated there may be some improvements he can make in the firmware, but I suspect that the way you are using the "frequencies" and "data" console commands in a tight loop that you will still experience some flow control related USB lockup issues when operating over an extended length of time.
?
For the best performance I suggest:
?
1. Create your frequency array in code using "sweep" and LinSpace.
2. Use "scanraw" instead of "data" console command.
3. Verify that your computer does not remove power to your USB ports to save energy.
?
I only program for my own pleasure so hopefully Erik or someone else more knowledgeable than me will correct any errors in my post.
?
Herb


 

On Thu, Jan 9, 2025 at 09:00 PM, hwalker wrote:
?

Well, this is definitely an error that appeared after
tinySA4_v1.3-435-g391dca6
HW Version: 167.

I started the Python script I provided yesterday, and it has been running continuously. Now, I see that more than 29,000 iterations have been executed successfully.


 

On Thu, Jan 9, 2025 at 10:01 PM, <voloshyn.v.v@...> wrote:
I started the Python script I provided yesterday, and it has been running continuously. Now, I see that more than 29,000 iterations have been executed successfully.
I knew Python's serial port driver was better than the one for C# but I didn't realize it was so much faster.? I have been running a C# script using the current firmware and the suggestions I made yesterday since 11:30 pm last night and in 6 hours I've only gotten to 8,000 iterations.? I'm better at C# but may have to consider using Python as a primary programming language for instrument control.?
?
Instrument Manufacturer ... ?2019-2024 Copyright @Erik Kaashoek
Instrument Name ........... ?tinySA ULTRA
Instrument Firmware Version ... tinySA4_v1.4-177-g1687fbc
Instrument Battery Voltage ... 4.256 Vdc
?
2025-01-09 23:23:06: 1: (-43.7, 105000720)
2025-01-09 23:23:09: 2: (-44.7, 105006293)
2025-01-09 23:23:12: 3: (-42.7, 105023508)
2025-01-09 23:23:14: 4: (-42.7, 105099651)
2025-01-09 23:23:17: 5: (-41.7, 105122494)
2025-01-09 23:23:20: 6: (-41.2, 105116515)
...........
2025-01-10 05:31:37: 8004: (-46.3, 105079387)
2025-01-10 05:31:40: 8005: (-45.8, 105129399)
2025-01-10 05:31:43: 8006: (-46.3, 105174031)
2025-01-10 05:31:46: 8007: (-45.8, 105060340)
2025-01-10 05:31:48: 8008: (-46.3, 105230012)
2025-01-10 05:31:51: 8009: (-46.3, 105040357)
?
Herb


 

Could you please advise how to use "scanraw" instead of "data" console command in this case.
Thx in advance.


 

See wiki
?
--
Designer of the tinySA
For more info go to


 

On Fri, Jan 10, 2025 at 05:45 AM, <voloshyn.v.v@...> wrote:
Could you please advise how to use "scanraw" instead of "data" console command in this case.
In addition to Erik's Wiki reference, here is an example of a function pulled from a web search:
?
def get_tinysa_scanraw(f_low, f_high, N_points):
? ? ser.timeout = 100
? ? ser.flushInput()
? ? ser.flushOutput()
? ? ser.flush()
? ? ser.read_all()
? ? scan_command = "scanraw"+" "+str(int(f_low))+" "+str(int(f_high))+" "+str(int(N_points))
? ? result = ""
? ? data = ""
? ? ser.write(str(scan_command + "\r").encode('ascii')) ?
? ? sleep(0.05)
? ? ser.readline()
? ? ser.readline()
? ? bin_data = ser.read_until(b"}ch> ")
? ? read_data = unpack('cBB'*N_points,bin_data[1:-5])
? ? m_power = np.zeros(N_points, dtype=np.float64)
? ? for i in range(N_points):
? ? ? ? m_power[i] = (read_data[i*3+1] + read_data[i*3+2]*256)/32-174
? ? return m_power
?
?
Please note this is for the tinySA Ultra.? The tinySA uses a scaling offset of 128 instead of 174.? Also, I have not tested the code, but the math looks OK to me.
?
Herb