Monday, December 3, 2018

Internet Time Morse Code Clock

-----
There are plenty of ways to irritate your XYL with an obsession of ham radio; but if you feel you need just one more then keep reading.   The black box above is actually a clock.  It's a cool clock if you know Morse Code (or CW), but it is worthless if you don't.
-----
The brains of the Morse Code clock is an ESP8266 with on board WiFi.  At power up, the rig connects to WiFi and fetches the time from the internet (so always accurate).  On first run the 'clock' sends out some Self Test tones after getting the time.  These Self Test tones can be something like a callsign, but it could be anything or even nothing.  The pace (or WPM) of the Morse Code is adjustable by a variable in the source code.  In the example videos it is 10WPM as calculated by "The Paris Standard".

From that point on the time of day (localized to your time zone) is output to a speaker and LED tower in Morse Code (24 hour format) as HHMM.  A calm quite house is filled with dit-dah tones and flashing light.
----
The build is not that difficult as shown in the schematic below.  On the bench it looks something like this:
-----
A metal box found around the shack was repurposed to clean up the look.  This vid shows the end result.  At power up the LED tower flashes until it gets the time from the internet.  Then the Self Test tones and LED flashes happen.   After that, only the time is "announced" when the red button is pressed.
It all came out pretty nice.
-----
If you decide to duplicate the build here is the simple schematic:
 -----
And the Arduino/ESP8266 IDE Source Code:
 _______________________________________________________________
/*
 *  NOV2018
 *  CW "Talking Clock"
 *  WhiskeyTangoHotel.Com
 * 
 * Get Internet time.
 * Upon a button press, convert the Internet time to defined local time zone.
 * Parse the Internet time to HHMM (24 hr format)
 * Convert the HHMM time to Morse Code (CW) dits and dahs
 * Play the Morse Code converted times over a speaker and a LED.
 *
 * At startup a self test sends a callsign (or user define msg) to
 * the speaker in CW.
 *
 * BTW, CW is fun to learn.
 *  --... / ...--   //  --... / ...--
 *
*/

#include <time.h>

// Set up or the Wireless.  We wil need this to get the internet time
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

// WiFi Connection Information
const char* ssid = "YOUR_SSID";         // PRIVATE: Enter your personal SSID setup information. *PRIVATE*
const char* password = "YOURWIFIPASSWORD"; // PRIVATE: Enter your personal PASSWORD setup information. *PRIVATE*
ESP8266WebServer server(80);

// Define and set up some variables
int timezone = 18;  // Chicago = 18
int dst = 0;        // 0 or 1.  1 for DST or "Summer Adjusted Time"
String Callsign = "W1AW";   // ALL CAPS!!!  Used for self test 'beeps' at startup.  Could be anything alphanumic you like
String Time_substring;   // Used for parsing
String Parsedtime; // Feteched internet time boiled down to HHMM in 24 hr format.
String Dit_or_Dah;  // Output a dit or dah to the speaker.  Used when parsing a character

int Pitch = 600;      // Normally around 600Hz.  This this the pitch frequency of the CW tones
float WPM = 10;       // How fast the letters are sent to the speaker using the "Paris Standard" in Words per Minute (8-25; depending on skill level)
//  Paris Standard formula: Tmsec = (1200 / WPM) WPM is the desired speed in words-per-minute. T is the dit time in mSecs
float Tmsec = 1200 / WPM;
float Dit = Tmsec;
float intercharacter_spacing = Dit;
float Dah = Tmsec * 3;
float interword_spacing = Dah;

// Load the CW database 'dits' and 'dahs' for each Alphanumeric. Boring....
String A = ".-";;
String B = "-...";
String C = "-.-.";
String D = "-..";
String E = ".";
String F = "..-.";
String G = "--.";
String H = "....";
String I = "..";
String J = ".---";
String K = "-.-";
String L = ".-..";
String M = "--";
String N = "-.";
String O = "---";
String P = ".--.";
String Q = "--.-";
String R = ".-.";
String S = "...";
String T = "-";
String U = "..-";
String V = "...-";
String W = ".--";
String X = "-..-";
String Y = "-.--";
String Z = "--..";
String zero = "-----";
String one = ".----";
String two = "..---";
String three = "...--";
String four = "....-";
String five = ".....";
String six = "-....";
String seven = "--...";
String eight = "---..";
String nine = "----.";

