HL2 receive power levels, additional questions on debugging HL2/SDR receive code

194 views
Skip to first unread message

Roger David Powers

unread,
Jan 28, 2022, 10:27:05 PM1/28/22
to Hermes-Lite
Hi,

First question is based on what I read about HackRF One:

What is the Receive Power of HackRF?
The maximum RX power of HackRF One is -5 dBm. 

Source: https://hackrf.readthedocs.io/en/latest/faq.html 

Does anyone have a similar (ballpark) figure for the HL2 input?

I ask because I am debugging some code that streams data from HL2 based on the rx4000.py code that's been mentioned a few times here, and the data does not look like what I expect it to look like after I run it through a FFT and then draw a waterfall (heatmap) of the FFT'd data.  My changes to rx4000.py are to support one to four receivers at a time.  I had this code written for a while but decided I should QA it before before I release it, and I ran into problems that I can really use some help with.  I've never debugged SDR code before so I don't know any of the tricks of the trade.

So, my newbie thought process was to try to generate a "test pattern" by using a second SDR (another HL2 or a HackRF One) to generate some data in a known pattern, send it to the second radio (HL2), use my HL2 code to stream the data and print out various bits of it to see if it matches that known "test pattern".  I was thinking I'd just transmit it over the air, but then I realized I'd want to test the whole passband of the HL2 so that'd be a broader signal than I should be transmitting so I'd want to directly cable the two to each other with suitable attenuation inline.  To do that, I'd need to know how much attenuation to use, thus my question about acceptable RX power levels.

My thought process was if I used gnuradio on the first SDR to generate a (sine wave) carrier in the HL2's 0.5-30 MHz range, then used a mixer block to mix in another sine wave or a ramp or sawtooth (some pattern I hope I could recognize in the data) that would be a large percent of the passband (lets say 40 kHz with sample rate set to 48 kHz?) then put that through a lowpass filter to get rid of harmonics then sent it to the HL2 or osmocom sink to send it, I'd have my "test pattern". 

On the RX side I could set the receiver to the same carrier frequency and start steaming.  Then I could use wireshark to look at the IQ values on the RX ethernet, compare to what I can print out from the copy in my program's memory, see if they agree or not, and if not, see if there is any pattern to the difference between what I see in wireshark vs what I see using my own program.  I've done this already with a (legal) carrier over the air to the HL2 and looked at data in program memory vs wireshark and the problem was I didn't have a good pattern to look for.

Sorry if my explanation isn't clear enough.  My main idea is to get my code (FFT and heatmap) out of the loop since it is not confirmed to be working.  If I can verify the data on the ethernet is good then I can look more at the FFT and waterfall, otherwise I back track more towards the radio   I'm just looking for a way to do this, and this is what I have come up with so far, given that I am relatively new to SDR.  If there are better ways to go about this, I'd love to know!

To be honest, I have some grounds to think the radio side is not streaming what I expect it to be streaming.  I think this because I watched what gnuradio's gr-hermeslite code does by using wireshark.  I noticed that when they send the "SDR configuration" command (C0=0) to the HL2 they turn on the duplex bit (0x4 in C4) whereas rx4000.py does not.  When I also set the duplex bit in my code, all the data looks like what I expect.  The problem is when I do this, the packet loss rate goes very high, something like 65% of the packets get dropped, whereas without duplex the packet drop rate is zero for the same one receiver case. 

I'm not exactly sure what duplex does.  It seems it means it expects my program to be streaming mic audio and commands to the HL2, but I am not doing that.  I'm not sure if the high packet loss rate is because it is not seeing my mic audio stream which messes up the HL2 or for some other reason.  I know it is dropping packets because I implemented sequence number tracking.

Another observation is without duplex set if I use two receivers both streams have the data I expect, whereas with one receiver the data does not look like what I expect, and with three receivers #1 and #2 have good data but #3 does not, and with four receivers all four are good.  When I say "like I expect" or "good" I mean my waterfall shows exactly what I sent, which is a carrier at 10 kHz above the frequency tuned by both transmitter and all N receivers.   

So, the test pattern thing is to try to quantify what i see different when I'm not getting the data that I want.  One thing the waterfall often shows is when it is not working (i.e. duplex is not set) the data above the center frequency and below the center frequency are mirror images.  My reading tells me one way this happens when all the data is real and is put into the complex domain, the negative frequencies are just mirrors of the positive frequencies.

For those of you who got this far, TYVM for reading!

