Monday, February 7, 2022

Retirement Clock Goes Digital

 

-----

We overheard in a conversation recently something like: "Now that I'm retired I really only focus on what day of the week it is and the general time of day."  We then discovered this awful looking Day of the Week Clock and the vision of a more modern version came to mind.

-----

The rig is based around this MakerFocus ESP32 Development Board mainly because it works with the Arduino IDE and has WiFi with a display on board.   The code (source below) gets it's time/date from a NTP server and then simply figures out and displays the day of the week and what percentage of the day has past.  Evidently this is all the critical information needed to guide the non-working through their day.

-----

To dress up the look a case was 3D printed.  After seeing the result we needed to celebrate with a beer.   As shown in the video below it was a bit early in the day for a drink, but as the ol' saying goes "It's 71% somewhere!".

-----

Retirement Clock Source Code:

/*
 * HelTec Automation(TM) ESP32 Series Dev boards OLED "Retirement Clock"
 * Adruino IDE Board Setting: WiFi Kit32, Disabled, 240MHz, 921600, None
 *
 * "Retirement Clock" shows only Day of Week and percentage time left in the day.
 *  
 * FEB 2022
 * Search whiskeytangohotel.com for project details.
 *
*/

#include "Arduino.h"
#include "heltec.h"

#include <TimeLib.h>
#include <WiFi.h>
#include <WiFiUdp.h>

const char ssid[] = "xxxxxxx";  //  your network SSID (name)
const char pass[] = "xxxxxxx";       // your network password
long Sync_Delay = 60000;  //  60000 is sync every ten minutes,  We aren't going for precision here. LOL

int DOWNUM = 0;     //  DOWNUM from NTP (expect 0 - 6)
String DOW = "DOW";  // DOWNUM to a Day of Week String
int hourNUM = 0;    //  hour() value from NTP
float minuteNUM = 0;   // minute() value from NPT

// NTP Servers:
static const char ntpServerName[] = "pool.ntp.org";
const int timeZone = 0;     // leave as 0 for UTC.  We do the offset math in void setup

WiFiUDP Udp;
unsigned int localPort = 8888;  // local port to listen for UDP packets

time_t getNtpTime();
void digitalClockDisplay();
void printDigits(int digits);
void sendNTPpacket(IPAddress &address);

void setup() {
  //NTP setup
  Serial.begin(115200);
  while (!Serial) ; // Needed for Leonardo only
  delay(250);
  Serial.println("TimeNTP");
  Serial.print("Connecting to... ");
  Serial.println(ssid);
  WiFi.disconnect();
  WiFi.mode(WIFI_MODE_STA);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.print("IP number assigned by DHCP is: ");
  Serial.println(WiFi.localIP());
  Serial.println("Starting UDP");
  Udp.begin(localPort);
  Serial.print("Local port: ");
//  Serial.println(Udp.localPort());
  Serial.println("waiting for sync... ");
  setSyncProvider(getNtpTime);
  setSyncInterval(Sync_Delay);  //   defines how often to check NTP time

  // Hetec setup
  Heltec.begin(true /*DisplayEnable Enable*/, false /*LoRa Disable*/, true /*Serial Enable*/);
  Heltec.display->flipScreenVertically();
  Heltec.display->setFont(ArialMT_Plain_24);
} // end setup link

time_t prevDisplay = 0; // when the digital clock was last displayed timer

