Sunday, November 10, 2024

500 Watt Antenna Tuner Part 8 Software and Microcontroller

 Controller Hardware and Programming Language Selection

This is a new iteration of this page.  I have kept the old page and included it at the end of this blog post series for anyone interested.

With the recommendation of a friend, Mike Rauch K2VPX, I started looking at the Raspberry Pi Pico.  I built a test frequency generator and the frequency measurement function for this tuner.  It worked well and I really liked what I saw.  The documentation is superb.  I also chose its native C programming environment for no other purpose than to keep things as simple as possible.

I also tested an interface between the Raspberry Pi Pico and the Mac over USB and I am satisfied that it works reasonably well.

To conserve pin count and keep the board layout simple, I have chosen the SPI interface and tested the software for driving it.  I am using three NCV7240ADPR2G relay drivers.  I have also decided to put the 3 relay drivers in series as shown by the data sheet.  The Raspberry Pi Pico SPI Chip Select pin makes a low to high transition at the end of each block of data, so it does not meet the requirements of cascading the three relay drivers.  The workaround is to operate the CSN pin software separate from the data transmission using the SPI library.  Here is the pin utilization for the microcontroller

  • 4 pins for the SPI interface.  I am using SPI1 and specific pins to make the board layout easier.
    • RX: GPIO12 (note, GPIO, not pin numbers)
    • CSN: GPIO13
    • SCK: GPIO14
    • TX: GPIO15
  • 2 analog pins for magnitude and phase of the reflection coefficient
    • Phase: GPIO26_ADC0
    • Magnitude: GPIO27_ADC1
  • 1 analog pin for power level input
    • Power: GPIO28_ADC2
  • 1 pin for frequency input
    • Frequency: GPIO10
  • 1 pin for gating the frequency measurement (so I am not shipping a high frequncy digital signal all over the printed wiring board)
    • Measure: GPIO11
Lot's of spare pins left.  The 12 bit A/D convertors and fast floating point arithmetic are both pluses.   But the true winners are the documentation and the SDK.

Design Concepts

My core design idea is to interface the tuner to my Stationmaster software and use its ability to manage the radio, the linear, and the tuner together.  As of right now, I don't have any concrete ideas for a local display.  I might just stick with setting limits on power and SWR and Power measurements and lighting a red LED.  Then the Stationmaster software can interrogate the tuner and display the results.

The Stationmaster software will be interfaced with the Pico over the USB interface.  The commands from the Stationmaster to tuner are formatted as follows:
  • Address (one byte)
  • Command (one byte)
  • Data bytes as needed (zero or more bytes)
  • Terminating semicolon ";" (one byte)
Other than the address byte, this is the same format as the Yaesu radio commands.

The replies to the commands will be formatted as follows:
  • Address (one byte) 
  • Command (one byte) - the same as the command received
  • Data bytes as needed (zero or more bytes) 
  • Terminating semicolon ";" (one byte)
There will be two sets of commands.  One set for normal operation and another set for testing of the tuner.

Operating Commands:
  • Test tuner (to see if the device at this USB port is the tuner) - returns Address, Command, ;
  • Bypass - returns Address, Command, (decrease power or done - one byte), ;
  • Measure power - returns Address, Command, two bytes of data,;
  • Tune - returns Address, Command, (decrease power, increase power, or done), ;
Testing Commands:
  • Read phase - returns Address, Command, two bytes of data, ;
  • Read magnitude - returns Address, Command, two bytes of data, ;
  • Read frequency - returns Address, Command, four bytes of data, ;
  • Read digits (of the A/D convertors) - returns Address, Command, two bytes of data, ;
  • Read volts (of the A/D convertors) - returns Address, Command, two bytes of data, ;
  • Read LC (for positive and negative phases) - returns Address, Command, four bytes of data,;
One of the challenges with this program is to make sure that the code is readable and maintainable and that is when this objective runs into the other objective which is to make for making the board layout as easy as possible.  That resulted in a completely random assignment of capacitor and inductor relays to relay driver pins from the sofware point of view.  The routing of the bits out of the microcontroller to the relay drivers is as follows (for IC numbers, see the schematics in the next section).
Microcontroller => IC3 => IC1 => IC2 => Microcontroller 
So the first 16 bit word that is shipped out drives the pins to IC2, the second word drives the pins in IC1 and the third word drives the pins in IC3.  Here is what I think will make the code easy to read and maintain.

  struct relay{
  	int wordNo; //word 0 to IC2, word 1 to IC1 and word 2 to IC3
  	int pos;    //positiion of the two bits driving the relay
  };
  
  struct relay capRelays[8] = 
  	{
    	{2, 5},
        {2, 3},
        {2, 2},
        (1, 6},
        {1, 4},
        {1, 2},
        {1, 1},
        (0, 6},
    };
    
  struct relay indRelays[8] = 
  	{
    	{0, 3},
        {0, 4},
        {0, 5},
        {1, 0},
        {1, 3},
        {1, 5},
        {1, 7},
        {2, 4},
    };
    
  struct relay bypass[2] =
    {
    	{2, 6}, //input
        {0, 0}, //output
    };
    
  struct relay caps[2] =
    {
    	{2, 7}, //input
        {0, 7}, //output
    };
    
  struct relay comps[2] =
    {
    	{0, 2}, //series capacitor, close to short
        {0, 1}, //shunt inductor, close to engage
    };
  uint16_t words[3] = {0x0000, 0x0000, 0x0000}

The approach will be to locate the "1" position in the relay or capacitor position byte (outcome of the tuning algorithm), index into the capRelays or indRelays respectively, then pick the word number and change the bit positon as indicated by the relay driver datasheet. At least for now, my plan is to change on relay position at time with a little bit of delay between the changes to minimize noise.

To convince myself that the serial connection of the relay drivers works and also to debug the software for driving the relays, I am building a prototype board of the Raspberry Pi Pico, the three relay drivers and a bunch of LEDs and two relays.  It also gives me a chance to test the 5 volts feed circuit that I did not test in my previous prototype build.  Here it is.



 

I add more documentation to the code and link the Github page.




No comments:

Post a Comment