Regards,
RDP







Josh Logan

unread,
Jan 29, 2022, 2:36:35 AM1/29/22
to Roger David Powers, Hermes-Lite

Here is a link to testing the board with an attenuator from the wiki.

Connect the attenuator with loopback cable as seen in the picture above. The attenuator is a common 2W 50Ohm DC-6GHz 30dB inline SMA coaxial attenuator. The one I used is marked as SMA-JK6G-30dB. Two sources for acceptable attenuators are here and here. It is important to use a 30dB attenuator.

I don't know is this is with the PA on or off, but maybe you can look at the raspberry pi flashing code and tell.



73, KD7HGL
Josh


--
You received this message because you are subscribed to the Google Groups "Hermes-Lite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hermes-lite...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/hermes-lite/927344037.3793776.1643426785380%40mail.yahoo.com.

Alan Hopper

unread,
Jan 29, 2022, 4:23:12 AM1/29/22
to Hermes-Lite
Hi RDP,
it might be simpler to use my emulator  ahopper/Patroclus: Software defined radio emulator (github.com) the Avalonia version will work on windows, mac and linux.
73 Alan M0NNB

Roger David Powers

unread,
Jan 29, 2022, 12:03:58 PM1/29/22
to Josh Logan, Hermes-Lite
Thanks, Josh!  That page is a good resource.  Someone else recently mentioned the hl2setup code in our github repo.  I will go through all that content in the very near future.

Regards,
RDP

Roger David Powers

unread,
Jan 29, 2022, 12:25:06 PM1/29/22
to Hermes-Lite, Alan Hopper
Hi, Alan!

Thanks for pointing your emulator out, I did not know it existed!

I will start going through it now, but before I do, since you know enough to write the emulator, I'm hoping you might be able to address some questions that may help me and/or others trying to work in this space.

And of course I'd be glad if any other knowledgeable reader can add what they know.

Can you explain the difference between duplex on and duplex off, what changes in behavior should I expect to see?

Would you expect turning duplex off or off would change the data being streamed from the SDR to the PC?  I think that is what I am observing, but I could be mistaken.  

Does your emulator emulate both duplex on and duplex off?

Has the use case of duplex off with 1/2/3/4 receive slices active been exercised much?

I think the main idea for duplex off is for a receive-only device to not have to generate packets from the PC to the SDR when there is no intention to transmit audio.  Since I'm using raspberry pi, eliminating this stream is important to get the desired level of performance.

I see from observing gr-hermeslite that apps that send transmit audio from PC to SDR turn duplex on and send commands in the "usb header" of the two usb frames packed into the udp frames. 

In the case of the receive-only code presented in rx4000.py it puts commands into the "0xef 0xfe 0x05 <0x7f C0 C1 C2 C3 C4>" metis udp header that I believe is a relatively recent addition to the HL2 firmware.

Does the emulator know about this packet format?

How would one get the same effect (streaming of packets from SDR to PC with no back flow of packets from PC to SDR) without using this packet format?

Is there an example of another app that uses duplex off that I could observe using wireshark?  Especially one supporting more than 1 receiver would be helpful.

Sorry for so many questions, please indulge me as much as your patience allows, I think others may benefit from the discussion as well.

Regards,
RDP



Roger Critchlow

unread,
Jan 29, 2022, 1:57:49 PM1/29/22
to Roger David Powers, Hermes-Lite
Hi Roger --

I can answer some of this.   

The protocol spec is described at https://github.com/softerhardware/Hermes-Lite2/wiki/Protocol, you should read the USB_protocol_V and Metis documents linked in the first paragraph.  Then read the rest of the article explains the HL2 specific additions and interpretations of the base protocols.

After the discovery phase, and the commands which start, stop, set number of receivers, and sample rate, which are all fairly transparent, comes the sample streaming phase.

The code for controlling the HL2 is hard to read in any language because it is continuously sending transmit packets and continuously handling receive packets.  The HL2 is controlled through headers in transmit packets.  The HL2 communicates back through headers in the receive packets.   The interaction between the two streams gets really hairy when sending i2c commands and waiting for acknowledgement.

The HL2 shuts down if enough transmit packets don't arrive, it assumes it is out of control and returns to the stopped state.

The receive packets continue to deliver the specified number of receivers at the specified sample rate until the radio is stopped.  If you want to reduce the cpu load on your rpi, then reduce the number of receivers and/or reduce the sample rate.  I believe you can run with 0 receivers if you like.  