void loop() {   // main program loop
  if (timeStatus() != timeNotSet) {
    if (now() != prevDisplay) { //update the display only if time has changed
      prevDisplay = now();
    }
  }

  // Parse time info and send info to serial monitor (for debug)
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(".");
  Serial.print(month());
  Serial.print(".");
  Serial.print(year());
  Serial.print(" : ");

  if (int(year()) < 2022) {
     Serial.print(String(int(year())) + " is the NTP server year.  That aint right, so try again!!!");
     Serial.println();      
     setup();
  }   // the NTP server return something 'wierd' (probably 1970) so try again  

  //Covert Time in percent of day completed.  Midnight Local = 0%, Noon Local = 50%  
  minuteNUM = minute();
  hourNUM =   int(hour());  
  // manually adjust hourNUM and minuteNUM for debug
  // hourNUM =  5;    // valid values are INTERGERS 0 thru 24
  // minuteNUM = 49;    // valid values are INTEGERS 0 thru 60  

  minuteNUM = minuteNUM / 60;    // covert minutes to 'fraction'  
  hourNUM = hourNUM - 6;   // hourNUM is in UTC.   Adjust to local.   -6 = CST, -5 = CDT, 0 = UTC
  DOWNUM = int(weekday());
   
  // Calculate percentage of the day pasted into 'progress'
  int progress = round(   (  ((hourNUM + minuteNUM))   /  24   )  * 100    );
  if (progress < 0) {   // it's past UTC midnight and the timezone offset created a negative %
    progress = 100 + progress;
    DOWNUM = DOWNUM -  1;
  }  //end progress < 0

  // Convert DOWNUM into printable String.  Sunday is 1
  if (DOWNUM  == 1) { DOW = "SUN"; }
  if (DOWNUM  == 2) { DOW = "MON"; }
  if (DOWNUM  == 3) { DOW = "TUE"; }
  if (DOWNUM  == 4) { DOW = "WED"; }
  if (DOWNUM  == 5) { DOW = "THU"; }
  if (DOWNUM  == 6) { DOW = "FRI"; }
  if (DOWNUM  == 7) { DOW = "SAT"; }

  Serial.print(String(int(weekday())) + " is " + DOW);
  Serial.println();   
  Serial.print(String(hourNUM) + " + " + String(minuteNUM) + " = " + String(progress) + "%");
  Serial.println();
 
  // clear the display
  Heltec.display->clear();

  // Draw the Precent of Day pasted onto progress bar
  Heltec.display->drawProgressBar(0, 0, 127, 20, progress);

  // Label the Day Of Week and percentage as String
  Heltec.display->setTextAlignment(TEXT_ALIGN_CENTER);
  Heltec.display->drawString(60, 31, DOW + " " + String(progress) + "%");
  // Write buffer to Heltec display
  Heltec.display->display();
 
  delay(5000); // wait some.  we are in no hurry to update the screen
}  // end void loop main program


void printDigits(int digits)
{
  // utility for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/*-------- NTP code ----------*/

const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

time_t getNtpTime()
{
  IPAddress ntpServerIP; // NTP server's ip address

  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  Serial.println("Transmit NTP Request");
  // get a random server from the pool
  WiFi.hostByName(ntpServerName, ntpServerIP);
  Serial.print(ntpServerName);
  Serial.print(": ");
  Serial.println(ntpServerIP);
  sendNTPpacket(ntpServerIP);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Serial.println("Receive NTP Response");
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  Serial.println("No NTP Response :-(");
  return 0; // return 0 if unable to get the time
}

// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

-----

Friday, January 21, 2022

Wireless Charger Checker

-----

Charging your phone, watch, earbuds, etc. from a wireless charger sometimes doesn't work.   Most of the time it is due to poor alignment to the charge point.   Of course, it could be that the wireless charger is broken or simply unplugged.

This quick DIY tool helps verify that the charger is plugged in as well as determine the wireless charger's "sweet spot".

-----

-----

The build is about as cheap and simple is it can be.  If you have trouble building the rig from the image below you may be following the wrong project site.  ;)

-----

-----
 

Saturday, October 2, 2021

Elenco Resistor Substitution Kit

 

-----

We built the Elenco Capacitor Substitution Kit and because it went together so well decided to build it's partner the Elenco Resistor Substitution Kit.  Not much else to say; like the Capacitor Substitution Kit the directions are easy to follow for this very basic kit.   We did make the same modification and replace the provided alligator clip connection with banana jacks.  The measured values look fine:

-----

-----

Sunday, September 5, 2021

Elenco Capacitor Substitution Kit

 

-----

Not often (okay, almost never) a capacitance substitution box would come in handy on the bench.   Finally, the Amazon AI wizard suggested that at $14.99 we couldn't live life any longer without one. 

From the pic above you can see that the included wire and alligator clip connector were replaced with banana plug jacks.   It gives the rig and the bench a cleaner look.

-----

The directions (which we folded up and placed inside the box for future generations) were straight forward and the values are accurate enough per a NIST traceable capacitance meter.   

-----

The same company also makes a resistance substitution box which we also don't need, but will probably build up anyway.  Both are a nice, cheap, welcome convenience. 

-----

Sunday, May 30, 2021

Remote CW Straight Key [FlexRadio and RemoteHams.Com]

Note:  As presented this project requires a FCC Amateur Radio license.  It's not hard to get and it is a fun and rewarding hobby. Also, learning Morse code is no longer a requirement.

-----

As a remote ham radio operator that enjoys using a manual CW (Morse code) straight key we were presented with two problems:

Since both require slightly different hardware wiring to the PC running the remote rig, we set out to make something that would be a universal connection regardless of which platform we are using. 

-----

The hardware connection is simple and shown below.  It does require a USB/RS-232 adapter and using the RS-232 terminal block break out module shown makes things easier.   There are many example of these two items on Amazon.Com, etc.

For both applications software is needed as well.

-----

For our RemoteHams.Com solution go here.

-----

For the FlexRadio solution you will need to install the excellent and easy to use Remote Keyer Interface software.   Follow the RKI link for the software and you will also find the very helpful RKI message board that I personally proved is helpful and tolerant of 'stupid' questions.  Seriously, the software has great documentation and even though I asked a "RTFM" question I got helpful direction from the forum.   After you install and run the RKI software you will see this screen: 

Make the remote connection to your FlexRadio via your SmartLink login and select the correct COM Port for your (now) USB straight key.  Verify the other options are selected per above screen shot and you should be good to go.

BTW, Remote Keyer Interface software has several other cool features in addition to this simple application.

-----

Summary:   My remote CW manual straight keying problems are solved!

-----

Wednesday, May 26, 2021

The Tale of Three USB Chargers

 

-----

Everyone seems to have a box full of USB chargers.   Well, we do anyway and decided to pick two random "no name" chargers and pit them up against an official Apple USB charger.

The test setup was the same for each USB charger.   We swept a load that increases from 100mA until the USB charger went into protection (no voltage output).  We then checked EMI/RF Noise and 'vampire drain'.

EMI/RF Noise is a big concern.  EMI/RF can have a negative effect on WiFi, Bluetooth, ham radio, and pretty much any radio signal in the area.  Measuring with a Spectrum Analyzer the Apple was by far the most RF quite.  The White "no name" was extremely EMI/RF noisy with the Black "no name" being pretty bad as well.

"Vampire drain" or standby power is how much energy the charger uses when just plugged into the wall doing nothing.  The Apple won in this category as well.

My opinion, get the Apple or other well made USB charger and avoid the "no names",  The Apple uses less standby power and should not have a negative effect on your or your neighbors wireless equipment.  The Apple power output meets spec as well and is more linear until protection kicks in.  The Apple is just better and some "no names" are are just unsafe.

-----

-----

-----

-----

Thursday, May 20, 2021

Morse Code QSO via Vintage Phone

 

-----

As a preteen many many years ago the thought never occurred that the same phone used to plan childhood mischief would some day be used for a CW (Morse code) ham radio QSO.   Ain't life funny...

-----

We found the old Western Electric phone in the attic and wired the switch hook as a straight key.

 


 -----

Then we went to 80m where we heard ham radio operator K5JM and decided to "ring" him up.  The result; success!!!

-----

73!

Friday, May 14, 2021

