Friday, October 16, 2026

A Quick-Deploy Guying System for My Hustler 4BTV



A Quick-Deploy Guying System for My Hustler 4BTV

For some time now, I've been looking for a solution to a problem that many of us who use vertical antennas can relate to: what do you do when the forecast calls for high winds or freezing rain?

Living near the ocean , we aren't strangers to strong winds. Between the occasional hurricane or its remnants passing through the area and the frequent windstorms we experience, there have been plenty of occasions when I've felt it necessary to take my antenna down for protection. When winds reach 70 km/h or higher, or freezing rain is in the forecast, I'd rather be safe than sorry.


The obvious solution is to guy the antenna. However, I wasn't keen on installing a permanent guying system. Our lot is already small, and the last thing I wanted was to have guy ropes permanently stretched across the yard. I needed something that would provide additional support when the weather turned nasty but could be quickly deployed and put away when it wasn't needed.

Space guy ring 
After giving it some thought, I came up with a simple solution that seems to fit the bill.

Putting the Pieces Together

The first item on my shopping list was a set of guy rings from DX Engineering. They offer a set of two specifically designed for Hustler vertical antennas. The rings are pre-drilled and UV-resistant, making them well suited to outdoor use.

Next came the rope. After looking at several options, I settled on 4 mm polyester diamond-braided rope. Polyester diamond braid offers low stretch and good resistance to UV exposure, moisture, rot, and mildew, making it a sensible choice for an outdoor installation.

For securing and being able to adjust the tension on the ropes, I chose Nite Ize CamJam carabiners. The models I purchased have a stated maximum load rating of 280 pounds. They offer a convenient way to secure the guy ropes without having to tie and untie knots every time I want to use the system.

With those three components in hand, I was ready to put my idea into practice.

Finding the Right Position for the Guy Ring

The first challenge was deciding where to install the guy ring on the antenna.

 Guy ring above 20m trap


DX Engineering recommended positioning it just below the capacitance hat, which sits above the 20-metre trap. Installing it there required moving the capacitance hat upward, which produced some small changes in SWR. The SWR on 40 meters increased slightly, while 20 and 15 meters actually improved. There was no noticeable change on 10 meters.

The changes were minor, but I wasn't entirely happy with the physical installation. Once the guy ring was in place, I could see that it rested on the plastic cap at the top of the 20-metre trap. I was concerned that the pressure and movement over time could damage the cap, so I decided to look for another option.

I eventually moved the guy ring to the bottom of the 20-metre trap. This put it only about six inches lower than the originally recommended position, which I felt was a reasonable compromise for supporting the antenna. With the ring in this position, I found no noticeable change in SWR.

No Ground Anchors Required

The next challenge was figuring out where to attach the guy ropes.

I decided to use three guying points, but I didn't want to install ground anchors. Since the antenna would remain un-guyed most of the time, permanent anchors in the yard would be an inconvenience. I could easily imagine running over one with the lawn mower or spending half the winter trying to remember where they were buried under the snow!

Where I decided to place the guy ring

Fortunately, I already had three suitable attachment points: two eye hooks mounted on my deck and another on the shed.

These would serve as the anchor points for the three guy ropes, allowing me to deploy the system when needed without leaving anything stretched across the yard the rest of the time.

I permanently attached the guy ropes to the guy ring and secured the excess rope at the base of the antenna with Velcro straps. Everything could remain neatly tucked away until the weather called for extra support.

Making Deployment Quick and Easy

During my first trial run, I discovered that getting the tension right on all three ropes took a little more back-and-forth adjustment than I had anticipated.

Tension one rope affected the others, so it took a few attempts to get everything where I wanted it. Once I was satisfied with the arrangement, I marked each rope with a permanent marker at the point where it passed through the CamJam tension mechanism.

These marks provide a reference for future deployments. Rather than starting from scratch each time, I can use the marks to get the ropes close to their previously established positions and then make any necessary adjustments.

The idea is to turn what could otherwise be a time-consuming job into a quick and straightforward operation when bad weather is approaching.

Naturally, I'll still check the tension and overall stability rather than relying entirely on the marks.

And Now for the Funny Part!
Guy ring 

You would think that living near the ocean, with the threat of hurricanes and strong fall storms, would have given me plenty of opportunities to test my new system.