The time required to stop and restart the HL2 with a different number of receivers is pretty quick, so you might be able to roll your own receiver mute that way.

I believe that duplex is simply switching the cable modem chip between simplex and duplex modes.  The receiver samples will all be zero during transmit if you operate simplex, but they will continue arriving at the rate required for the specified number of receivers and sample rate, which could be a lot of zeros.

Using the USB_protocol_V document and the Metis document and the wiki page, you can compute exactly the volume of UDP receive packets your rpi can expect for any combination of number of receivers and sample rate.

 I could be out of date, it's been several years, but I don't see any hints of change as drastic as you want.

The idea that duplex=0 should mute the receiver samples is interesting, except that it would break all the existing HL2 software.  It would be thrown into a panic when the receiver stopped sending samples at the rate specified by the protocols.  Lots of code uses the number of received packets to time the sending of transmit packets.

-- 73 -- rec -- ad5dz --


--
You received this message because you are subscribed to the Google Groups "Hermes-Lite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hermes-lite...@googlegroups.com.

ron.ni...@gmail.com

unread,
Jan 29, 2022, 3:36:10 PM1/29/22
to Hermes-Lite
To safely test HL2 broadband transmit and receive, I've found that the HL2 receive capability is good enough that I can connect both HL2's to 2 different 50 Ohm dummy loads that are near each other, and receive on one HL2 what I transmit on the other.  For weaker signal testing I move the 2 dummy loads farther apart and use lower maximum amplitude samples (down to a fraction of 1 bit, dithered).

UDP traffic to/from the HL2 has to go in both directions to reliably get past my network router and WiFi firewalls.  So I always use HL2 duplex from my Raspberry Pi's and iOS devices.  Never tried duplex off.

To get my FFT out of the loop, I optionally capture raw data from the HL2 to a file, and then can later replay that data from a file to my FFT/spectrum/waterfall/etc. experiments.  I also synthesized known spectrum data for file playback, so I could view known signals in the waterfall for debug, and compare them to HL2 captured data.

Discovery took me awhile to debug because some of my macOS system and iOS devices firewalled UDP broadcast packets, so I had to use directed UDP Discovery packets to the expected subnet instead.

73,
Ron
n6ywu

Roger David Powers

unread,
Jan 29, 2022, 10:24:59 PM1/29/22
to Hermes-Lite, Alan Hopper
I could use some help on running the emulator.

the Avalonia version will work on windows, mac and linux.

Linux is my platform of choice.

By Avalonia do you mean https://github.com/ahopper/Patroclus/tree/master/Patroclus.Avalonia ?

Top-level readme.md says:

It can be built with Visual Studio 2013 or Visual Studio 2013 Express desktop edition. It uses .net4.5

I don't have access to those build tools.

I have run .net apps using 'mono' on Linux, but these need an exe file, I believe.

Is there an exe for the emulator online, or is the only choice to build the emulator from source?

Regards,
RDP


Roger David Powers

unread,
Jan 29, 2022, 10:33:51 PM1/29/22
to Roger Critchlow, Hermes-Lite
Hi, Roger. 

This is the kind of info I am after!  Unfortunately I didn't see it till now, 10:30PM on the US East coast, after a long day of mostly pursuing the original plan I sent out earlier, plus a little time seeing if I could not get Alan's emulator to run.  Today was a good day to play in the radio room because we were in a blizzard all day.  Tomorrow will need some snow removal time and also I have some other plans too but hopefully I will get time to go through your email tomorrow or Monday.

Thanks!
RDP



Roger David Powers

unread,
Jan 30, 2022, 12:17:44 AM1/30/22
to Hermes-Lite, ron.ni...@gmail.com
Thanks, Ron, for the comments.  Keep in mind as above I'm responding late in the day after a lot of hacking.

To safely test HL2 broadband transmit and receive, I've found that the HL2 receive capability is good enough that I can connect both HL2's to 2 different 50 Ohm dummy loads that are near each other, and receive on one HL2 what I transmit on the other.  For weaker signal testing I move the 2 dummy loads farther apart and use lower maximum amplitude samples (down to a fraction of 1 bit, dithered).

Another ham radio friend suggested this as well, and it worked great!  He calls it the "air gap" method.  It eliminates a lot of the risk of blowing up the receiver front end.