// Output pins
const int led = 2;  // NEGATIVE Logic (LOW is ON) Blue on board LED is on PIN2 for this NoderMCU 1.0 ESP8266.
const int speaker = 14;  // tone outputs to the EXTERNALLY amplified speaker to pin 14
int time_buttonPin = 4;  // When button pressed CW the time to the speaker.  pin 4
boolean buttonState = LOW;  // for the time_buttonPin status

void setup(void){  // This is run once.
  Serial.begin(115200);  // turn on the serial monitor for debug
  //Serial.setDebugOutput(true);  // Turn on the Serial Debugger if desired

  //Define the I/O
  pinMode(led, OUTPUT);  // set up the onboard Blue LED as an output.
  pinMode(time_buttonPin, INPUT); // Input for the button switch.  if HIGH (pressed) play CW the time to the speaker

  // Connect WiFi.  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.println(WiFi.localIP());
    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
      delay(50);  
    } // endfor WiFi blink connect
  }
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.println(WiFi.localIP());

  // Get the current time from "THE INTERNET!"
  configTime((timezone + dst) * 3600, 0, "pool.ntp.org", "time.nist.gov");
  Serial.println("\nWaiting for time");
  while (!time(nullptr)) {
    Serial.print(".");
    delay(100);
  }

  //Send tones for the variable Callsign to the speaker as a self test.
  Serial.println("Sending Self Test tones " + Callsign + " ......");
  int L = Callsign.length();
  for (int i=0; i<L; i++) {  // Start Self Test Convert the time numbers to dit and dahs
    Time_substring = Callsign.substring(i, i+1);
    if (Time_substring == "0") { Time_substring = zero; }
    if (Time_substring == "1") { Time_substring = one; }
    if (Time_substring == "2") { Time_substring = two; }
    if (Time_substring == "3") { Time_substring = three; }
    if (Time_substring == "4") { Time_substring = four; }
    if (Time_substring == "5") { Time_substring = five; }
    if (Time_substring == "6") { Time_substring = six; }
    if (Time_substring == "7") { Time_substring = seven; }
    if (Time_substring == "8") { Time_substring = eight; }
    if (Time_substring == "9") { Time_substring = nine; }
    if (Time_substring == "A") { Time_substring = A; }
    if (Time_substring == "B") { Time_substring = B; }
    if (Time_substring == "C") { Time_substring = C; }
    if (Time_substring == "D") { Time_substring = D; }
    if (Time_substring == "E") { Time_substring = E; }
    if (Time_substring == "F") { Time_substring = F; }
    if (Time_substring == "G") { Time_substring = G; }
    if (Time_substring == "H") { Time_substring = H; }
    if (Time_substring == "I") { Time_substring = I; }
    if (Time_substring == "J") { Time_substring = J; }
    if (Time_substring == "K") { Time_substring = K; }
    if (Time_substring == "L") { Time_substring = L; }
    if (Time_substring == "M") { Time_substring = M; }
    if (Time_substring == "N") { Time_substring = N; }
    if (Time_substring == "O") { Time_substring = O; }
    if (Time_substring == "P") { Time_substring = P; }
    if (Time_substring == "Q") { Time_substring = Q; }
    if (Time_substring == "R") { Time_substring = R; }
    if (Time_substring == "S") { Time_substring = S; }
    if (Time_substring == "T") { Time_substring = T; }
    if (Time_substring == "U") { Time_substring = U; }
    if (Time_substring == "V") { Time_substring = V; }
    if (Time_substring == "W") { Time_substring = W; }
    if (Time_substring == "X") { Time_substring = X; }
    if (Time_substring == "Y") { Time_substring = Y; }
    if (Time_substring == "Z") { Time_substring = Z; }   

    // Now send the dit/dahs for the Self Test Callsign Character   
    int CW_length = Time_substring.length();

    for (int j=0; j<CW_length; j++)   {  // Send tones and blink LED in CW
      digitalWrite(led , HIGH); // NEGATIVE LOGIC.  Make sure the onboard LED is off
      Dit_or_Dah = Time_substring.substring(j, j+1);
      //Serial.println(Dit_or_Dah);
     
      if (Dit_or_Dah == ".") {   // process a Dit
        digitalWrite(led , LOW);
        tone(speaker, Pitch, Dit);
        delay(Dit);
        digitalWrite(led , HIGH);
      }  // end if process a Dit

      if (Dit_or_Dah == "-") {   // process a Dah
        digitalWrite(led , LOW);
        tone(speaker, Pitch, Dah);
        delay(Dah);
        digitalWrite(led , HIGH);
      }  // end if process a Dah

      delay(intercharacter_spacing);   //  a delay of "1 Dit" between dit/dahs in a character     
    }  // send for loop dit/dahs for selected time number
    delay (interword_spacing);   // done with sending character, so a longer "3 * Dit" delay"    
  } // end for loop on the Self Test 

  Serial.println("Self test completes!!!");
  digitalWrite(led , HIGH); // NEGATIVE LOGIC.  Make sure the onboard LED is off
  Serial.println("");

} // End void setup loop