Well, here's the funny part: since I finished setting everything up, absolutely nothing has happened!

We went through the fall without a single hurricane affecting our area, despite this being a part of the country where storm systems and their remnants are always a possibility. Even the usual bouts of nasty weather seem to have taken a break.

Perhaps I should have built this system years ago. It appears that the mere thought of being prepared is enough to keep the storms away!

CamJam 

Of course, winter is still ahead of us, and freezing rain and strong winds are always possibilities here in New Brunswick. Sooner or later, I'll get the opportunity to see how well the system works in real-world conditions.

For now, I'm pleased with the result. I have a way to add support to my Hustler 4BTV when the weather warrants it, without permanently cluttering up my small lot. And when the skies clear, I can put everything away and return the yard to normal.

Guy rope secured at base of antenna


Friday, October 2, 2026

The Google gadget is back and running

 


It seems Google has finally gotten around to fixing its Blogs I Follow gadget! The original issue was that it had completely stopped updating. You can read my previous post to see the workaround I used while waiting for the folks at Google to address the problem.

Below is the code I used to bring back the official Blogs I Follow gadget while hiding the temporary HTML/JavaScript fix.

To keep things organized, I saved both code snippets in OpenOffice. That way, if Google's gadget ever breaks again, it’s a quick copy and paste to deploy the temporary fix, and another simple copy and paste to switch back once it's resolved.

Note: The only change you will need to make is replacing my followed blog URLs with your own. I detailed step-by-step instructions on how to do this in the post linked above. Also you do this at your own risk. 


 HTML