NanoVNA on QPRGuys Tuner on 10-80m HWEF


 -----

Adjusting the tuning knobs on the QRPGuys tuner and showing their effect with a NanoVNA.   Antenna is 10-80m endfed

-----

Tuesday, May 11, 2021

2m / 70cm Ham Radio Traffic Logger

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYmnOfpJVA2y6GyGkoIOYluMaY2jMoXwGHuCfwkxN8XPYeJUn95zCR6ENM9gJrmd-2vhqYp_0OzWCLDiUItELwP690bjO5wu2y8NSGTZy4fF-TfU84jffUY3ztjd0bSz5hzo35BTHrxpsR/s1600/BT_Logger_Schmatic-793823.JPG 

Is the frequency in use (or QRL? in Morse Code)?

-----

We had a curiosity about how often some of the local ham radio repeaters and the 2m calling frequency was being used and decided to put together a rig that could answer the question with real data.    Ham radio has a lot to do with experimentation and tinkering so we set out on a mission to answer the question with "stuff" we had laying around the shack.

-----

Pretty much any newcomer to ham radio has invested $35'ish on a Baofeng hand held.  The little unit is quickly out grown, but it has come in useful time and time again.   This project was just another example of it's unintended usefulness.  Also, like most hobbyist there's never a shortage of WiFi friendly ESP8266s laying around.   Combining the two for an RF activity logger became the objective.

-----

And..... it turned out to be pretty easy and didn't even require opening up the Baofeng.   Anytime the Baofeng hears a signal the LCD display light is activated.   For reasons unknown this presents a voltage spike on the speaker jack.   We suspected this could be the case from the loud "pop" that can be heard when using earphones.

-----

Here is a look at the signal generated on the speaker jack when the display light gets activated:

Weird, huh?   Oh well, we can use that to make the project dead simple.  Just tune the Baofeng to the frequency of interest and let the rig run and log any traffic that hit the antenna.

-----

The schematic at the top of the page shows how we feed the speaker signal into the analog input (A0) of the ESP8266.   To tame the 5 volt signal going into the ESP8266 two diodes are placed back to back.   That's it.   The ESP8266 is programmed to update a Google Drive Sheet via an IFTTT Webhook anytime a voltage is detected.   The activity log looks like this and the source code is below that.  If you duplicate the project, let us know.

-----

-----

/*
 *  Baofeng Traffic Logger
 *  MAY2021
 *  WhiskeyTangoHotel.Com
 *   
 *  Logs to Google Sheet is traffic is dectected on BF HT Radio    !!!  
 *  by monitoring a voltage on the speaker output.  On traffic the !!!
 *  BF display lights and creates a voltage on the speaker jack    !!!
 *  Since no transit, does not require a license, but if you don't !!!
 *  have a ham license, get one.  It's a fun hobby!!!              !!!  
 *  See: http://www.arrl.org/getting-licensed                      !!!
 *  
 *  uC setting for Ardunio IDE (ESP8266 with WiFI)
 *  NodeMCU 1.0 (ESP-12E Module), 80MHz, 921600, 4M (3M SPIFFS)
 *  
*/

// For the Wireless
#include <ESP8266WiFi.h>

// WiFi Connection Information
const char* ssid = "yourSSID";           // PRIVATE: Enter your personal setup information.
const char* password = "yourpassword";   // PRIVATE: Enter your personal setup information.

// IFTTT Information for WebHook widget
String MAKER_SECRET_KEY = "yourIFTTTkey";   // PRIVATE: Enter your personal setup information. Your IFTTT Webhook key here
String TRIGGER_NAME_google_drive = "yourIFTTTWebHookTriggerName";  // this is the Maker IFTTT trigger name for google drive spreadsheet logging
String url_google_drive;  // url that gets built for the IFTTT Webhook logging to google drive spreadsheet
String Status ="Program_Started.....";  // Status payload for Google Sheet.  We log all starts and reboots
const char* host = "maker.ifttt.com";