void loop(void){  // Loop forever waiting for button push.  If pushed CW the local time as HHMM in CW and go back to waiting for that button
  int buttonState = digitalRead(time_buttonPin);   // check if the pushbutton is pressed.  
    if (buttonState == HIGH) {   // button is pressed, CW time to speaker 
      time_t now = time(nullptr);
      Serial.println("---------------------------------------");
      Serial.print("Internet time adjusted to tone zone: ");
      Serial.println(ctime(&now));
      Parsedtime = (ctime(&now));
   
      // Build the Parsed time from the internet time. The time is 24 hr format and always 4 characters in HHMM
      Parsedtime = Parsedtime.substring(11,12) + Parsedtime.substring(12,13) + Parsedtime.substring(14,15) + Parsedtime.substring(15,16);
      Serial.print("Parsedtime as HHMM is: ");
      Serial.println(Parsedtime);     
     
      for (int i=0; i<4; i++) {  // Convert the time numbers to dit and dahs. Always 4 characters in HHMM
        Time_substring = Parsedtime.substring(i, i+1);
        Serial.print("Currently sending Parsedtime character: ");
        Serial.println(Time_substring);
       
        if (Time_substring == "0") { Time_substring = zero; }
        if (Time_substring == "1") { Time_substring = one; }
        if (Time_substring == "2") { Time_substring = two; }
        if (Time_substring == "3") { Time_substring = three; }
        if (Time_substring == "4") { Time_substring = four; }
        if (Time_substring == "5") { Time_substring = five; }
        if (Time_substring == "6") { Time_substring = six; }
        if (Time_substring == "7") { Time_substring = seven; }
        if (Time_substring == "8") { Time_substring = eight; }
        if (Time_substring == "9") { Time_substring = nine; }
   
        // Now send the dit/dahs for the time number processed       
        int CW_length = Time_substring.length();
   
        for (int j=0; j<CW_length; j++)   {  // Send tones and blink LED in CW
          digitalWrite(led , HIGH); // NEGATIVE LOGIC.  Make sure the onboard LED is off
          Dit_or_Dah = Time_substring.substring(j, j+1);
                   
          if (Dit_or_Dah == ".") {   // process a Dit
            digitalWrite(led , LOW);
            tone(speaker, Pitch, Dit);
            delay(Dit);
            digitalWrite(led , HIGH);
          }  // end if process a Dit
   
          if (Dit_or_Dah == "-") {   // process a Dah
            digitalWrite(led , LOW);
            tone(speaker, Pitch, Dah);
            delay(Dah);
            digitalWrite(led , HIGH);
          }  // end if process a Dah
   
          delay(intercharacter_spacing);   //           
        }  // send for loop dit/dahs for selected time number   
        delay (interword_spacing);        
      } // end for loop Convert the HHMM time numbers to dit and dahs
   
      Serial.println("Sending time tones completed!!!");
      delay(1000);  // Delay for a sec just beacause...
    }  // End button press if
}  // End of Loop forever waiting for button push.
________________________________________________________
-----
Thanks for stopping by and 73!