<div style="display: none;">

  <div id="blogger-bloglist-feed">
    <p style="font-size: 0.9em; color: #ffffff; margin: 0;">Loading blog updates...</p>
  </div>

  <style>
    .bloglist-item {
      margin-bottom: 14px !important;
      padding-bottom: 10px !important;
      border-bottom: 1px dashed rgba(255, 255, 255, 0.3) !important;
      font-family: inherit !important;
    }
    /* Blog Name */
    .bloglist-name {
      display: block !important;
      font-size: 1.05em !important;
      font-weight: bold !important;
      color: #ffffff !important;
      margin-bottom: 4px !important;
      line-height: 1.3 !important;
    }
    /* Article Post Title Link */
    a.bloglist-link,
    a.bloglist-link:visited {
      display: block !important;
      font-size: 1.0em !important;
      font-weight: normal !important;
      color: #ffffff !important;
      text-decoration: none !important;
      line-height: 1.3 !important;
    }
    a.bloglist-link:hover {
      text-decoration: underline !important;
    }
    /* Updated Date */
    .bloglist-date {
      font-size: 0.85em !important;
      color: #ffffff !important;
      margin-top: 3px !important;
      display: block !important;
      opacity: 0.9 !important;
    }
  </style>

  <script>
    (function() {
      var followedFeeds = [
        "http://ae5x.blogspot.com/feeds/posts/default",
        "https://www.kb6nu.com/feed/",
        "http://w2lj.blogspot.com/feeds/posts/default",
        "http://pa1b-qrp.blogspot.com/feeds/posts/default",
        "https://ve7sar.blogspot.com/feeds/posts/default",
        "https://swling.com/blog/feed/",
        "https://www.arrl.org/arrl.rss",
        "http://ve3clq.blogspot.com/feeds/posts/default",
        "https://wb3gck.com/feed/",
        "https://tommcquiggan.blogspot.com/feeds/posts/default",
        "http://ve3vn.blogspot.com/feeds/posts/default",
        "https://ke9v.net/feed.xml",
        "https://kg3v.com/feed/",
        "http://offgridham.com/feed/",
        "http://pe4bas.blogspot.com/feeds/posts/default",
        "https://qrper.com/feed/",
        "https://www.amateurradio.com/feed/",
        "https://k9zw.wordpress.com/feed/"
      ];

      var container = document.getElementById("blogger-bloglist-feed");
      var loadedCount = 0;
      var items = [];

      // Helper function to fetch feeds that rss2json fails to parse
      async function fetchXmlFallback(feedUrl) {
        try {
          var proxyUrl = "https://api.allorigins.win/get?url=" + encodeURIComponent(feedUrl);
          var res = await fetch(proxyUrl);
          var data = await res.json();
          if (!data.contents) return null;
          
          var parser = new DOMParser();
          var xmlDoc = parser.parseFromString(data.contents, "text/xml");
          var item = xmlDoc.querySelector("item") || xmlDoc.querySelector("entry");
          if (!item) return null;
          
          var title = item.querySelector("title") ? item.querySelector("title").textContent : "Untitled";
          var link = item.querySelector("link") ? item.querySelector("link").textContent : "#";
          
          if (!link || link.trim() === "") {
            link = item.querySelector("link") ? item.querySelector("link").getAttribute("href") : "#";
          }
          
          var dateStr = item.querySelector("pubDate") ? item.querySelector("pubDate").textContent :
                        (item.querySelector("published") ? item.querySelector("published").textContent :
                        (item.querySelector("updated") ? item.querySelector("updated").textContent : ""));
                        
          var blogTitle = (xmlDoc.querySelector("channel > title") ? xmlDoc.querySelector("channel > title").textContent :
                          (xmlDoc.querySelector("feed > title") ? xmlDoc.querySelector("feed > title").textContent : "Blog"));
                          
          var pubDateObj = new Date(dateStr);
          return {
            blogTitle: blogTitle,
            title: title,
            link: link,
            date: pubDateObj,
            dateStr: isNaN(pubDateObj) ? "" : pubDateObj.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })
          };
        } catch (e) {
          return null;
        }
      }

      followedFeeds.forEach(function(feedUrl) {
        var apiUrl = "https://api.rss2json.com/v1/api.json?rss_url=" + encodeURIComponent(feedUrl);
        fetch(apiUrl)
          .then(function(res) { return res.json(); })
          .then(async function(data) {
            if (data.status === "ok" && data.items && data.items.length > 0) {
              var blogTitle = data.feed.title || "Blog";
              var latestPost = data.items[0];
              var pubDateObj = new Date(latestPost.pubDate);
              items.push({
                blogTitle: blogTitle,
                title: latestPost.title,
                link: latestPost.link,
                date: pubDateObj,
                dateStr: isNaN(pubDateObj) ? "" : pubDateObj.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })
              });
            } else {
              var fallbackItem = await fetchXmlFallback(feedUrl);
              if (fallbackItem) items.push(fallbackItem);
            }
          })
          .catch(async function(err) {
            var fallbackItem = await fetchXmlFallback(feedUrl);
            if (fallbackItem) items.push(fallbackItem);
          })
          .finally(function() {
            loadedCount++;
            if (loadedCount === followedFeeds.length) {
              if (items.length > 0) {
                items.sort(function(a, b) { return b.date - a.date; });
                var htmlBuffer = "";
                items.forEach(function(item) {
                  htmlBuffer += '<div class="bloglist-item">';
                  htmlBuffer += '<span class="bloglist-name">' + item.blogTitle + '</span>';
                  htmlBuffer += '<a class="bloglist-link" href="' + item.link + '" target="_blank" rel="noopener">' + item.title + '</a>';
                  if (item.dateStr) {
                    htmlBuffer += '<span class="bloglist-date">Updated: ' + item.dateStr + '</span>';
                  }
                  htmlBuffer += '</div>';
                });
                container.innerHTML = htmlBuffer;
              } else {
                container.innerHTML = "<p style='font-size:0.85em; color: #ffffff;'>No recent updates available.</p>";
              }
            }
          });
      });
    })();
  </script>

</div>

Monday, September 28, 2026

Q5 Interview with WRTC team MB1I

For some time now, I’ve been following Q5 on YouTube. It covers many aspects of contesting, POTA, DXpeditions, and other areas of amateur radio.

Their latest video deals with the WRTC cheating controversy. It is a one-on-one interview with Braco, E77DX, and Sven, DJ4MX, from WRTC Team MB1I.

 https://www.youtube.com/watch?v=Y_1q8lqH4kI

If you’re interested, I’ve included the link below. If not, I would still encourage you to check out their YouTube channel. They have a large library of shows covering a wide range of amateur radio topics.

https://www.youtube.com/@q5hamradio 


Monday, September 21, 2026

How to fix your gadget Blogs I follow using HTML

 I have been asked by a few bloggers for the details on what I did to overcome the issue with the blogs I follow widget with Blogger blogs not working. So below are the details of that I and AI together came up with. 