// Define ESP8266 pins
const int led = 2;  // Blue on board LED is on PIN-D4 (GPIO2) for this NoderMCU 1.0 ESP8266.  Blink it between reads
const int analogInPin = A0;  // ESP8266 Analog Pin ADC0 = A0

int sigValue = 0;  // value to determine if a signal is detected

// Program control variables
int logging = 1; // If 1 then send SMS.  Any other value (0) turns it off.  For debug, typically would be set = 1

void setup(void){ // This setup code is run once.
  pinMode(led, OUTPUT);     // set up the onboard Blue LED pin as an output.  
  Serial.begin(115200);     // turn on the serial monitor for debug

  // wait until serial port opens for native USB devices
  while (! Serial) {
    delay(10);
  }
 
  // Is the WiFi working?
  WiFi.begin(ssid, password);
  Serial.println("");
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("Trying to connect to ");
    Serial.print(ssid);
    Serial.print(" on ");
    Serial.print(WiFi.localIP());
    Serial.println(" ");
    for (int x = 0; x < 20; x++) { //  
      digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED. Shows program is trying to WiFi connect
      //Serial.println("Server Start blink loop....");
      delay(50);   
    } // endfor WiFi blink connect
  }
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.println(WiFi.localIP());

  for (int x = 0; x < 10; x++) { // 5 slow LED blinks to slow WIFI Connected.
  digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED.
  Serial.println("WIFI is Connected....");
  delay(500);   } // endif for WIFI Connected blink  

  // Use WiFiClient class to create TCP connections for WiFi logging
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");  // Boo!!!
    return;
  }

  // Trigger the IFTTT Webhook Channel to update a Google sheet at program start.
  // This can help log power outs, etc.  For first run we defined String Status for identify a startup condition.
  // Create the request for IFTTT google drive
  url_google_drive = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_google_drive + "/with/key/" + MAKER_SECRET_KEY + "?value1=" + String(Status);
  Serial.println(" ");  
  Serial.println("Status: Google Sheet update done with trigger:");
  Serial.println (url_google_drive);
  Serial.println(" ");  
    
  // This sends the request to the IFTTT server
  client.print(String("POST ") + url_google_drive + " HTTP/1.1\r\n" +
  "Host: " + host + "\r\n" +
  "Connection: close\r\n\r\n");  
  delay(500);  // Delay for web traffic; maybe not required.  

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
     String line = client.readStringUntil('\r');    }

}


void loop(void){    // Loop until the Dallas Cowboys win a Super Bowl
 
  sigValue = analogRead(analogInPin);
 
  // For Degug print SigVal readings in the Serial Monitor
  //Serial.println(sigValue);

  // The blue onboard LED will SLOW blink between to show prog is 'running'.
  // FAST blink when sig is dectected.
  digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED.
    
  if (sigValue > 500) {  //  Threshold may need adjusting.  Voltage on speaker jack detected.  We have a signal
      Serial.println("!!!_Signal_Detected_!!!");   
      Serial.println(" ");
              
      if (logging == 1) { // is Google Sheet logging turned on?
          Serial.println("***** Logging is ON *****");
          String Status = "!!!_Signal_Detected_!!!";
          // Set up IFTTT Webhook Channel to update the Google Sheet.  
          // Use WiFiClient class to create TCP connections for IFTTT
          WiFiClient client;
          const int httpPort = 80;
          if (!client.connect(host, httpPort)) {
            Serial.println("connection failed");
            return;
          }
          
          // Create the request for IFTTT google drive
          url_google_drive = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_google_drive + "/with/key/" + MAKER_SECRET_KEY + "?value1=" + String(Status);
            
          // This sends the request to the IFTTT server
          client.print(String("POST ") + url_google_drive + " HTTP/1.1\r\n" +
          "Host: " + host + "\r\n" +
          "Connection: close\r\n\r\n");  
          delay(500);  // Delay for web traffic; maybe not required.  
        
          // Read all the lines of the reply from server and print them to Serial
          while(client.available()){
             String line = client.readStringUntil('\r');    }
                  
          Serial.println("Status: Google Sheet update done with trigger:");
          Serial.println(url_google_drive);
          Serial.println(" ");
          
          // Fast blink the blue onboard LED to show sig was dectected and delay for flood control
          for (int x = 0; x < 600; x++) { // x = 20 for ~ 1 sec, x = 100 for ~5 sec.....
              digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED
              delay(50);   
          } // endfor delay/blink
          
          Serial.println("-------------------------------------");
          Serial.println("Waiting for signal... ");
           
      } else {
        
          Serial.println("Logging is OFF.");
          Serial.println(" ");
      } // endif/else logging  


            
  }
  delay(250); // Delay for onboard blue LED Blink shows program running
    
} // void loop until Cowboys win Super Bowl

