You can download the listing PDF here.
This is the “bare bones” version of the BITX Raduino operating system. It does nothing but provide tuning. No monitoring, no metering, just plain single side band. And only lower side band at that. There is nothing wrong with that! After all, this transceiver was designed to be cheap and usable and it has achieved that famously!
In this version I used just the original parts that were furnished with the basic radio. The potentiometer that originally tuned the transceiver is still used for that purpose. In fact, No physical changes are necessary, just reload this sketch into the Raduino module and it is done! Of course, if you want to change it back to the original, it is just as easy. Simply reload the original software and it goes back to what it was.
Stability. Using the original direct voltage-controlled oscillator scheme depended upon the stability of the internal reference voltage and the potentiometer control. If you wanted absolute control it was not available. Listening to AM or CW was difficult at best. You could tune within 100 Hz if you were very careful, but that was all that you could expect.
By using this sketch, you can tune in 1 Hz increments and have crystal-controlled stability.
The program source code begins with a “comment block” identifying this particular sketch: Who wrote it, what version, and when. This is important since we all try to improve our work and it constantly changes. It’s good to know what version this particular sketch is, especially if communicating a question or comment to someone else. If it uses a library to simplify the code then it is helpful to know the precise library and version for the same reason.
The introductory comment block also contains a bit of legal stuff. In this case it declares that this source code is donated to the general public but keeps anyone else from claiming total ownership and preventing anyone else (including the author!) from using it. Strange times.
Now the actual program begins. The Arduino compiler is told to include two libraries; One to control the frequency synthesizer (the Si5351) and the other to control the display. Statements are added to clarify the names of those devices and the pin allocations. These libraries actually contain the bulk of the programming, all wrapped and available for use by other programs. A huge savings in time and effort for the programmer, and we don’t have to type volumes of it repeated each time. Keeping the code small makes it easier to understand.
The next block assigns the “variables”. These are locations in memory that we assign names and use for storing information that will be used by the program. The location I named “tune” is assigned as a simple integer since it will always be a small number and doesn’t need a lot of memory. The comment after it explains that it will store the tuning knob position value. The next variable can be a large number; The count of milliseconds between events that we use to provide timing. The BFO variable is the frequency of the individual Beat Frequency Oscillator. This will be slightly different with each BITX. If you want precise frequencies then you need to measure this and enter your particular frequency here (where this build was 11.99855 MHz for instance). Finally, the Local Oscillator value is declared to be calculated by subtracting the operating frequency from the BFO. In this case, it also declares that, when you start this program, it will initialize on 7.2 MHz. Both of these last two variables are assigned as floating point type numbers to simplify calculations and display.
Having established those variables we now begin our subroutines. These are named and have empty parentheses after them. “void” means that they are not expected to return to the program flow with any information in particular. The first thing we do is set up the system. “setup(); “ sounds reasonable, eh?
The LCD display is initialized as a 16 character, 2 line display (since that what is supplied). Then the synthesizer is initialized. Here is an important number that needs to be input if you want precision frequencies. Like in the BFO frequency, we need to place the frequency of the Si5351 reference oscillator at the end of that first line (where 24999020L is on this example). It will be somewhere near 25 MHz and can be determined by running this calibration routine. Don’t forget to follow it by the letter “L” declaring it to be a Long integer type number, the comma, and a zero, just like it was.
After those initializations the program runs a small routine to display the sketch name and version for two seconds so that the user will know what is loaded into the BITX. How would you tell otherwise? This is a convenience, not necessary really, and I have not done this on many of my sketches. However, I have grown to appreciate it.
Loop() is actually the main program. It does exactly that: It reads the knob position voltage and, if it is within the “Idle” zone (between 560 and 464) and nothing has changed then it just jumps to the beginning of the loop and does it all over again. It does this many thousands of times each second, just waiting for that knob to move.
If the knob gets turned clockwise far enough that it exceeds the 560 limit, the program jumps to the “up()” subroutine (these are called “functions” in Arduino) if the operating frequency is below the limit set in the first line (7.3 MHz) then the Local Oscillator frequency change is computed and programmed into the synthesizer chip. I used a differential exponent algorithm so that tuning rates increase exponentially the farther the knob departs from the idle zone.
After the Si5351 gets re-programmed, the program waits 300 milliseconds so that the operator isn’t rushed. The time post is then reset so that, when the program returns to the loop, the frequency change is displayed.
That sort of action is also applied if the tuning knob is turned counter-clockwise. In that case the “down()” function is engaged so that the BITX is tuned lower in frequency instead of higher. The lower frequency limit is established here at 7.0 MHz but can be changed as needed.
The display is controlled with the “show()” function. It first clears the screen of any previous display, sets up to print on the top line, then calculates the displayed frequency by subtracting the Local Oscillator frequency from the Beat Frequency Oscillator frequency, dividing it by 1,000 (so that it will read out as KiloHertz) and displaying it to 3 digits. This makes it easier for some of us to read. Not so many zeros to count.
Following the frequency display is a tuning indicator to help indicate where the knob is positioned. Inside the “Idle” zone, an “I” is shown. Clockwise from that a “ > “ is displayed, CCW is “ < “. Then a “KHz” is displayed since there was vacant room and it fit (and only “cost” one line!).
The only explaining left that I can think of is the need for the timing posts. Some builders have experienced noises from the Raduino. Without the timing posts, the Raduino is constantly updating the display and the synthesizer. These noises are caused by lead placement or inadequate voltage filtering and are usually only heard on low efficiency antennas or dummy loads. When the BITX is connected to a fair antenna then background noise usually covers it up. By eliminating unnecessary updates, this noise is largely abated.
You can download the listing PDF here.
This sketch includes straight-key (including semi-automatic bugs) CW operation. The hardware changes are documented here and need to be in place for this to work. Most of the source code remains the same.
In the variable assignments I have added a “offset” integer value. This is how far below the displayed frequency that the transmitted signal will be placed. This value also is used as the side tone frequency. That way, when the received signal is tuned to where the tone matches the side tone frequency, the operator is quite close to the same frequency. This is called “spotting”. If we use 700 Hz for an offset then the side tone will be 700 Hz and the transmit frequency will be 700 Hz lower than the frequency displayed on the BITX.
Another new variable is “QSK” and is set by number of seconds (I use 1.5 seconds). This is how long the BITX stays in transmit mode before switching to receive. This is usually known as semi-break-in. The long delay keeps the relays from changing back and forth from transmit to receive as often. Very distracting. If you tend to send slowly, increase this value to where it is comfortable.
Since we are adding a key jack, a side tone output, and software control of T/R switching and a transmit IF amplifier disable, three digital pins need to be provisioned. I used D5 through D7. Pin D5 is used for key input so the mode is set as an input and a high-value pull-up resistor is enabled. You don’t need an external resistor to supply a voltage! Pin D6 is set up as the side tone output and D7 is used to output the control of the transmit/receive hardware.
The CW() function uses the CLK1 output of the synthesizer chip to generate the transmit frequency directly. By using just one command to activate it, delay is reduced to less than a millisecond so there is no perceivable hesitation at speeds to 50 WPM. One of those undocumented shortcuts that I discovered.
You can download the listing PDF here.
Time to lose the “simple” part of the sketch name. This sketch builds upon the previous three and adds a signal strength indicator, an RF power monitor, a VSWR bridge, and an Iambic keyer!
In the variables, I included one for CW speed for the keyer, one for the S meter value, one each for forward and reverse RF power readings, and a variable to keep count of the number of iterations in the keyer function as an additional timing monitor.
Another digital pin (D4) is added to monitor the “dash” input if a paddle is used. Analog pin A1 is called to service to read the S meter value, A6 is used to measure the voltage from the keyer speed control. A3 measures the voltage from the forward power of the bridge detectors and A2 measures the associated reflected power.
Those forward and reflected power measurements are done using an algorithm developed by regressing empirical test results. During the measurement period (arbitrarily set at 2 seconds here) the peak values are stored for display. This stabilizes the displayed figures and minimizes update noise. VSWR is computed in the display routine using the “ratio of square roots” method.
The S meter readings are much simpler, derived from signal generator tests where S9 corresponds to 50 microvolts. Signal levels often differ with individual boards so exact calibration is up to the builder.
To make room for all of the displayed items, the S meter is displayed until power output over 1 watt is detected and is then it is replaced by the RF measurements.
The iambic keyer function is called when one of the paddle contact closures is detected and the speed control is set above 10 Words Per Minute. The length of the primary element (dot or element space) is determined by the speed control voltage. The selected element (dot or dash) is then formed and transmitted followed by the element space period. This is the same method that I developed in the PIC Keyer project .