Those of you who have a blogger blog sign into it and on the left hand side go down to Layout and click on it. On the right side you will see "Add a Gadget" click on that to expand to a menu of Gadgets. Now find the Gadget called "HTML/JAVAScript" and click on that. 

A new HTML/JavaScript window will open and you first put a title. I just called it "Blogs I follow" In the the space below is where you add the HTML coding. This coding will add a new Blogs I follow to your blog. Below is the script and before you cut and paste it some changes need to be made from the code I posted. They are very easy changes and actually you really do not need to do anything as AI can make the changes for you. In the code you will notice a section STEP 1 and some instructions to enter your blog you follow URL's. An easy way to do this is to sign into your blog, go to layout and to the left you will see Gadgets. Look for the gadget "blogs I follow" in the lists of gadgets and click edit. Highlight all the URL's of the blogs your follow and post the code below into the AI of your choice and ask also paste the URL's of the blogs you follow and ask AI to add them at step 1 in the code. Then take this code with the URL's inserted and cut and paste it into the gadget HTML/JavaScript. Click save and give it a go in your blog. Also in the HTML code below is a line that will hide your gadget Blogs I follow. This way you do not have 2 Blogs I follow. 

 NOTE: Always keep a unedited version of the code incase something does not workout. The code below worked great for me but I take no responsibility how things may work out at your end. As a side... if you try the HTML/JavaScript and it messes things up just turn it off and go back to the broken gadget "Blogs I follow"   

The HTML code 

HTML

<div id="blogger-bloglist-feed">
  <p style="font-size: 0.9em; 
            color: #ffffff; 
            margin: 0;">
    Loading blog updates...
  </p>
</div>

<style>
  .bloglist-item {
    margin-bottom: 14px !important;
    padding-bottom: 10px !important;
    border-bottom: 1px dashed 
      rgba(255, 255, 255, 0.3) !important;
    font-family: inherit !important;
  }
  .bloglist-name {
    display: block !important;
    font-size: 1.05em !important;
    font-weight: bold !important;
    color: #ffffff !important;
    margin-bottom: 4px !important;
    line-height: 1.3 !important;
  }
  a.bloglist-link, 
  a.bloglist-link:visited {
    display: block !important;
    font-size: 1.0em !important;
    font-weight: normal !important;
    color: #ffffff !important;
    text-decoration: none !important;
    line-height: 1.3 !important;
  }
  a.bloglist-link:hover {
    text-decoration: underline !important;
  }
  .bloglist-date {
    font-size: 0.85em !important;
    color: #ffffff !important;
    margin-top: 3px !important;
    display: block !important;
    opacity: 0.9 !important;
  }
  /* Hides original broken gadget */
  #BlogList1 { 
    display: none !important; 
  }
</style>

