Keyboard Shortcuts
Likes
- SoftwareControlledHamRadio
- Messages
Search
Re: Restructuring the T41 code
On Fri, Apr 25, 2025 at 07:26 AM, Greg KF5N wrote:
The one exceptional header file is the T41EEE's AudioSignal.h file.? This is a super-important and special header file which contains the Teensy Audio and Open Audio related code.? This header is included into the T41EEE.ino file.There isn't anything particularly special about this code.? It can be placed in its own cpp file along with a header file for the global externs and function prototypes.? That's what I've done. |
||
Re: Restructuring the T41 code
Yep...we're on the same page. Jack, W8TEE
On Friday, April 25, 2025 at 10:26:51 AM EDT, Greg KF5N via groups.io <greg.electricity@...> wrote:
Yes, Jack, you've got it!? There is some nuance when someone uses the term "global", and what I was trying to flush out was the "super globals" versus "local file globals".? When I see "extern" that is a pretty good hint.
So what I've been doing, and I think Oliver is doing something similar, is isolating the "local file globals" first.? So that's what I do, is to put them in the existing .cpp file, in their home turf.
At some point it makes sense to re-factor into a class.? That is when a unique new header file is added.? The "local file globals" are scooped up and dropped into that new header file.
Externs are removed from the SDT.h file, and the same goes for function declarations which can be "delisted" from the SDT.h.
?
The one exceptional header file is the T41EEE's AudioSignal.h file.? This is a super-important and special header file which contains the Teensy Audio and Open Audio related code.? This header is inserted into the T41EEE.ino file.
?
--
73 Greg KF5N
-- Jack, W8TEE |
||
Re: Restructuring the T41 code
Yes, Jack, you've got it!? There is some nuance when someone uses the term "global", and what I was trying to flush out was the "super globals" versus "local file globals".? When I see "extern" that is a pretty good hint.
So what I've been doing, and I think Oliver is doing something similar, is isolating the "local file globals" first.? So that's what I do, is to put them in the existing .cpp file, in their home turf.
At some point it makes sense to re-factor into a class.? That is when a unique new header file is added.? The "local file globals" are scooped up and dropped into that new header file.
Externs are removed from the SDT.h file, and the same goes for function declarations which can be "delisted" from the SDT.h.
?
The one exceptional header file is the T41EEE's AudioSignal.h file.? This is a super-important and special header file which contains the Teensy Audio and Open Audio related code.? This header is included into the T41EEE.ino file.
?
--
73 Greg KF5N |
||
Re: Restructuring the T41 code
Mornin' Greg: Yes, Al and I found a lot of "dead" variables when we started out. We could tell by their names that some of them were clearly used as temporary debug variables that just didn't get cleared out. We also found a bunch of "dead" functions that were never called anywhere. We tried to remove all of those, but I know some were not removed. At one time, I thought some of these might be resued later on, but ended up not being used. I just never when back to clean them out. "De-globalizing" the code is a little harder when the variable is used in multiple unrelated functions. In those cases, the variable could be defined in the ino file, but passed to the other functions (as a pointer?) as needed. That does de-clutter things, but is a pain to do. However, if you can isolate the variable to only the file that uses it, the problem is more manageable. Example: If a variable is only used in the display.cpp source file, it can be localized to that file. It sounds like that's what you've done: create a header file for each "functional" cpp file. The reason I didn't do this is because, as you pointed out, it means each cpp file has its own header file, which has the effect of doubling the number of file which is its own form of clutter, albeit it is organized clutter.? For such global variables that are only used in one cpp file, instead of placing them their own header file (e.g., display.h which ties to display.cpp), you could place those "local globals" in the cpp file, but use the static storage specifier for them. This keyword is more of an attention-gettter to the programmer than a difference in the variable's placement in memory. I say that because, if you define the variable in the display.cpp file outside of a function without the static specifier, it has global scope, but only for the file in which it is defined. If that variable is not called in any other cpp file, you won't get the "undefined" error message. The only thing the static keyword does is allow you to use that same variable name in multiple cpp files and still not generate a "multiply defined" error message. (I don't know why you'd want to do that, but you could!) The only reason I would add the static keyword in this case is to serve as a sentinel to tell other programmers that this is a "local global". Jack, W8TEE
On Thursday, April 24, 2025 at 11:26:11 PM EDT, Greg KF5N via groups.io <greg.electricity@...> wrote:
Hi Jack-
?
It's a metric of the reduction of global variables.? Note that the .ino file was also greatly de-cluttered in concert with SDT.h.
There were also a bunch of variables which only existed in the SDT.h file.? I suspect they were remnants of earlier functions, tests, and experiments which were never cleaned up.
?
It was a large clean-up job, but the result was worth it.? The code is much easier to work with and debug.? Not really different in effect than that first step you Al took to break the
SDR Convolution code from a single to multiple files.
?
--
73 Greg KF5N
-- Jack, W8TEE |
||
Re: FW 66.9 bug
Found the bug -- it was a simple one-line fix in the end. Pushed to GitHub:
On Thursday, April 24th, 2025 at 10:34 PM, Tim via groups.io <w4yn@...> wrote:
|
||
Re: Restructuring the T41 code
Oliver - Thanks for update.? Your diagrams are very helpful.
?
On Thu, Apr 24, 2025 at 07:10 PM, Greg KF5N wrote:
The rest have to be handled one at a time, manually.? It's tedious.I took this approach.? Yes, it's tedious.? I've gone pretty far with my approach.? My SDT.h is only 209 lines.? This doesn't reflect a massive reduction in global variables but more of a redistribution into the modules primarily related to the variable.? Often these could be made local to specific functions or global to just that module.? When needed outside that module I use module specific header file with the required variable declared as external.? These header files also contain that module's function prototype declarations needed by other modules.? This basically doubles the number of files but makes it easier to find stuff. |
||
Re: Restructuring the T41 code
Hi Jack-
?
It's a metric of the reduction of global variables.? Note that the .ino file was also greatly de-cluttered in concert with SDT.h.
There were also a bunch of variables which only existed in the SDT.h file.? I suspect they were remnants of earlier functions, tests, and experiments which were never cleaned up.
?
It was a large clean-up job, but the result was worth it.? The code is much easier to work with and debug.? Not really different in effect than that first step you Al took to break the
SDR Convolution code from a single to multiple files.
?
--
73 Greg KF5N |
||
Re: Restructuring the T41 code
Greg: Curious about the line: To get an idea of how much progress I have made, the number of lines in T41EEE.9/SDT.h = 1057.? SDTVer066-9/SDT.h = 2640. What was the impact if you add up the class header file lines. How much net change was there? Jack, W8TEE
On Thursday, April 24, 2025 at 10:10:13 PM EDT, Greg KF5N via groups.io <greg.electricity@...> wrote:
Hi Oliver-
?
One thing I recommend is writing a script to "de-globalize" the code.? I did this and removed hundreds of globals.? There were even globalized local variables!
What the script does is take a variable from SDT.h, and then does a search on all of the other files (I dont' think the .ino file was included).? Any variable which
shows up only once is a candidate for de-globalization.? The first step is to pull that extern variable out of SDT.h and make it a file scope variable in the file where it belongs.
Once that process is complete, then copy the file scope variables into a header file and make a class.? Not everything is a class yet, but the file scope variables are mostly
sorted to their home files.
?
The script will get a bunch of them.? But I didn't refine it enough to get all of them.? The rest have to be handled one at a time, manually.? It's tedious.
To get an idea of how much progress I have made, the number of lines in T41EEE.9/SDT.h = 1057.? SDTVer066-9/SDT.h = 2640.
There is still a huge amount of work to be done.? But a few variables will have to remain global.
?
The other thing I have done is to "modalize" the code.? I've used scoped enums to great effect.? This was a huge change in T41EEE.9.? I wasn't sure how it would work out,
but it is working extremely well and it's a clear way forward to more robust code.? There are still some things not completely modalized, but I think the next version will get it there.
A lot of things have been working in a state machine pattern for the last several versions.? It's less than perfect, but the modalization was a big step forward in improving that.
?
StateSmith looks pretty cool.? I bought a big artist's pad at Walmart and draw everything out with a pen.
?
--
73 Greg KF5N
-- Jack, W8TEE |
||
Re: Restructuring the T41 code
Hi Oliver-
?
One thing I recommend is writing a script to "de-globalize" the code.? I did this and removed hundreds of globals.? There were even globalized local variables!
What the script does is take a variable from SDT.h, and then does a search on all of the other files (I dont' think the .ino file was included).? Any variable which
shows up only once is a candidate for de-globalization.? The first step is to pull that extern variable out of SDT.h and make it a file scope variable in the file where it belongs.
Once that process is complete, then copy the file scope variables into a header file and make a class.? Not everything is a class yet, but the file scope variables are mostly
sorted to their home files.
?
The script will get a bunch of them.? But I didn't refine it enough to get all of them.? The rest have to be handled one at a time, manually.? It's tedious.
To get an idea of how much progress I have made, the number of lines in T41EEE.9/SDT.h = 1057.? SDTVer066-9/SDT.h = 2640.
There is still a huge amount of work to be done.? But a few variables will have to remain global.
?
The other thing I have done is to "modalize" the code.? I've used scoped enums to great effect.? This was a huge change in T41EEE.9.? I wasn't sure how it would work out,
but it is working extremely well and it's a clear way forward to more robust code.? There are still some things not completely modalized, but I think the next version will get it there.
A lot of things have been working in a state machine pattern for the last several versions.? It's less than perfect, but the modalization was a big step forward in improving that.
?
StateSmith looks pretty cool.? I bought a big artist's pad at Walmart and draw everything out with a pen.
?
--
73 Greg KF5N |
||
Re: Restructuring the T41 code
toggle quoted message
Show quoted text
On Apr 24, 2025, at 8:52?PM, Oliver KI3P via groups.io <oliver@...> wrote:
|
||
Re: LPF Control Board addressing help
¿ªÔÆÌåÓýOliver, success, I went back and re-flowed all of the connections
on U15 on the LPF control board and checked continuity on all the
pins again. Everything was ok. Then I remembered that there was a
7991 at U20 which was also connected to the I2C lines. I checked
the pins and found a short and an open and I couldn't tell if the
IC was on correctly. It's so small and the markings are impossible
to read. So I removed it, cleaned up the pads and the IC leads.
Was able to verify an alignment dot and replaced it. Continuity
checks went ok, and now it's working. It was probably on
backwards. Thanks for the help. Now I can get back to winding
Toroids. On 4/24/2025 7:55 PM, Oliver KI3P via
groups.io wrote:
--
73
Bob W3RDL |
||
Restructuring the T41 code
I wanted to share a little information on how I'm going to go about restructuring the T41 code.?
?
The most difficult bugs to track down in the current code have been those caused by the radio being in an unknown state -- some line that controlled a switch on the RF board or a parameter in the DSP chain was inserted or omitted somewhere in the code. Because all variables are global, this could be literally anywhere in the nearly 30,000 lines of code. Finding the source of the bug without the ability to use a debugger is a challenge. It also possible to insert an entirely valid line of code that places the radio in an invalid or undesirable state -- for instance, imagine turning the CAL switch on when trying to transmit SSB.
?
I'm going to solve this problem by using state machines. In the new code structure, the state of the radio hardware will be controlled entirely by a radio mode state machine. This state machine is the only place in the code where the hardware state is changed. Using a state machine to control the hardware ensures that all hardware is always in a known configuration state. I'm working my way through the hardware boards, defining the valid configuration states for that hardware. I will then write functions that put the boards into each valid configuration state. The only way the rest of the code can affect the radio hardware is by calling one of those functions, and the only part of the code that will call those functions is the radio mode state machine. Here's an example of some of the states for the RF board (does not include the calibration states).
?
?
?
State machines can be written entirely in C code, but it¡¯s easier to understand how the state machine operates through a visual diagram. I've found an open-source solution, , that allows you to draw the state machines in a graphical environment (I'm using draw.io) and then automatically generate the C code that implements the state machine. Here's the state machine I've created for the radio hardware.
?
?
?
I'm working on a separate state machine to control the state of the graphical display.
?
Here's how I imagine them all working together:
?
?
The software runs in a loop as shown in the diagram above. It performs three major functions:
?
Then go back to step 1 and repeat. This loop should take at most 10ms to execute in order to avoid buffer overflows in the IQ buffers.
?
I'm building this up from a blank canvas. I've spent most of my effort over the last few weeks learning how to use StateSmith and how to build an automated test environment using . I've now started to write code, starting with the signal processing, and writing unit tests for the code as I go. I've found the unit tests to be very helpful. If I decide to change a function's prototype or modify what the function does, I'll immediately know if that change breaks something somewhere else in the code. It should make the process of getting the code running on the Teensy much faster.
?
I'm going to clean up the code as I move it over, piece by piece, to this new structure -- remove dead code, apply consistent style formatting, minimize the use of global variables, and write tests for every function so we know what it's supposed to do and when it stops doing this.
?
?
?
?
?
|
||
Re: FW 66.9 bug
The Ver066.9 code doesn't have a menu option called "Display Options" -- which one did you select?
On Thursday, April 24th, 2025 at 2:35 PM, Tim via groups.io <w4yn@...> wrote:
|
||
Re: LPF Control Board addressing help
The daisy chain test sounds like it might be a clue. Does your radio find the BPF if that board is connected to the main board? It uses the same I2C bus, so this will confirm that the problem is not on the main board side. If adding the LPF board to the daisy then prevents the main board from discovering both the BPF and the LPF boards, then this implies that something on the LPF board is messing with the I2C lines, likely by pulling them high or low. If the test above indicates that the I2C lines are being messed with on the LPF board then check the other parts of the board where the I2C lines run for shorts.
On Thursday, April 24th, 2025 at 12:51 PM, Robert Luken W3RDL via groups.io <now.w3rdl@...> wrote:
|
||
Re: Kits and parts.
¿ªÔÆÌåÓýInvoice Incoming ? ? ? Dr. William J. Schmidt - K9HZ J62K(J68HZ) 8P6HK ZF2HZ PJ4/K9HZ VP5/K9HZ PJ2/K9HZ VP2EHZ ? Owner - Operator Big Signal Ranch ¨C K9ZC Staunton, Illinois ? Owner ¨C Operator Villa Grand Piton ¨C J68HZ Soufriere, St. Lucia W.I. Rent it: ? Moderator: North American QRO Group at Groups.IO. Moderator: Amateur Radio Builders Group at Groups.IO. ? email:? bill@... ? ? From: [email protected] <[email protected]> On Behalf Of Robert Luken W3RDL via groups.io
Sent: Thursday, April 24, 2025 12:56 PM To: [email protected] Subject: Re: [SoftwareControlledHamRadio] Kits and parts. ? Bill, I would like to order the following: 1 - 20W DL and 40dB Attenuator 1 - 20A Distribution Kit 1450 Lester Court Merritt Island, FL 32952 On 4/24/2025 11:37 AM, K9HZ via groups.io wrote:
-- 73 Bob W3RDL ?
|
||
Re: Kits and parts.
¿ªÔÆÌåÓýBill, I would like to order the following: 1 - 20W DL and 40dB Attenuator 1 - 20A Distribution Kit 1450 Lester Court Merritt Island, FL 32952 On 4/24/2025 11:37 AM, K9HZ via
groups.io wrote:
--
73
Bob W3RDL |