Sunday, November 4, 2018

Model EFHW-8010 End Fed Antenna Characterization

-----
The EFHW-8010 End Fed antenna was recommended so we gave it a go.  The installation has the "business" end of the 130 feet antenna wire about 50 feet high sloping down to about 8 feet with some para-cord support from an overhanging tree near mid run to keep the antenna wire high as long as possible.  The inline choke and and matching transformer are located in the attic.  This is not the optimal setup, but the configuration was convenient for our QTH.  We are very happy with the performance and the Icom IC-7300 tunes it to well to all spec'd bands. 
-----
Once again, my Elmer friend let me borrow an antenna analyzer to test things out.  This analyzer is very nice kit with a sturdy case, touch screen interface, and an easy to understand user interface.  Go to this page and see the AQRP 8KHz to 440MHz Vector Impedance Analyzer kit #25 for more details.  It's well documented and a very slick package.  
 
-----
Below are the SWR plots and a few Insertion Loss plots for the bands.  Remember, the EFHW-8010 End Fed antenna is spec'd from 10m to 80m.  We tested it on a few bands outside its design spec.  All measurements are made through 50 feet of RG8X, plus 25 feet of BNC cable, plus an Alpha Delta 4:1 coax switch.
-----
2 meters:

-----
6 meters:

-----
10 meters:
-----
12 meters:
-----
15 meters:
-----
17 meters:
-----
20 meters:

-----
30 meters:
-----
40 meters:

-----
60 meters:
-----
80 meters:
-----
160 meters:
-----
Regardless of how you interpret the data the antenna is working well for our setup.  73 and see you on the bands!
-----

Friday, August 24, 2018

Ham Radio HT 2m Antenna Comparison

AQRP 8KHz to 440MHz Vector Impedance Analyzer kit #25
-----
An OFC Dipole antenna was recently paid-forward to me.  My Elmer friend let me borrow an antenna analyzer to check it out.  I soon learned that the analyzer was actually put together from a kit.  It is a very nice package with a sturdy case, touch screen interface, and an easy to understand user interface.  Go to this page and see the AQRP 8KHz to 440MHz Vector Impedance Analyzer kit #25 for more details.  It's well documented and a very slick package. 
 
 
-----
Right away I wanted to play with the analyzer and decided to sweep a few 2m hand held radio antennas as a test (results below). 
It's interesting how much flatter the VSWR curve is with the Nogoya NA-771 VHF/UHF aftermarket duckie.  Also, I never tuned the DIY 2m Tape Measure Yagi but just following the build instructions carefully seemed to yield good results.
 -----
 

-----

-----


-----

-----
And, just for grins we swept a DIY simple wire dipole that was cut for 20m which is only use for Rx with a SDRPlay RSP1A. Our placement for the dipole is marginal and it works equally marginal on 20m and 40m.   FWIW, here are the results:

-----

Monday, August 20, 2018

Morse Code Practice Oscillator (eBay Kit)

-----
When learning Morse code (referred to as CW in ham radio circles) a practice oscillator can be helpful.  It lets you practice your sending without transmitting.  Also, if can be useful if you are wanting to practice sending/receiving CW with another ham through a Skype channel without waiting for propagation conditions.  A voice channel like Skype also allows immediate voice feedback for effective Elmering.
-----
We shelled out $10US on eBay and a few days later we got the practice oscillator pictured above in kit form from  Electroresales with some good instructions.  After about 30 minutes we had a working (and very loud if you crank the volume) practice oscillator.   We made one small mod by adding a JST connector in parallel to the power barrel jack.  This made it easier (for us anyway) to connect a 9VDC battery without having to find the right size barrel jack connector to supply the power.
-----
The result:
73!
-----