<script>
(function() {

  /* ====================================
     STEP 1: ADD YOUR BLOGS HERE
     Copy your list of blog URLs and paste 
     them between the brackets [] below.
     ==================================== */
  var followedFeeds = [
    "http://ae5x.blogspot.com/feeds/posts/default",
    "https://www.kb6nu.com/feed/",
    "http://w2lj.blogspot.com/feeds/posts/default"
  ];
  /* ====================================
     DO NOT EDIT BELOW THIS LINE
     ==================================== */

  var container = 
    document.getElementById(
      "blogger-bloglist-feed"
    );
  var loadedCount = 0;
  var items = [];

  async function fetchXmlFallback(feedUrl) {
    try {
      var proxyUrl = 
        "https://api.allorigins.win/get?url=" + 
        encodeURIComponent(feedUrl);
      var res = await fetch(proxyUrl);
      var data = await res.json();
      if (!data.contents) return null;

      var parser = new DOMParser();
      var xmlDoc = 
        parser.parseFromString(
          data.contents, 
          "text/xml"
        );
      var item = 
        xmlDoc.querySelector("item") || 
        xmlDoc.querySelector("entry");
      if (!item) return null;

      var title = item.querySelector("title") ? 
        item.querySelector("title").textContent : 
        "Untitled";
      var link = item.querySelector("link") ? 
        item.querySelector("link").textContent : 
        "#";
      if (!link || link.trim() === "") {
        link = item.querySelector("link") ? 
          item.querySelector("link")
            .getAttribute("href") : "#";
      }

      var dateStr = 
        item.querySelector("pubDate") ? 
        item.querySelector("pubDate").textContent :
        (item.querySelector("published") ? 
         item.querySelector("published").textContent :
        (item.querySelector("updated") ? 
         item.querySelector("updated").textContent : ""));
      
      var blogTitle = 
        (xmlDoc.querySelector("channel > title") ? 
         xmlDoc.querySelector("channel > title").textContent :
        (xmlDoc.querySelector("feed > title") ? 
         xmlDoc.querySelector("feed > title").textContent : 
         "Blog"));

      var pubDateObj = new Date(dateStr);

      return {
        blogTitle: blogTitle,
        title: title,
        link: link,
        date: pubDateObj,
        dateStr: isNaN(pubDateObj) ? "" : 
          pubDateObj.toLocaleDateString(
            undefined, 
            { month: 'short', day: 'numeric' }
          )
      };
    } catch (e) {
      return null;
    }
  }

  followedFeeds.forEach(function(feedUrl) {
    var apiUrl = 
      "https://api.rss2json.com/v1/api.json?rss_url=" + 
      encodeURIComponent(feedUrl);

    fetch(apiUrl)
      .then(function(res) { 
        return res.json(); 
      })
      .then(async function(data) {
        if (data.status === "ok" && 
            data.items && 
            data.items.length > 0) {
          var blogTitle = 
            data.feed.title || "Blog";
          var latestPost = data.items[0];
          var pubDateObj = 
            new Date(latestPost.pubDate);

          items.push({
            blogTitle: blogTitle,
            title: latestPost.title,
            link: latestPost.link,
            date: pubDateObj,
            dateStr: isNaN(pubDateObj) ? "" : 
              pubDateObj.toLocaleDateString(
                undefined, 
                { month: 'short', day: 'numeric' }
              )
          });
        } else {
          var fallbackItem = 
            await fetchXmlFallback(feedUrl);
          if (fallbackItem) 
            items.push(fallbackItem);
        }
      })
      .catch(async function(err) {
        var fallbackItem = 
          await fetchXmlFallback(feedUrl);
        if (fallbackItem) 
          items.push(fallbackItem);
      })
      .finally(function() {
        loadedCount++;
        if (loadedCount === followedFeeds.length) {
          if (items.length > 0) {
            items.sort(function(a, b) { 
              return b.date - a.date; 
            });

            var htmlBuffer = "";
            items.forEach(function(item) {
              htmlBuffer += 
                '<div class="bloglist-item">';
              htmlBuffer += 
                '<span class="bloglist-name">' + 
                item.blogTitle + '</span>';
              htmlBuffer += 
                '<a class="bloglist-link" href="' + 
                item.link + 
                '" target="_blank" rel="noopener">' + 
                item.title + '</a>';
              if (item.dateStr) {
                htmlBuffer += 
                  '<span class="bloglist-date">' +
                  'Updated: ' + item.dateStr + 
                  '</span>';
              }
              htmlBuffer += '</div>';
            });
            container.innerHTML = htmlBuffer;
          } else {
            container.innerHTML = 
              "<p style='font-size:0.85em; " +
              "color: #ffffff;'>" +
              "No recent updates available.</p>";
          }
        }
      });
  });
})();
</script>



This is how the blog URL section looks in my HTML/JavaScrip gadget.
<script> (function() { var followedFeeds = [ "http://ae5x.blogspot.com/feeds/posts/default", "https://www.kb6nu.com/feed/", "http://w2lj.blogspot.com/feeds/posts/default", "http://pa1b-qrp.blogspot.com/feeds/posts/default", "https://ve7sar.blogspot.com/feeds/posts/default", "https://swling.com/blog/feed/", "https://www.arrl.org/arrl.rss", "http://ve3clq.blogspot.com/feeds/posts/default", "https://wb3gck.com/feed/", "https://tommcquiggan.blogspot.com/feeds/posts/default", "http://ve3vn.blogspot.com/feeds/posts/default", "https://ke9v.net/feed.xml", "https://kg3v.com/feed/", "http://offgridham.com/feed/", "http://pe4bas.blogspot.com/feeds/posts/default", "https://qrper.com/feed/", "https://www.amateurradio.com/feed/", "https://k9zw.wordpress.com/feed/" ];