Welcome to the new FlexRadio Community! Please review the new Community Rules and other important new Community information on the Message Board.
If you are having a problem, please refer to the product documentation or check the Help Center for known solutions.
Need technical support from FlexRadio? It's as simple as Creating a HelpDesk ticket.

Steps to initalize the radio without SmartSDR

James Whiteway
edited February 2017 in SmartSDR API
In my continuing studies on relearning C# and working with Flexlib, I was wondering in what order does the radio need to be initialized from an application that does not depend on the SmartSDR client running.  I am playing around with a small app for a Windows tablet I have, and at some point an Android tablet as well, that would control the radio over my LAN and WiFi connection.
I can control the radio, (to a point) from the tablet as long as SmartSDR is running. But, it is slow and uses too many resources (cpu cycles) at present. So, my goal is to eliminate using SmartSDR for a simple interface that should, in theory, be able to control the radio and once v1.4 comes out, I'm betting I can add audio back to the tablet as well.
Any clues on what needs to occur would be appreciated. 

Answers

  • IW7DMH, Enzo
    IW7DMH, Enzo Member ✭✭
    edited January 2017
    Hello James,

    reading this post probably will help you
    https://community.flexradio.com/flexradio/topics/smartsdr-tcp-ip-api-starting-demodulation-and-receiver-using-telnet
    Stu helped me to start the receiver using only a telnet client.
    You should follow the same logic (few simple commands actually) but using FlexLib api.

    73' Enzo
    iw7dmh




  • James Whiteway
    edited February 2015
    Thanks for the link Enzo! That gives me a better idea on what settings need to happen.
    james
    WD5GWY

  • James Whiteway
    edited November 2016
    Just a little update on my "attempts" to initialize the radio without SSDR running. The code below
    will start the radio just fine:
     _thisRadio.Connect();
                double freq = 14.290d;
                string RXA = "Ant 1";
                string Mode = "USB";
               
                Slice Slice0 = new Slice(_thisRadio);
                Slice0 = _thisRadio.CreateSlice(freq, RXA, Mode);
                Slice0.RequestSliceFromRadio();
    But, I have no control over the radio. And, on my testbed form, the only things that are properly updated are the frequency, antenna selected and Mode. Visual Studio throws an exception for all other events that I normally would be able to display were SSDR running at the same time.
    I can start SSDR after stopping execution of my program in Visual Studio and everything I have set will be displayed on the Panafall. But, the Panafall's gain is wrong and several other settings as well. Closing SSDR and restarting puts everything back to normal.
    The code above was "borrowed" from another post in the API forum and is further kludged by me and not the original author!
    I figure I need to initialize a bunch of other things, such as AGC, Band, etc. but, I don't know if I should do that before or after calling: Slice0.RequestSliceFromRadio();

    I figure that getting the above correct will help in my attempts to create a panadapter as well.
    So, any pointers on this will be appreciated.
    james
    WD5GWY

     Edit: since we now have a Persistence database in the radio itself, (unless I've greatly misunderstood something) would it be possible to start the radio and have my program use the database to set the radio to it's previous state? It sure would make things easier!
     
    
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    Absolutely, I routinely navigate between my, um, other SSDR and SSDR. I could have sworn I've had them both running at the same time. I had a heck of a time getting the order straight and, frankly, I think the radio behaves far better when you've entered "client gui" than if you don't. So, yes to your question, you can predictable start it where the other left off.
    So, you have 3 events
    1) OnRadioAdded, (or for those with deeper pockets, radio choosen)
    2) OnPanadapterCreated
    3) OnSliceCreated

    You should definitely respond to these things as asynchronous events
    then,

    1) OnRadioAdded( Radio radio) {
                 PanadapterAddedEventHandler panAdded = (Panadapter panx, Waterfall fall) -> processPanAdded(panx, fall);
                PanadapterRemovedEventHandler panRemoved = (Panadapter pan) -> processPanRemoved(pan);
                activeRadio.addPanAddedEventListener(panAdded);
                activeRadio.addPanRemovedEventListener(panRemoved);
               
                SliceEventHandler sliceAdded = (Slice slc) -> processSliceAdded(slc);
                SliceEventHandler sliceRemoved = (Slice slc) -> processSliceRemoved(slc);
               
                SlicePanReferenceChangeEventHandler slcpan = (Slice slc) -> processSliceAdded(slc);
                SlicePanReferenceChangeEventHandler slcpan1 = (Slice slc) -> processSliceRemoved(slc);

                activeRadio.addSliceAddedEventListener(sliceAdded);
                activeRadio.addSliceRemovedEventListener(sliceRemoved);
               
                activeRadio.addSlicePanReferenceChangeListener(slcpan1);
                activeRadio.addObserver(this);
                activeRadio.Connect();

                activeRadio.RequestPanafall();

    2) OnPanadapterAdded(Panadapter pan, Waterfall fall) {
            activePan = pan;
            assert(activeRadio.findPanadapterByStreamID(activePan.getStreamID()) != null);
            activePan.addObserver(this);       
            log.debug("Entering processPanAdded" + activePan.toString() + " " + fall.toString());
            PanDataReadyEventHandler tempVar1 = (Panadapter panx, short[] data) -> processPanData(panx, data);
            activePan.addDataReadyEventListeners(tempVar1);


    3) OnSliceAdded(Slice slice) {

    }

        What I'd do is for all 3 events, first thing, on the OnXXXXAdded, create a class to handle the object and in the constructor, do the C# version of what I am doing in Java. When you get the slice, it will be where you left it, you can send commands through the pan object (one for each panafall), the radio object, and the slice object, one for each slice you create.

    Make sense?
  • James Whiteway
    edited June 2015
    "Make sense?"
    To some degree yes. But, like everything else, I'll have to study it for a while and play with various things till I get the results I need.
    Thank you for your help Walt. It is appreciated.
    I won't be able to do much with this till next weekend, since I'm going out on the road again today. But, I will definitely dive into it this weekend after HAMCOM!
    james
    WD5GWY
     
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    As I was saying, I had a time getting objects to mated properly. I was still having multiple pans show up and multiple slices show up and I wasn't getting events as I should have. I put client gui in and cleaned up how I requested things and voila! The two SSDR versions are in perfect sync. I am working on a completely kick **** UI now.

    One piece of advice though. Don't worry about modifying anything internal objects in your app. Simply get to the point where your app comes up in the same mode that the SSDR was terminated with.
  • Eric-KE5DTO
    Eric-KE5DTO Administrator, FlexRadio Employee admin
    edited February 2017
    James,

    Welcome to the API developers club!  The steps to get started with a FlexLib based application are covered in this thread: https://community.flexradio.com/flexradio/topics/first_steps_with_flexlib.  If you have questions, don't hesitate to ask.
  • James Whiteway
    edited June 2015
    Thanks Eric! Been playing and asking questions for a while now. I've read & reread the info in the link you posted a number of times. But, I guess I'm getting senile and still canno quite get the order I need to send commands to the radio to properly initalize the radio. As posted above, I have had some success and can get things going to a point. But, no control over the radio from my program without SSDR running too. I want to be able to control the radio without SSDR. I'm using C Sharp and Flexlib. Any suggestions/examples would be appreciated. james WD5GWY
  • Eric-KE5DTO
    Eric-KE5DTO Administrator, FlexRadio Employee admin
    edited December 2016
    SmartSDR is certainly not necessary to control the radio.  When you say that you want to control the radio, what do you mean by this?  Can you give me a list of the things you'd like to control (i.e. change, monitor).  I'm assuming Slice frequency and mode.
  • James Whiteway
    edited June 2015
    I'm sorry if I'm not being very clear about what I am trying to do Eric. Currently, with SSDR running, I can control the radio. Change frequency, band, ect mode, add a slice, adjust filtering etc from my test program. What appears in SSDR is reflected in my program as well. But, I want to do all those things and more, without SSDR running. Same as William is doing, except in a Windows program. All that I have done so far is written in C# with a similar test program ( not as current ss the C# program) written in Visual Basic. This is a learning exercise for me. Not a commercial program. My issue is simply this, in order to get my program to interact with the radio the same as SSDR, but WITHOUT SSDR running, or even on the same machine, I need to know in what order do I send commands to the radio to properly activate the radio. And do I do that after, or before calling radio.connect(); ??? And I was wondering if I could use the Persistance database to do all that instead of having to create my own version of the database to hold all the presets from the previous session. james WD5GWY
  • Eric-KE5DTO
    Eric-KE5DTO Administrator, FlexRadio Employee admin
    edited December 2016
    I think I see where you are heading.  I think the order is as follows:

    1. Subscribe to the RadioAdded (and potentially RadioRemoved) event.
    2. Wait for the RadioAdded event to fire.
    3. Connect to the relevant events for the objects in which you are interested (SliceAdded, SliceRemoved, PanadapterAdded, PanadapterRemoved, etc).
    4. Connect to the radio.
    5. At this point you will handle the events likely in the same way whether they arrive asynchronously via persistence or whether you request new resources (e.g. radio.CreateSlice).

    Note that unless you send the "client start_persistence off" command, persistence will indeed happen when you send the radio which udpport to use ("client udpport <port#>").  This is handled for you if you are using FlexLib.

    In FlexLib we disable persistence if an update is required (ConnectedState == "Update") so that we don't end up restoring/saving persistence information when we are just attempting to update the radio to the correct version.  This happens whenever the radio's reported version doesn't match the RequiredFirmwareVersion (see the file by the same name).

    Let me know if you have specific questions about how any of this works.  We're here to help.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    James, what Eric and I are suggesting IS the easy way to accomplish what William was doing. You mentioned you wanted to do what William was doing. I am not going to pass on what he told me, but you might want to directly ask him if he would do it that way again. PLUS, Eric and staff already wrote the library to use in C#. I wrote the library to use in Java but William, who did his work in Java, didn't know that at the time. So if you do what Eric suggested followed by a API.CloseSession() when you are done you'll see that SSDR restarts precisely where it left off, which is one of your concerns. Once you start manipulating the radio or panadapter or slice receiver, once you close SSDR will start where your program left off.
  • James Whiteway
    edited June 2015
    Thanks Eric, that is the info I was missing. James WD5GWY
  • James Whiteway
    edited June 2015
    Thank you Walt. When I said I wanted to do what William was doing, I meant writing a program that would run my radio without SSDR . And using Flexlib to do it. I doubt I could do what you and William have done, independent of Flexlib. james WD5GWY
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    You mean Stu and me? William did not do what Stu and I did, being rewriting the library to support different languages and operating systems.. Look at the code for Cat, that is likely as close as you'll get to examples of using the library
  • James Whiteway
    edited June 2015
    I guess I'm a simpleton. I knew that Stu and you are/ were writing your own versions of Flexlib (Stu doing it in Objective C) . And it seems I also knew that William did not write his own version of Flexlib either. Instead William is working with the Vita packets directly and controlling the radio that way. But, my point, if there really was one, is this, what William has done just may well be above my skill set. But, I want(ed) to write an application similar to his that would work on my Win 8.1 tablet. And maybe someday dive into Java and do the same for my Android tablet. All just as a mental exercise. Not with the intention of selling anything. But, I would share the app(s) and the source code with others with similar thoughts. (which I've already done to some degree) So, no disrespect intended to you or Stu. William's app was symbolic of what I want to do. Nothing more. james WD5GWY
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    Understood, what I and Eric are suggesting is the fastest path to achieving that. In either case the java code I showed you or the C# code Eric showed you, in a dozen stmts you'll have a slice receiver and panadapter to play with. Now, if you don't know how to do a graphical interface, you have a much different problem.I
  • James Whiteway
    edited November 2016
    Well, "almost" there! I STILL cannot get the radio to send any data back to my program without SSDR running at the same time. Looking at the Wiki, it shows that  api.isGUI  is a bool and can be
    set to true. And if I understand correctly, doing so will tell the radio that my application is the gui client and send all data to my application. And that persistence will / should, make the radio return to it's previous state just as it does for SSDR (or my app if I ever get it running right without SSDR)
    when it closes down and then is restarted.
    The ONLY things I can currently get without SSDR running After doing:  radio.Connect();
    is the PA Temp, Voltage data, Callsign and Nickname. IP Address, Serial Number and Model Numbers all show up when my application initially loads. However, if SSDR is already running, I can get ALL the data except Panafall data sent back to my application. And as I understand it, the panafall is not available to both SSDR and another client at the same time. (currently)
      Maybe running almost 4,000 miles this week has slightly fried my brain, (along with having my trailer turn over yesterday morning while dumping out near Austin) but, it seems that the more things I try the less I seem to actually accomplish.
    james
    WD5GWY

        
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    If you want you app to run properly without SmartSDR running, stop running SmartSDR. Yes, some people may consider that a syllogism but it is true. client GUI tells the radio there is only one controlling app (instantiating Radios and Panadapters and Slices, that would be SmartSDR. Eric provided now two examples of how to do it, I provided one as well. I, further, gave you a language independent first steps. James, are you certain you want to do this?
  • James Whiteway
    edited June 2015
    Walt, I guess, I am not drawing this picture clear enough. When I run my app without SSDR, what I wrote in my previous post happens, only certain things are returned from the radio to my application. I have set : isGUI to : true, and still, the same results. NO additional info  shows up in my app as it would if  SSDR running at the same time. I have found no statement or setting in Flexlib for "Client GUI" . ONLY : api.isGUI and that is a BOOLEAN object and as far as I can see, that tells the radio that my application , running WITHOUT SSDR running should receive all events.
    I have followed Eric's steps and subscribed to the RadioAdded and RadioRemoved events. But, they do not happen as far as I can see. I can only get the three other things I mentioned in my previous post.
      I know you think I am dense, but, MAYBE, someone with some C# experience that could give me the correct syntax to set whatever it is, Client GUI or api.isGUI (which is a bool and does not return an error when set to true) that I am doing wrong.
    As for " Client udpport <port#>" that Eric mentioned, he states that that is handled by Flexlib. And I cannot see anywhere in Flexlib where I have to manually set it.
    And YES, I am certain I want to do this.
    james
    WD5GWY
  • James Whiteway
    edited June 2015
    I found this in radio.cs :

     // send client program to radio
                    if (API.ProgramName != null && API.ProgramName != "")
                        SendCommand("client program " + API.ProgramName);

                    if (API.IsGUI) SendCommand("client gui");

                    // subscribe for status updates
                    SendCommand("sub tx all");
                    SendCommand("sub atu all");
                    SendCommand("sub meter all");
                    SendCommand("sub pan all");
                    SendCommand("sub slice all");
                    SendCommand("sub gps all");
                    SendCommand("sub audio_stream all");
                    SendCommand("sub cwx all");
                    SendCommand("sub xvtr all");
                    SendCommand("sub memories all");
                    SendCommand("sub daxiq all");
                    SendCommand("sub dax all");

                    // get info (name, etc)
                    GetInfo();

                    // get version info from radio
                    GetVersions();

                    // get the list of antennas from the radio
                    GetRXAntennaList();

                    // get list of Input sources
                    GetMicList();

                    // get list of Profiles
                    GetProfileLists();

                    // turn off persistence if about to do an update
                    if (ConnectedState == "Update")
                        SendCommand("client start_persistence off");

                    // set the streaming UDP port for this client
                    SendCommand("client udpport " + API.UDPPort);


                    StartFFTProcessThread();
                    StartMeterProcessThread();

                     // send client program to radio
                    if (API.ProgramName != null && API.ProgramName != "")
                        SendCommand("client program " + API.ProgramName);

                    if (API.IsGUI) SendCommand("client gui");

                    // subscribe for status updates
                    SendCommand("sub tx all");
                    SendCommand("sub atu all");
                    SendCommand("sub meter all");
                    SendCommand("sub pan all");
                    SendCommand("sub slice all");
                    SendCommand("sub gps all");
                    SendCommand("sub audio_stream all");
                    SendCommand("sub cwx all");
                    SendCommand("sub xvtr all");
                    SendCommand("sub memories all");
                    SendCommand("sub daxiq all");
                    SendCommand("sub dax all");

                    // get info (name, etc)
                    GetInfo();

                    // get version info from radio
                    GetVersions();

                    // get the list of antennas from the radio
                    GetRXAntennaList();

                    // get list of Input sources
                    GetMicList();

                    // get list of Profiles
                    GetProfileLists();

                    // turn off persistence if about to do an update
                    if (ConnectedState == "Update")
                        SendCommand("client start_persistence off");

                    // set the streaming UDP port for this client
                    SendCommand("client udpport " + API.UDPPort);


                    StartFFTProcessThread();
                    StartMeterProcessThread();

                    StartKeepAlive();

                    return true;
                }
            }

    It would appear that if " isGUI" is set to true by my app Flexlib should direct the radio to send data to my client app. But, for some reason that's not happening.
    I have subscribed to the events Eric mentioned and with SSDR running in the background my app receives those events. Just does not happen without it.
    Maybe, I'm putting the isGUI in the wrong place.

    my app:


     public Form1()
            {
                InitializeComponent();
                API.RadioAdded += API_RadioAdded;
                API.RadioRemoved += API_RadioRemoved;
                API.ProgramName = "WorkingCSharpFlexExample";
                API.IsGUI = true;

                API.Init();
               
            }

    If I put it in the form load event, the form shows, but, with NOTHING on it. Completely blank! The only place things seem to work, (again with SSDR running) is prior to the Form Load event.
    james
    WD5GWY

    I'm sure it's the ID 10 T error at work here. But, I cannot tell what I'm doing wrong.






  • James Whiteway
    edited June 2015
    In case Walt misses it in another thread, I owe him an apology for being a bit sharp in my previous responses here. Frustration can do that sometimes. Anyway, IT WORKS NOW! And without SSDR running at all.
    Thank you Walt, Eric and everyone else who offered advice and put up with my poorly worded questions. It is appreciated!
    james
    WD5GWY

  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    ID 10 T?
    Why do you think anything at all will show in your form?
    Here is the thing James, unless it was a dbl tap insert you are doing things multiple times and 4 of the last 6 things don't even make sense. Here is what I suggest:

    1) don't put anything into a program unless you can explain what it is supposed to do. The vast majority of what you have there you do not need. Compare that to this,

        private boolean launchDiscovery() {
            RadioAddedEventHandler onRadioAdded = (Radio radio) -> onRadioAdded(radio);
            api.addRadioAddedListener(onRadioAdded);
            API.setProgramName("OtherSmartSDR");
            api.setGUI(true);
            api.Init();
            return true;

    Forget, for the moment it's not C#. What did I just do?
    1) created a RadioAdded callback, regardless of what it is called in any given language, it is the sink for the event that will be raised when a radio is discovered and deemed not to be a duplicate, which will happen every second.

    2) I told the API class about it, so now API knows to add that method as a sink when it finds a radio.

    3) I set the program name...a totally futile thing to do as the radio returns an error to being given the program name, I just haven't removed it as it demonstrates the radio returning an error condition.

    4) set GUI to true

    5) invoked API.Init().

    So, regardless of language differences, get that much working in yours. The sink for onRadioAdded takes the radio object, chances are really good it will be a single radio unless you have multiple 6000 series radios. You will need that method in order to create the panadapter. But, your 'assignment' for now is just getting that much working. Bonus points, add the name to your form. That is not part of your 'assignment' I want you to get a notification you have a radio. That's it. BTW, I've taught programming in several settings, several different languages.

    And do this without running SmartSDR. The other key point is do not add a line of code you can't explain what it does and why it works.

    If you did not write a method called API_RadioAdded, then you need to write your own.

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.