Saturday, June 16, 2018

QRP Labs QCX 5W CW Transceiver Build

----
CQ CQ CQ....  In the "olden" days, Morse Code (or CW) was a requirement for a Ham Radio license.  That is no longer the case, but for some reason CW seems to have a new interest with those in the hobby.   After seeing more and more discussions about CW we decided to give it a try.
-----
Three things are needed:
1) An FCC Amateur Radio license; it's not hard get and it is an extremely interesting hobby.
2) A radio that can transmit/receive CW signals.  We chose the QRP Labs QCX Kit.
3) You have to know Morse Code; how to send it and how to decode it.

The first two are easy.  The third one not so much, but there are a host of tools and advise on the web to help.  Just search google.  We have only been at it 30 days and show progress, but still have a long way to go.
-----
Back to the QCX kit.... We wanted something cheap, small, and portable.  We read great reviews about QRP Labs QCX Kit and decided to give it a go.  After asking around about the best band for CW newbies we decided to configure for 40 meters.  This page was originally going to document the build process, but really there is no need.  The instructions and documentation provided with the kit are AMAZING.  Really, they are!   Great images, diagrams, etc.  There are lots of solder joints and some toroids to hand wind, but follow the directions exactly and you will be fine.
-----
Here is the whole enchilada in a niffy 3D printed case purchased from W4KHZ / Mike.  At $25 shipped it is a great value.

-----
The QCX is very battery friendly.  It seems to run 'forever' using one of the many low cost car jump start battery bricks.  The video below shows the current (mA) profile using a Keithley 2450 Source Measure Unit.

-----
And... a low cost transceiver is of no use without a low cost antenna.   We had spare long runs of common speaker wire and hand cut a dipole for 7.050MHz (a common frequency for 40m CW).  We must have been using calibrated wire cutters.  Below is the initial SWR sweep from 7.000MHz to 7.100MHz.

-----
All in all we are very pleased.  Now back to CW practice.  Thanks for the visit and maybe we will hook up on 40m.

73!
-----

Thursday, April 12, 2018

SSTV and the ISS: Space Based Fax Machine

-----
From time to time the International Space Station (ISS) will activate their Slow Scan Television (SSTV) transmitter.  April 12, 2018 was one of those times as the Russian crew commemorated  Cosmonautics Day.  Getting a SSTV image from the ISS is kind of like getting a FAX sent to you from a spaceship.  In the case of the captured image above the ISS was transmitting an audio signal to Earth on a frequency 145.800MHz with 25 Watts.  The signal is strong and lets anyone with some basic equipment receive and decode the image.
----
For this capture we used:
- The Heavens Above website to predict the ISS pass.
- A Kenwood TH-D72A to receive the signal (could be a low cost ham radio or SDR).
- A DIY Yagi antenna (the signal was so strong this was probably not required).
- A small recorder to save the audio received.
- Software to decode the recorded audio into an image.  We used RX-SSTV.
----
The whole process takes some planning and setup, but it's not that hard and it was rewarding to see the result.  If you want to hear what our image "sounds like" or test your decode SW then play this:

-----
Later that evening I was able to downlink these two images in one pass:

April 13, 2018:
April 14, 2018:
June 2018:

-----

Sunday, March 25, 2018

Ham Solo: ESP8266 Based Amateur Radio Simplex Confirmation Project

-----
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 and stay away from local repeater stations, stay in accordance to FCC Amateur Radio rules such as 97.201(a), 97.201(b), 97.213(a), 97.215, 97.3(a)(7), and likely a few others.  Even after following all those rules, nobody likes to hear a bunch on random DTMF tones so keep your transmissions short and infrequent.
-----
Most Amateur (or ham) radio operators have wondered how or if their signal is getting received.  After getting a YES/NO answer they may want to decrease power, try a different antenna set up, or change location.  The challenge with this can be a willing participant on the receive side that has promised to remain perfectly still and listen for hours.  If you have a friend or XYL willing to do that then consider yourself fortunate.  For all the others there is this project.
-----
The rig is pretty straight forward and explained in the image above.
   - From the field a DTMF tone is transmitted on a frequency that "the shack" is tuned to.
   - If the radio in the shack hears the DTMF tone it is decoded with this module.
   - Code running on an ESP8266 turns the decoded tone "to English" and sends a SMS text message via IFTTT.
   - If the shack received everything you will get a confirming QSL SMS on your smartphone.