As an aside, my "test pattern generator" idea worked.  I just hooked up gnuradio's signal generator block ( https://wiki.gnuradio.org/index.php/Signal_Source ) to the gr-hermeslite narrowband block ( https://github.com/daniestevez/gr-hermeslite2 ) without needing a mixer and I could receive the waveform on my second HL2 which was running quisk.  I was able to examine the packets using wireshark with the hpsdr plug in ( https://github.com/matthew-wolf-n4mtt/openhpsdr-u ).  Note you need to go into the options to turn on HL2 support for this to work well.  It didn't give me a very intuitive feel if the test pattern was being generated or received well because it dumps the IQ values in hex and not as floating point numbers.  I'll have to have a go at changing that tomorrow.

UDP traffic to/from the HL2 has to go in both directions to reliably get past my network router and WiFi firewalls.  So I always use HL2 duplex from my Raspberry Pi's and iOS devices.  Never tried duplex off.

Actually, looking at the original line of code in rx4000.py, it looks like it has duplex 'on' since it has C4=0x04 which means duplex on and 2 receivers ( 
https://github.com/softerhardware/Hermes-Lite2/blob/master/software/ft8/rx4000.py#L42 ).  Looking at my code, it looks like I turned duplex off pretty much unintentionally, but I kind of like the fact that if it can be made to work I don't need to stream packets at the radio.  I will have to read Roger's email tomorrow to try to understand more about what the duplex bit does.

To get my FFT out of the loop, I optionally capture raw data from the HL2 to a file, and then can later replay that data from a file to my FFT/spectrum/waterfall/etc. experiments.  I also synthesized known spectrum data for file playback, so I could view known signals in the waterfall for debug, and compare them to HL2 captured data.

Great ideas!  I've been meaning to look at input/output of radio data using the SigMF format ( https://github.com/gnuradio/SigMF ).  Another idea is that rx4000.py sends packets to a zeromq interface.  It should be possible to make a simple gnuradio flow that reads them from gnuradio's zmq block and writes them to a file.  For the TX side, just hook up the gnuradio file source block to the gr-hermeslite block and it should send it.

Thanks for all the great ideas and info!
RDP

Alan Hopper

unread,
Jan 30, 2022, 5:07:16 AM1/30/22
to Hermes-Lite
Hi RDP,
sorry the emulator documentation is rather out of date, I'll try and improve it and build some executables.  If you want to build it your best bet is to install the .net 6.0 sdk  Download .NET 6.0 (Linux, macOS, and Windows) (microsoft.com) and then from the Patroclus.Avalonia directory 'dotnet restore' and then 'dotnet run'
73 Alan M0NNB

Roger David Powers

unread,
Jan 30, 2022, 7:06:47 PM1/30/22
to Hermes-Lite
Thank you Roger, as I wrote earlier, this is the kind of info I think I need.  Comments inline.


I can answer some of this.   

The protocol spec is described at https://github.com/softerhardware/Hermes-Lite2/wiki/Protocol, you should read the USB_protocol_V and Metis documents linked in the first paragraph.  Then read the rest of the article explains the HL2 specific additions and interpretations of the base protocols.

After the discovery phase, and the commands which start, stop, set number of receivers, and sample rate, which are all fairly transparent, comes the sample streaming phase.

I have read those specs a few times now.  I also am using Wireshark to dissect the Ethernet packets on the wire so I can study each packet, look at the headers and the fields in each byte.  Wireshark is a great tool!

Let me say more about what I am trying to do, at the risk of being overly verbose.

My current interest is mainly in using the rx4000.py code ( https://github.com/softerhardware/Hermes-Lite2/blob/master/software/ft8/rx4000.py ) Steve has put in the repo in the context of his ft8 beam steering / diversity work.  Basically it is a experimental, receive-only app that streams RX data from the HL2.  In this case, it's OK that it is not compliant with other HL2 apps, this is an experimental use case.  I asked Steve some questions about how it works and got some responses that I have summarized and commented on and that Raphael has just put online at https://github.com/DigitalHERMES/hermes_controller/blob/main/README.md which says:

  • Notes on the sequence 0xef, 0xfe, 0x05 in ethernet frames

  • My interpretation of (and comments on) the sequence 0xef, 0xfe, 0x05

    • It's a mechanism to send a command to the SDR on the alternate port 1025 regardless of whether or not the start command has been sent

    • Python function 'command()' in hermeslite.py shows the message sent is: bytes([0xef,0xfe,0x05,0x7f,addr<<1])+cmd+bytes([0x0]*51) where command can be either a 32 bit number or a four byte sequence

    • 'addr' corresponds to C0 and 'cmd' corresponds to C1 C2 C3 C4 of the main openhpsdr protocol


Sorry if the formatting is messed up, I'm using a dumb email client...

I'm pretty sure this stuff hasn't made it into the protocol documents yet, but I think if you look at the referenced fpga source file you will find that it does accept that command, and I've done enough testing to be fairly convinced what it does, which allows you to send a command from the PC to the SDR without putting it into the header of a USB-level packet carrying audio being streamed from PC to SDR.

Here's the fpga source of interest;

Inline image

"eth_data == 8'h05" is the case we are in.

Note I have no experience working with fpga code, but as above, I have convinced myself that it is an addition to the Metis-level protocol that does discovery, one that makes it easier to do certain things.

Back to your email.

The code for controlling the HL2 is hard to read in any language because it is continuously sending transmit packets and continuously handling receive packets.  The HL2 is controlled through headers in transmit packets.  The HL2 communicates back through headers in the receive packets.   The interaction between the two streams gets really hairy when sending i2c commands and waiting for acknowledgement.

The HL2 shuts down if enough transmit packets don't arrive, it assumes it is out of control and returns to the stopped state.

Yes, this is the kind of insight I need to help me understand what is going on!

Note that https://github.com/softerhardware/Hermes-Lite2/wiki/Protocol section Discovery/Start/Stop says:


The Metis Start packet is <0xEFFE><0x04>< Command><60 bytes of 0x00> where Command bit[0] starts the radio and bit[1] starts the wideband data as in protocol 1. The HL2 also uses bit[7] to disable the internal watchdog timer. The watchdog timer requires that the host computer send regular commands to keep the HL2 running. This ensures that the HL2 doesn't continue sending data if the host computer program crashes. Setting bit[7] disables this feature. It is useful for some receive-only programs such as CW skimmer.

I think this bypasses the shut-down logic you describe above.

So, I presume this isn't working as I want, I'll have to check my code.

The receive packets continue to deliver the specified number of receivers at the specified sample rate until the radio is stopped.  If you want to reduce the cpu load on your rpi, then reduce the number of receivers and/or reduce the sample rate.  I believe you can run with 0 receivers if you like.  

Yes, I've measured receiver throughput as a function of receivers and sample rate and concur.  I'll go even further to say using Python to unpack the incoming IQ samples is so inefficient that I intend to move away from doing this and move on to a compiled language.  However I have put a lot of time getting to this point and I want to publish what I've done, once it works as well as I can make it work.  The nice thing about the pure Python approach is that it is quite instructive.  The bad thing is that it is inefficient for this kind of data-intense work.

I believe that duplex is simply switching the cable modem chip between simplex and duplex modes.  The receiver samples will all be zero during transmit if you operate simplex, but they will continue arriving at the rate required for the specified number of receivers and sample rate, which could be a lot of zeros.

Ahh, ok.  This is something that did not or would not have occurred to me.  This helps me stop wondering what was going on with duplex on vs off.

Using the USB_protocol_V document and the Metis document and the wiki page, you can compute exactly the volume of UDP receive packets your rpi can expect for any combination of number of receivers and sample rate.

Actually, that one did occur to me. I was seeing packet drops.  I read the spec and asked myself, how much time do I need to process a packet in before the next one arrives vs how much time am I consuming to process a packet.  Once I did that, it was obvious why I was dropping packets, it simply was taking the code too long to process each packet.  I wrote a Python program to print out tables of things like time per packet as a function of number of receivers and sample rate, and its reciprocal, which is packet rate.  

I could be out of date, it's been several years, but I don't see any hints of change as drastic as you want.

The idea that duplex=0 should mute the receiver samples is interesting, except that it would break all the existing HL2 software.  It would be thrown into a panic when the receiver stopped sending samples at the rate specified by the protocols.  Lots of code uses the number of received packets to time the sending of transmit packets.

As above, it seems people have been wanting to do receive-only apps such as CW skimmers and it seems the FPGA logic has been changed to allow this to happen. 

Thanks to your help, I now understand a bit more about the "soul of the machine" and investigating my problem(s) should be easier!


Regards,
RDP

Roger David Powers

unread,
Jan 30, 2022, 7:51:58 PM1/30/22
to Hermes-Lite, Alan Hopper
Hi, Alan!

Thanks for the instructions!  I was able to install the dotnet runtime as per the link and  'dotnet restore' worked but 'dotnet run' did not.  Its output is below, see bold below for error, the rest appear to be warnings.   Machine is Ubuntu 18.04 x86_64.  Old, I know, but still it is a LTS release.  

/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj : warning NU1603: Patroclus.Avalonia depends on Avalonia (>= 0.9.999-cibuild0005911-beta) but Avalonia 0.9.999-cibuild0005911-beta was not found. An approximate best match of Avalonia 0.10.0-preview1 was resolved.

/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj : warning NU1603: Patroclus.Avalonia depends on Avalonia.Desktop (>= 0.9.999-cibuild0005911-beta) but Avalonia.Desktop 0.9.999-cibuild0005911-beta was not found. An approximate best match of Avalonia.Desktop 0.10.0-preview1 was resolved.

/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj : warning NU1603: Patroclus.Avalonia depends on Avalonia.ReactiveUI (>= 0.9.999-cibuild0005911-beta) but Avalonia.ReactiveUI 0.9.999-cibuild0005911-beta was not found. An approximate best match of Avalonia.ReactiveUI 0.10.0-preview1 was resolved.
/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj : warning NU1603: Patroclus.Avalonia depends on Avalonia (>= 0.9.999-cibuild0005911-beta) but Avalonia 0.9.999-cibuild0005911-beta was not found. An approximate best match of Avalonia 0.10.0-preview1 was resolved.

/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj : warning NU1603: Patroclus.Avalonia depends on Avalonia.Desktop (>= 0.9.999-cibuild0005911-beta) but Avalonia.Desktop 0.9.999-cibuild0005911-beta was not found. An approximate best match of Avalonia.Desktop 0.10.0-preview1 was resolved.

/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj : warning NU1603: Patroclus.Avalonia depends on Avalonia.ReactiveUI (>= 0.9.999-cibuild0005911-beta) but Avalonia.ReactiveUI 0.9.999-cibuild0005911-beta was not found. An approximate best match of Avalonia.ReactiveUI 0.10.0-preview1 was resolved.

/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Program.cs(3,24): error CS0234: The type or namespace name 'Serilog' does not exist in the namespace 'Avalonia.Logging' (are you missing an assembly reference?)

 [/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj]
/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Controls/MultiSpinner.cs(127,33): warning CS0672: Member 'MultiSpinner.OnTemplateApplied(TemplateAppliedEventArgs)' overrides obsolete member 'TemplatedControl.OnTemplateApplied(TemplateAppliedEventArgs)'. Add the Obsolete attribute to 'MultiSpinner.OnTemplateApplied(TemplateAppliedEventArgs)'. [/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj]
The build failed. Fix the build errors and run again.


Regards,
RDP
--
You received this message because you are subscribed to the Google Groups "Hermes-Lite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hermes-lite...@googlegroups.com.

Steve Haynal

unread,
Jan 31, 2022, 12:58:16 AM1/31/22
to Hermes-Lite
Hi RDP,

One comment, the place in the code that branches off of the value 8'h05 is to support the secondary port 1025 communication. That is an extension to openhpsdr. I actually did not want to document it in the spec as I don't think software should make use of it. It is more of a debug port only for hermeslite.py. The file hermeslite.py is the best documentation for its use.

73,

Steve
kf7o

Roger David Powers

unread,
Jan 31, 2022, 9:46:51 AM1/31/22
to Hermes-Lite
Hi, Steve!

One comment, the place in the code that branches off of the value 8'h05 is to support the secondary port 1025 communication. That is an extension to openhpsdr. I actually did not want to document it in the spec as I don't think software should make use of it. It is more of a debug port only for hermeslite.py. The file hermeslite.py is the best documentation for its use.

That makes sense, but that leaves me wondering what is the most supportable way to code a receive-only SDR app that does not want/need to generate TX audio packets from PC to SDR, like the CW skimmer mentioned in the protocol page.  Or in the case of rx4000.py running on Raspberry Pi and decoding FT8, an app whose platform not have the performance to do so?  

My guess is we stop using port 1025, we do discovery then issue the start command with watchdog timer disabled on port 1024, we generate a few TX packets whose headers issue the needed commands to set up and tune the radio and otherwise are zero filled, then we just stop sending TX packets and rely on the disabled watchdog to keep the radio from timing out?

Also, I'm wondering if you know if the duplex bit in C4 of the command with C0=0 (Wireshark calls this the 'SDR configuration' command) just controls the radio-side full vs half duplex mode and has no role in the computer-side protocol?  I simply do not have the familiarity with Verilog in general and our firmware in particular to figure this out.  My problem is I think I saw the radio delivering receive data I didn't understand when I had duplex off and was not transmitting.  In the big picture this won't matter if it has no impact on the computer protocol side, I will just leave it on, but I'm still curious about what it does.

This snapshot from the USB protocol document shows the duplex bit highlighted.

Inline image
Regards,
RDP

Jim Ancona

unread,
Jan 31, 2022, 11:54:30 AM1/31/22
to Hermes-Lite
For HPSDR Connector[1] (which works with OpenWebRX and so is receive-only) I chose to simply send dummy TX packets to keep the watchdog timer happy. I thought that might help compatibility with other HPSDR radios, but I don't know whether that's actually true.


--
You received this message because you are subscribed to the Google Groups "Hermes-Lite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hermes-lite...@googlegroups.com.

ron.ni...@gmail.com

unread,
Jan 31, 2022, 1:21:13 PM1/31/22
to Hermes-Lite
Sending UDP packets to the HL2 continuously (at the unused audio rate) usually reports back status far more promptly if the network route becomes unreachable, faster than waiting for a receive data underflow time-out.  The additional CPU load for sending packets, compared to handling the received IQ samples, is negligible.
73,
Ron
n6ywu


Alan Hopper

unread,
Jan 31, 2022, 2:20:19 PM1/31/22
to Hermes-Lite
Hi RDP,
sorry I should have mentioned I updated the github project just before my last post and it looks you were using an old version. I just tested here on linux and put up another tweak so it should work if you try again with a fresh copy.
73 Alan M0NNB

Roger David Powers

unread,
Jan 31, 2022, 4:11:25 PM1/31/22
to Hermes-Lite
Hi, Jim, thanks for responding!

For HPSDR Connector[1] (which works with OpenWebRX and so is receive-only) I chose to simply send dummy TX packets to keep the watchdog timer happy. I thought that might help compatibility with other HPSDR radios, but I don't know whether that's actually true.

So, do you keep the watchdog happy by sending packets with zero'd packets at the full specified rate (see below), or at some slower rate that keeps the watchdog from going off?

The USB protocol spec says:

Inline image

Thanks,
RDP


Roger David Powers

unread,
Jan 31, 2022, 4:40:09 PM1/31/22
to Hermes-Lite
Hi, Ron, thanks for responding!

Sending UDP packets to the HL2 continuously (at the unused audio rate) usually reports back status far more promptly if the network route becomes unreachable, faster than waiting for a receive data underflow time-out.  The additional CPU load for sending packets, compared to handling the received IQ samples, is negligible.

I am wondering, which receive data timeout are you speaking of?

My use case is Python code ideally running on a Raspberry Pi which is already pretty performance limited, and I'd like to avoid the complexity and the performance hit of streaming zeros back to the radio.  As mentioned earlier, I'll probably move on from this approach once I have it working as well as I can make it work, but I want to get it to that point because I feel it has instructional value.

I've written code that I plan to release that runs packet tests and prints packet loss rates as a function of sample rate and number of receivers on three different computers I have access to.  Here's a preview of its output:

Inline image


So, in my experience, the Pi struggles to keep up with two 48 ksps streams, add one more stream it drops 39% of the packets, double the sample rate it drops 28% of the packets. This is with the computer doing nothing with the data it receives, add some signal processing and I presume it gets worse.  I know there are lots of ways to improve on this (use compiled code for the "inner loop", use threads to get other cores working, etc) but I'd like to keep it as simple as I can.  That's one thing I liked about the rx4000.py code, it was pretty straight forward once you read the protocol specs.

Regards,
RDP







Roger David Powers

unread,
Jan 31, 2022, 4:54:50 PM1/31/22
to Hermes-Lite, Alan Hopper
Thanks, Alan!

You were right, I was trying a stale version, updating helped.

No warnings from 'dotnet restore' but a few warnings from 'dotnet run':

rdp@pmax:~/code/sdr/Patroclus/Patroclus.Avalonia$ dotnet restore

  Determining projects to restore...


  Restored /home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj (in 16.38 sec).


rdp@pmax:~/code/sdr/Patroclus/Patroclus.Avalonia$ dotnet run



/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Controls/MultiSpinner.cs(127,33): warning CS0672: Member 'MultiSpinner.OnTemplateApplied(TemplateAppliedEventArgs)' overrides obsolete member 'TemplatedControl.OnTemplateApplied(TemplateAppliedEventArgs)'. Add the Obsolete attribute to 'MultiSpinner.OnTemplateApplied(TemplateAppliedEventArgs)'. [/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj]


/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/ViewModels/FakeHermesNewProtocol.cs(53,14): warning CS0414: The field 'FakeHermesNewProtocol.hermesCodeVersion' is assigned but its value is never used [/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj]


/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/ViewModels/FakeHermesNewProtocol.cs(265,14): warning CS0414: The field 'FakeHermesNewProtocol.actualPacketCount' is assigned but its value is never used [/home/rdp/code/sdr/Patroclus/Patroclus.Avalonia/Patroclus.Avalonia.csproj]


00000089


Output looks like:

Inline image


Let me know if you want me to test any updated version.

Regards,
RDP


Steve Haynal

unread,
Feb 1, 2022, 1:48:09 AM2/1/22
to Hermes-Lite
HI RDP,

A few comments on this thread. Yes, you only need to use port 1024 and you can disable the watchdog timer immediately (no need to ever send TX packets) by setting the bit in the Metis start packet. I think this is what CW skimmer does.

The openhpsdr radios always send receive packets back to the host PC, whether in full duplex or not. If the full duplex flag is set, then the TX and first receiver can be set to different frequencies. If the full duplex flag is not set, then the TX and first receiver are always set to the TX frequency. This is historical from the original port of the openhpsdr gateware. In my opinion it is not elegant and should be removed. I would want the default to be full duplex is always set so that the TX and first receiver frequencies are independent. Does anyone make use of this functionality?

73,

Steve
kf7o

Roger David Powers

unread,
Feb 2, 2022, 12:32:46 PM2/2/22
to Hermes-Lite
Here is a summary of some recent emails, with me doing some interpretation of them based on my perspective, hopefully not missing the intent/meaning of the authors.  The emails have all been helpful!

Executive summary: I need to do some experiments to see what works best for my app and its intended use cases.  Note that I consider my app to be an instructional tool rather than a "real SDR application", but of course I want it to be as reliable as I can make it without sacrificing too much in terms of performance or complexity.

One suggestion is to just send enough UDP packets at the radio to avoid the radio timeouts.

I need to do some experiments with the rate of sending packets to the radio to see if I can determine what a suitable rate would be.

Another suggestion is do what most apps do, send UDP packets continuously to the radio at the two stream 48khz audio rate because it will provide feedback (in what form?) far more promptly than the feedback provided by a receive data underflow timeout (which rx4000.py doesn't seem to currently have support for).

I need to explore the mechanisms in the protocol for feedback from the radio. 

I need to consider how important/unimportant detecting such conditions are for my application, which so far is intentionally just a radio directly hardwired to a computer ethernet port with no other devices on that ethernet.

I already know my application is already showing that performance is a challenge.

I have observed what gr-hermeslite does using wireshark to sniff the packets, which is presumably similar to what most other OpenHPSDR apps do.  It just sends Metis data packets at the 48khz two stream rate. The Metis data packets have two USB packets whose IQ data is set to zero and whose headers contain a round-robin replay of all the commands it's sent to the radio for configuration, for setting the transmit frequency and then for setting all the frequencies for all the receivers it knows about, which for some reason is 8.  Presumably 8 was the number of radios in the protocol when the code was written.  It commands all eight receivers even when it is using just one.  gr-hermeslight does not have a receive-only vs tx/rx mode, I am just observing what it does with its input set to the "null source".

It was pointed out to me that the original protocol largely does not let you directly verify that these bits/values are set as intended, so the approach of just resending the commands over and over and presuming that they eventually be received and processed by the radio is what was taken.

As above, I need to verify what mechanisms do or do not exist in the protocol.

I had already noticed that one can set the RQST bit on packet sent to the radio and look for the ACK response on incoming packets, but this is a HL2-specific protocol extension so using it means your app won't work with other HPSDR based radios.

I will do some experiments to see what methods of commanding the radio work best.

It was pointed out to me that you can do the same things with port 1025 as you do with port 1024, but port 1025 is also a HL2-specific extension so using it also means your app won't work with other HPSDR radios.

Now I will go buy groceries before the next snow storm!

Regards,
RDP


Reply all
Reply to author
Forward
0 new messages