-----

Wednesday, January 20, 2021

Flex Radio Turned Boat Anchor

Have you ever wanted the nostalgic sound of a vintage ham radio rig only to be stuck with an expensive modern transceiver?

-----

Note:  As presented this project requires a FCC Amateur Radio license.  Amateur Radio is about experimentation.   Even still you must be versed in the band plan, stay in accordance to FCC Amateur Radio rules in FCC Section 97, and probably a few other things.  That said, let's continue....
-----

The Flex Radio 6400 is an amazing state of the art ham radio transceiver with so many modern bells and whistles than no normal human could ever get around to using them all.   But, sometimes you long to send out that relaxing and warm sound that could only be achieved from a vintage "boat anchor" radio.  A signature trademark of these rigs is their inability to hold steady on a frequency.  This results in frequency drift.  This 'feature' is lost in modern rigs like the Flex Radio.  So what's a modern ham to do when that vintage sound is desired?

-----

The Flex Radio is a SDR; think powerful computer turned radio.   Flex allows third party applications to interface with the radio to make it even more powerful.   One such program is FRStack .  One of FRStack's many many features makes it easy to use API calls to control and configure the Flex Radio.  We wrote a simple Python script to have the Flex Radio simulate a drifting vintage ham radio during transmit.   We really don't recommend using this application; it's just stupid.  Our goal was to experiment with the APIs when the idea hit us. 

-----

 Here is a demo of the Flex Radio transmitting CW with the DriftyFlex script:

-----

Here is the short DriftyFlex Python script:

# DriftyFlex.py  JAN2021
# Python script to make the Flex Radio drift
# like that vintage rig you always wanted.
#
# WhiskeyTangoHotel.Com

# Simple novelty example of controlling
# a Flex Radio via FRStack

# FRStack is an amazing program with 100s of features that
# are a million times more useful than this stupid example.
# See: https://www.mkcmsoftware.com/Flex/Index

import urllib.request
import time
import random

# Define initial XIT offset XIT (0 is suggested)
XIT = 0

# Define amount of XIT SHIFT (or drift) per loop
SHIFT = 5  # in Hz

# Define MAX_XIT (or drift) so things don't get too out of control
MAX_XIT = 300  # in Hz

# Define how often to simulate a new drift
DELAY = .1   # in seconds

# turn on XIT mode
urllib.request.urlopen('http://localhost:13522/api/ActiveSlice/XIT?param=1')

print ( 'Drifty Flex endlesssssss loop.' )
while True:    
    DRIFT = (random.randint(-SHIFT, SHIFT))   

    NEW_XIT = XIT + DRIFT

    if abs(NEW_XIT) > MAX_XIT:  # Maintain drift constraints
        NEW_XIT = XIT - DRIFT
       
    url = 'http://localhost:13522/api/ActiveSlice/XITFREQ?param=' + str(NEW_XIT)
    urllib.request.urlopen( url )

    print ( 'Current drift is: ', NEW_XIT, ' Hz.' )
    XIT = NEW_XIT
    
    time.sleep(DELAY)
    # end while loop  