-----
It's all quick and simple.  It takes only a 250 mSec or so transmission time and a delay of maybe 2 seconds to get the confirming QSL SMS.  The short video below gives a good explanation:

-----
Want to build your own?  No problem.
   1st:  Get a FCC Amateur Radio license; it's not hard and is an extremely interesting hobby.
   2nd: Buy some radios (costs range from $30 to infinity).
   3rd:  Buy the DTMF module and an ESP8266.
   4th:  Set up a free IFTTT account for the SMS texting.
   5th:  Hook it all up as shown in the image at the top of this page.
   6th:  Load the source code below into your ESP8266 (you will need the Arduino IDE).
   7th:  Be respectful of the rules and test away.
-----
Before showing the ESP8266 source code here's a short video using 5 of the 8 channels on the Tektronix MSO5 (which is bad ass!!!) to monitor the signals coming off the DTMF module.
-----
The (short/simple) ESP8266 source code is below.  If you duplicate the project or this motivates you to get your FCC Amateur Radio license let us know:
-----
/*
 *  HamControl
 *  MARCH2018
 *  WhiskeyTangoHotel.Com
 *  
 *  This project as described requires a FCC Amateur Radio License!!!!!! 
 *  Be aware of all FCC license and regulation retrictions before use!!!
 *  Follow local band plan and Federal regulations!!!!!!!!!!!!!!!!!!!!!!
 *  Go ahead and get your license.  It's a fun hobby.  See: http://www.arrl.org/getting-licensed
 * 
 *  HamControl:
 *  Use DTMF Tones to control ESP8266 via ham radio.
 *  Primary application was to confirm simplex signal Tx/Rx for antenna testing.
 *  When a DTFM is detected a SMS is sent your cell phone for field comfirmation.
 * 
 *  For DTMF DeCode: SMAKN® XD-61 MT8870 (~$10 USD)  
 *  NOTE:  For Baofeng set volume to ~80%
 * 
 *  uC setting for Ardunio IDE (ESP8266 with WiFI)
 *  NoderMCU 1.0 (ESP-12E Module), 80MHz, 921600, 4M (3M SPIFFS)
 * 
*/

// For the Wireless
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

// WiFi Connection Information
const char* ssid = "Your-SSID-Here";           // PRIVATE: Enter your personal setup information.
const char* password = "Your-WiFi-PW-Here";   // PRIVATE: Enter your personal setup information.
ESP8266WebServer server(80);

// IFTTT Information for WebHook widget
String MAKER_SECRET_KEY = "Your-IFTTT-PrivateKey-Here";   // PRIVATE: Enter your personal setup information. Your IFTTT Webhook key here
String TRIGGER_NAME_SMS = "HamControl_SMS";           // this is the Maker IFTTT trigger name to send SMS if a DTFM tone is recieved.
const char* host = "maker.ifttt.com";
String url_SMS;       // url that gets built for the IFTTT Webhook sending SMS DTMF recieved confirmation.
String DTMF_String;   // used to covert numbers and *,#,A,B,C,D tones to a string value.

// Define and set up some variables
int DTMF;  // What key press was sent by the ham radio.

// 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
// Define pins from the DTMF Decoder to the ESP8266 GPIO
const int Q1 = 12;  // PIN-D6 SILK SCREEN LABEL
const int Q2 = 13;  // PIN-D7 SILK SCREEN LABEL
const int Q3 = 15;  // PIN-D8 SILK SCREEN LABEL
const int Q4 = 5;   // PIN-D1 SILK SCREEN LABEL
const int STQ = 4;  // PIN-D2 SILK SCREEN LABEL

// 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.
  pinMode(Q1, INPUT);       // Q1-4 are the output signals from the DTFM IC
  pinMode(Q2, INPUT);       // that are feed into and read by the ESP8266
  pinMode(Q3, INPUT);
  pinMode(Q4, INPUT); 
  pinMode(STQ, INPUT);      // STQ is high when DTFM tone is detected
 
  Serial.begin(115200);     // turn on the serial monitor for debug
 
  // 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());
    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());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
    Serial.println(" ");
  }

  // 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;
  }

  server.begin();
  Serial.println("HTTP server started");  // Woo Hoo!!!
  Serial.println(" ");
   
  Serial.println("Entering HamControl main loop. ");
  Serial.println("Waiting for DTMF... ");
  Serial.println("-------------------------------------");
}

void loop(void){    // Loop this code section until hell freezes over

  // The blue onboard LED will blink between to show prog is 'running'.
  digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED.
   
  if (digitalRead(STQ) == HIGH) {  // If it HIGH then DTFM detected.  Let's get to work.
      Serial.println("DTMF Detected!!!");
      DTMF_String = "Could_not_decode_DTFM!";  // Should be overwritten below, but just in case Mr Murphry shows up...
     
      // Convert the four bit (Q1-Q4 read) to decimal values 1-9 to match the button pushed
      // 0=10, *=11, #=12, A=13, B=14, C=15, D=0
      DTMF = (digitalRead(Q4) * 8) + (digitalRead(Q3) * 4) + (digitalRead(Q2) * 2) + (digitalRead(Q1) * 1);
      DTMF_String = String(DTMF);
      if (DTMF == 10) {
          DTMF_String = "0";
      }
      if (DTMF == 11) {
          DTMF_String = "*";
      }
      if (DTMF == 12) {
          DTMF_String = "HASH";
      }
      if (DTMF == 13) {
          DTMF_String = "A";
      }
      if (DTMF == 14) {
          DTMF_String = "B";
      }
      if (DTMF == 15) {
          DTMF_String = "C";
      }
      if (DTMF == 0) {
          DTMF_String = "D";
      }     
      Serial.println("Key pressed: " + DTMF_String);     
             
      if (logging == 1) { // is SMS logging turned on?
          // Set up IFTTT Webhook Channel to send the SMS. 
          // Use WiFiClient class to create TCP connections for IFTT SMS
          WiFiClient client;
          const int httpPort = 80;
          if (!client.connect(host, httpPort)) {
            Serial.println("connection failed");
            return;
          }
         
          // Build the IFTTT SMS url
          url_SMS = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_SMS + "/with/key/" + MAKER_SECRET_KEY+ "?value1=" + DTMF_String;
          Serial.println(" ");
          Serial.println("SMS payload to IFTTT.");
          Serial.println(url_SMS);
          client.print(String("POST ") + url_SMS + " HTTP/1.1\r\n" +
          "Host: " + host + "\r\n" +
          "Connection: close\r\n\r\n");
          Serial.println(" ");
          Serial.println("Logging is ON.");
          delay(1000);   // pause for webservices and to prevent double tap
          // and fast blink the blue onboard LED to show DTMF was recognized
          for (int x = 0; x < 100; x++) {
              digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED
              delay(50);  
          } // endfor DFTM delay/blink                
          
      } else {
       
          Serial.println("Logging is OFF.");
          Serial.println(" ");
      } // endif/else logging 

      Serial.println("-------------------------------------");
      Serial.println("Waiting for DTMF... ");
           
  } //Endif STQ High?
  delay(250); // Delay for flashing on board BLUE program running status LED
   
} // void loop until hell freezes over
-----
73!

Sunday, January 28, 2018

1st Amateur Radio Contact with Satellite A0-91

-----
It's done everyday, but (as they say) you never forget your first.  The 'cube' above is Satellite A0-91.  This little guy has a VHF/UHF amateur radio repeater on board which means it is available for use if you hold a FCC Technician license.

It's not overly difficult, but it is a good challenge.  Today we were able to get a contact for the first time.  It's pretty satisfying using a $50'ish handheld radio to communicate via space. 
-----
Here is the audio:
-----
73s