-----

Saturday, November 28, 2020

Ham Radio Fox Hunt Attenuator [FAIL]

 

-----

One of the many aspects of the ham radio hobby is finding a hidden transmitter; also called a fox hunt.  These are often set up by local clubs as a fun social activity, but they can also be competitive athletic events.  We had done a few fox hunts for fun, but were unsuccessful in finding the transmitter.  What we learned is when you get close to a transmitter (regardless of the power it is outputting) the signal becomes so strong there is no way to reliably get the direction information needed to track it down.   It's basically like a bright light blinding you and sunglasses are needed to reduce the input getting into your eyes.  To reduce the radio frequency (RF) signals picked up by your receiver (from the fox) an attenuator is used. 

-----

We saw this HMC472 Digital RF Attenuator Module on sale for $10US and thought it would be a cheap and simple project to solve our fox hunt problems.  We were wrong.....

It's not the module's fault; it works as spec'd.  Here are our measurement results from the bench:

-----
Wow, ten bucks buys a lot!   So....   what's the issue?  Well, after 3D printing a box for the rig we took it out into the field for a test drive and learned that 32dB attenuation is not nearly enough.   You need at least 100dB from what we later discovered.   Still, the final product came out nice, it did work as advertised, and things were learned.  We're gonna call that a win.  We could cascade a few modules to get more attenuation, but there are better solutions.  Here are some details on the simple build:
 
-----

Thursday, November 12, 2020

XR2206 Function Signal Generator DIY Kit

   

-----

We have seen this signal generator come up as "suggested" in our Amazon account from time to time.  Finally, the Amazon marketing engine combined with COVID cabin fever persuaded us to shell out the $10US and give the kit a try.  

----

$10 gets you a lot and not so much both at the same time.   First off, the directions are not very well written, but the kit is simply enough that they don't need to be.  We did have to ohm out the PCB just to verify that the NEG terminal for the electrolytic caps went into the "hashed" marked hole.   After about 20 minutes the kit was ready test out.  The results.....

-----

We took measurements with an oscilloscope for each setting.   Instead of putting up a bunch of boring sin, triangle, and square wave pics we will just state that the rig works as expected.   ONE CAVEAT:  THIS ONLY SEEMS TO BE TRUE WHEN YOU POWER THE RIG WITH 9VDC.  Also, adjusting the "Amp" knob can really effect the quality of the output signal.  There is a sweet spot on the "Amp" setting, but without a scope I'm not sure how you could find it.   Another odd behavior; a square wave will produce an almost 9V output.  The sin and triangle waves max out at about half that. 

-----

Here are our findings:

-----

So..... if you need a low end sig gen this kit does work.  It's cheap to buy.  It's easy and fun to build up.  But, be aware that without a scope you will not have a way to know the exact output frequency and output voltage or if the output signal is being clipped or otherwise deformed.  

-----

Sunday, August 30, 2020

Using Tesla Screen to Display FlexRadio SmartSDR

 

-----

We posted the video above of the FlexRadio 6400 streaming it's SmartSDR output to a Tesla on our Twitter feed and had several ham radio operators ask; "How did you do that"?  Well, it's a lot easier than you may think.

-----

Most hams never throw anything away and will find the materials needed to pull this off laying around their ham shack:

    - Tesla Model X

    - FlexRadio 6400

    - PC running FlexRadio's SmartSDR software

    - an internet connection

-----

After you have gathered the materials, it's easy.  Just go to the Dead Simple Screen Sharing site on the PC, click the button for the share link, then type that link into the browser on the Tesla.   The Dead Simple Screen Sharing site really is 'dead simple'.  I wouldn't suggest it for on-line banking, but for less critical applications it fits the bill.

Here is a slightly longer version of the demo:


-----

Thanks for watching and 73!