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!



Wednesday, July 29, 2020

3D Printed FlexRadio Maestro Stand

-----
The stand for the FlexRadio Maestro is bulky and doesn't travel well.   FlexRadio does make folding feet to take care of this, but that solution is a hundred bucks.  We didn't need a less bulky travel stand all the time and we didn't want to part with the cash.  So.... we printed one.
-----
Works great!  Design file on Thingiverse.

-----

Sunday, July 19, 2020

3D Printed Single Lever Paddle/Cootie Morse Code Key


-----
We had originally printed this Morse Code key to operate in "Cootie" mode.  You can read about that here.   It turns out using a Cootie key is fun and easy on the wrist, but.....  learning to operate a Cootie key does take some practice.   That said, the automotive spark plug feeler gauge gave such an effortless feel we decided to make a small modification and create a Single Lever Paddle from the original design.
-----
This mod allows usage with an electronic keyer in three terminal mode.  The two terminals on the left can be shorted to quickly switch into Cootie mode.
-----


-----

Tuesday, July 14, 2020

Send Morse Code (CW) with your Voice

-----
CW or Morse Code is a way ham radio operators send messages with a simple tone of two durations.  It was a must before the days of wireless voice communications and still remains popular because it is a fun challenge. 

There are many online tools that will convert text into Morse Code.  However, a Google AIY Voice Bonnet came into our possession and we thought we could take that another step by creating a "Speech to Morse" translator that would actually send code over the air on the ham radio bands from spoken word.

To use the rig, you don't need a ham radio license unless you connect to an actually ham radio transmitter; which is kinda the whole point.  My quick ham radio advertisement:  Get a FCC Amateur Radio license; it's not hard and is an extremely interesting hobby.  BTW, learning Morse Code is no longer a requirement.
-----
When we were given the AIY Voice Bonnet we really didn't even know what it did.  We knew it needed a Raspberry PI and it could act somewhat like a Google Voice Assistant.   We had a Raspberry PI Zero handy and after some Google search engineering we found a disk image file to get us started.

Like a lot of internet projects APIs can change and documentation can be conflicting, we finally got the RasPI and Voice Bonnet to talk to the web after some effort.  A full blown Google Voice Assistant this thing is NOT; if you want one of those then BUY, don't BUILD.  After leaning into the AIY GitHub for knowledge we were finally rewarded with success.
-----
The connections are easy and just follow the AIY GitHub to wire the ACTIVATE BUTTON. We used IO Pin 16 on the RasPI for the relay control because it wasn't used by the AIY Voice Bonnet.  The AIY Voice Bonnet has four GPIO pins on board, but we could never get them to work.   Here's the summary:
-----
And here is the rig in action.  The Python code to make it run is below.

Demo at 20 WPM:
Demo at 12 WPM:
-----
Thanks and 73!   Here is our Python source code:

#!/usr/bin/env python3

#
#  July  2020
#  Voice to Morse Code Translator
#  WhiskeyTangoHotel.Com
#
# RaspberryPI Zero and AIY Voice Bonnet.
#
# Use Google Voice AIY to convert speech to text.
# Read that text file created and convert the text.
# Turn that text into to Morse Code "." and "-".
# Close a relay to transmit it over the air with a ham radio
#
#
# BTW, CW is fun to learn.
# *  --... / ...--   //  --... / ...--

# Some program set up and Define some variables

import os  # needed to delete the text file after reading
import time  # needed for delays
from datetime import datetime # need to calc run time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM) # Use BCM I/O board pin numbers

SendingLine = 0  # this is the text file line we will send
StartCW = 0    #  Char position to start sending from the parsed line
EndCW = 0       #  Char position to stop sending from the parsed line

keyer = 16  # Pin where the keyer relay is connected
GPIO.setup(keyer, GPIO.OUT)
GPIO.output(keyer, GPIO.LOW)  # make certain we are not keyed down

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

# WPM spacing calculated using the "Paris Standard"
# Per Morse code convention: 1 Dah = 3 Dits, LETTERS are spaced by one Dit, WORDS are spaced by one Dah.

WPM = 20.0    # Don't leave off the ".0" or WPM will be an integer (we want it to float)
Dit = 1.200 / WPM
Dah = Dit * 3.0
between_ditdah_spacing = Dit
between_character_spacing = Dit * 2
between_word_spacing = Dit * 3

"""Calls to Google Assistant GRPC recognizer."""

# We use AIY in the cloud to do the speech to text processing.  The RaspberryPI just can't do it as good.

# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import locale
import logging
import signal
import sys

from aiy.assistant.grpc import AssistantServiceClientWithLed
from aiy.board import Board

def volume(string):
    value = int(string)
    if value < 0 or value > 100:
        raise argparse.ArgumentTypeError('Volume must be in [0...100] range.')
    return value

def locale_language():
    language, _ = locale.getdefaultlocale()
    return language

def main():
    logging.basicConfig(level=logging.DEBUG)
    signal.signal(signal.SIGTERM, lambda signum, frame: sys.exit(0))

    parser = argparse.ArgumentParser(description='Assistant service example.')
    parser.add_argument('--language', default=locale_language())
    parser.add_argument('--volume', type=volume, default=100)
    args = parser.parse_args()

    with Board() as board:
        assistant = AssistantServiceClientWithLed(board=board,
                                                  volume_percentage=args.volume,
                                                  language_code=args.language)
        while True:
            logging.info('Press button to start conversation...')
            board.button.wait_for_press()
            logging.info('Conversation started!')
            assistant.conversation()

            # Voice to CW routine starts here are the dim RED button is pressed
            # Button will turn bright RED while the rig is listening
            # Button will dim blink RED when ready for next speech input

            #  Read the text file created by the speech to text and get it ready to send as CW

            # Look for "Trigger Lines" in the text file.  Parse and send the line above it
            Trig1 = "Recording stopped."
            Trig2 = "End of audio request detected"
            Trig3 = "Updating conversation state"
            i = -1

            Get_file = "keywhat.txt"  # this is the text file created from AIY that we are going to process

            mylines = []
            with open (Get_file, 'rt') as myfile:    #'rt' means 'read text data'
                for line in myfile:
                    i = i + 1
                    mylines.append(line)
                   
                    # If we find one to the Trigger lines, we have passed the voice text by one line in the file
                    if mylines[i].find(Trig1) and mylines[i].find(Trig2) and mylines[i].find(Trig3)!= -1 :
                        SendingLine = i-1

            print (SendingLine, mylines[SendingLine])
            Send_text = mylines[SendingLine]

            #  Strip out only the text we want to send over the air
            StartCW = int((mylines[SendingLine].find('"')) + 1)
            EndCW = int(len(mylines[SendingLine]) - 3)
            # print StartCW, EndCW    #  used for debug

            SendasCW = Send_text[StartCW:EndCW]  # this is the text sent as CW

            #SendasCW = "test"  # used for debug
            SendasCW = (SendasCW.upper())  # and we always make certain it is all caps

            # We have the text.  Now parse it and send each letter as CW

            print ("Going to send: " + SendasCW + " at " + str(int(WPM)) + " WPM.")
            print ("-------------------------------------------")

            L = len(SendasCW)
            t0 = datetime.now()

            for x in range(0,L):  # Start character converstion to dit and dahs
                    Text_substring = SendasCW[x:x+1]
                    print ("Sending: " + Text_substring)   # for debug
                    if Text_substring == "0"  :  Text_substring = zero
                    if Text_substring == "1"  :  Text_substring = one
                    if Text_substring == "2"  :  Text_substring = two
                    if Text_substring == "3"  :  Text_substring = three
                    if Text_substring == "4"  :  Text_substring = four
                    if Text_substring == "5"  :  Text_substring = five
                    if Text_substring == "6"  :  Text_substring = six
                    if Text_substring == "7"  :  Text_substring = seven
                    if Text_substring == "8"  :  Text_substring = eight
                    if Text_substring == "9"  :  Text_substring = nine
                    if Text_substring == "."  :  Text_substring = period
                    if Text_substring == "A"  :  Text_substring = A
                    if Text_substring == "B"  :  Text_substring = B
                    if Text_substring == "C"  :  Text_substring = C
                    if Text_substring == "D"  :  Text_substring = D
                    if Text_substring == "E"  :  Text_substring = E
                    if Text_substring == "F"  :  Text_substring = F
                    if Text_substring == "G"  :  Text_substring = G
                    if Text_substring == "H"  :  Text_substring = H
                    if Text_substring == "I"  :  Text_substring = I
                    if Text_substring == "J"  :  Text_substring = J
                    if Text_substring == "K"  :  Text_substring = K
                    if Text_substring == "L"  :  Text_substring = L
                    if Text_substring == "M"  :  Text_substring = M
                    if Text_substring == "N"  :  Text_substring = N
                    if Text_substring == "O"  :  Text_substring = O
                    if Text_substring == "P"  :  Text_substring = P
                    if Text_substring == "Q"  :  Text_substring = Q
                    if Text_substring == "R"  :  Text_substring = R
                    if Text_substring == "S"  :  Text_substring = S
                    if Text_substring == "T"  :  Text_substring = T
                    if Text_substring == "U"  :  Text_substring = U
                    if Text_substring == "V"  :  Text_substring = V
                    if Text_substring == "W"  :  Text_substring = W
                    if Text_substring == "X"  :  Text_substring = X
                    if Text_substring == "Y"  :  Text_substring = Y
                    if Text_substring == "Z"  :  Text_substring = Z

                    #  Now send the dit/dahs for the Self Test Callsign Character
                    CW_length = int(len(Text_substring))

                    time.sleep(between_character_spacing) # a delay between characters

                    for j in range(0, CW_length):     # Send tones and blink LED in CW

                            Dit_or_Dah = Text_substring[j:j+1]

                            # HIGH closes a relay connect to the ham radio.  LOW opens the relay
                            # This relay closure is the same as pushing down on a straight key

                            if (Dit_or_Dah) == "."  :    # process a Dit
                                    print (Dit_or_Dah)
                                    GPIO.output(keyer, GPIO.HIGH)
                                    time.sleep(Dit) # a delay of "1 Dit" between dit/dahs in a character
                                    GPIO.output(keyer, GPIO.LOW)  #make certain we are not keyed down
                                    time.sleep(between_ditdah_spacing) # a delay bewteen characters
                                    # end if process a Dit

                            if (Dit_or_Dah) == "-"  :    # process a Dah
                                    print (Dit_or_Dah)
                                    GPIO.output(keyer, GPIO.HIGH)
                                    time.sleep(Dah) # a delay of "1 Dit" between dit/dahs in a character
                                    GPIO.output(keyer, GPIO.LOW)  #make certain we are not keyed down
                                    time.sleep(between_ditdah_spacing) # a delay bewteen characters
                                    # end if process a Dah

                            if (Dit_or_Dah) == " "  :    # process a SPACE (delay between words)
                                    print ("<SPACE>")
                                    GPIO.output(keyer, GPIO.LOW)  #make double certain we are not keyed down
                                    time.sleep(between_word_spacing) # a delay of "3 Dit" between words
                                    # end if process a SPACE


            GPIO.output(keyer, GPIO.LOW)  #make absolutely certain we are not keyed down

            t1 = datetime.now() - t0  # how long did it take to send?

            print ("-------------------------------------------")
            print ("Completed in " + str(t1) + " seconds at " + str(int(WPM)) + " WPM to send:")
            print (SendasCW)

            # close and delete voice to text cloud file to get ready for the next voice decode
            time.sleep(1)  # file handling delay, probably not needed
            myfile.close()
            os.remove(Get_file)
            time.sleep(1)  # file handling delay, probably not needed
            myfile = open(Get_file, "w")

if __name__ == '__main__':
    main()
-----

Wednesday, April 29, 2020

FlexRadio: Remote Control ON/OFF State

-----
FlexRadio makes controlling the ON/OFF state of their ham radio rigs simple.   Basically a "short" across the RCA jack on the back labeled REM ON will start the rig and an "open" will power the rig down.
-----
Here's how we did it for the FlexRadio 6400 (video below).

- From SmartSMR go to Setting / Radio Setup.... (I wish SmartSDR would just use CTRL R for this and similar for other menu commands).   In the screen make "Remote on: Enabled":
- Now you need some hardware.  Most hams will have plenty of the wire, wall warts, and connectors gathering dust that are in the diagram below.   However, two items may need to be purchased.  Don't worry; they're cheap:

     - This 120VAC outlet that can be controlled via your smart phone.  Cost from Amazon ~$10.
- A simple relay to "short/open" the REM ON labeled RCA jack on the back of the rig.  Cost for three was ~$8 from Amazon.

-----
You will need to download an app for your smart phone to control the AC outlet.  Then hook things up like this (click to enlarge image):

-----
Here's vid of the whole enchilada in action:
-----
It took us more time to document the project than to actually do it.   It's simple.  Hope to catch you on the air.   dit dit.
-----
 

Monday, April 13, 2020

3D Printed "Cootie" Key for CW/Morse Code

-----
May 2020 Update:  This key was gifted to KK5PJ who was extremely patient with me in my very first CW QSO and the many practice sessions that followed.  THX.
-----
CW or Morse Code is a way ham radio operators send messages with a simple tone of two durations.  It was a must before the days of wireless voice communications and still remains popular because it is a fun challenge.  Also, due to its efficiency messages can get through with limited power or in poor conditions.
-----
There are no shortage of morse code key designs, but in general they fall into a few categories that are discussed here.  We decided to DIY a "cootie" or "sideswiper" key and used our 3D printer to produce this design from Thingiverse.
-----
The result was surprisingly fantastic in both look and feel.   Now, to practice.
-----



Sunday, March 15, 2020

Icom IC7300: Memory External Keypad


-----
The Icom IC7300 is a fantastic and very popular ham radio HF rig.  One thing that we didn't care for is if you utilize the transmit memory functions for CW, phone, etc. half of the touch screen was dedicated to the memory location buttons.
The IC7300 has other features that are a much better use of the touch screen real estate than displaying the memory location buttons.  A few examples are...

Making the Band Scope larger:

Displaying the Audio Scope:

Or getting more information on how the rig is behaving:
-----
In a RTFM moment, I discovered that Icom had a simple circuit that allows the operator to use an external switch keypad to control the top four memory locations. 
-----
A search of our spare parts bin uncovered that all of the materials needed were "in stock".  We set the 3D printer on a mission to print a project box while the soldering iron connected everything up.   Soldering took about 10 minutes; the 3D print a few hours.  The end result is a nicely done external keypad for the memories.   We like it; we like it a lot!
-----
The project is cheap, easy, and useful.  73!

Wednesday, February 26, 2020

ESP8266 Doorbell Sends SMS and Updates Google Sheet

-----
On-line shopping has changed the way goods are acquired.  For most packages it is not necessary to be around for the dropoff.  But... for the important stuff it is.  Those packages always seem to show up right when you are in the backyard for mere seconds causing that frustrating "Personal Signature Required for Delivery" note on the door.  This is our DIY effort to solve that problem.
-----
Needed:
     - ESP8266 (microcontroller with WiFi)
     - 1M ohm resistor
     - reed switch
     - IFTTT account (using the WebHook applet)
     - wire and stuff
     - fundamental knowledge on Arduino sketches (simple code edits).
-----
The connections are simple:

 ----
And the rig will look something like this:
-----
A 1M ohm resister connected from 3.3V to the A0 [ADC] input on the ESP8266 keeps the A0 reading at maximum value.   The normally open reed switch is placed right on top of the coils that activate the doorbell.  These coils act like that electromagnet you build in grade school to ring the doorbell and cause the reed switch to close.  This drops the impedance to the 1M resistor and changes the ADC value on the A0 pin for detection of the doorbell.  Then the SMS is sent to your phone and a Google Drive Sheet is updated.
-----
-----
The sketch you need to upload to the the ESP8266 looks like this:
```````````````````````````````````````````````````````````````````````````````
/*
 *  FEB2020
 *  Door Bell Monitoring
 *  WhiskeyTangoHotel.Com
 * 
 *  Build details at:
 *  http://www.whiskeytangohotel.com/2020/02/esp8266-doorbell-sends-sms-and-updates.html
 * 
 *  On Doorbell ring:
 *    Logs to Google Drive (as an appending spreadsheet)
 *    Sends SMS to cell phone
 * 
 *  ESP8266 uC
*/

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

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

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

// Define and set up some variables
int sensorValue = 0;  // reading from A0.  This pin detects the doorbell (ADC reading between 0-1024)

// Define pins
const int led = 2;     // Blue on board LED is on PIN2.  Active LOW.  Blinks it between reads
const int bell = A0;  // analog input for the doorbell transducer. 1MOhm on board in // with 1MOhm from the reed switch pickup

// Program control variables
int Seconds_dwell_after_detect = 8;  // Prevents logging flood and debounce.   Sensor reads, LED flashing, etc.
int logging = 1; // If 1 then SMS and log to cloud.  Any other value (0) turns it off.

void setup(){  // This is run once.
  pinMode(led, OUTPUT);  // set up the onbaord 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.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
      //Serial.println("Server Start blink loop....");
      delay(5);   // Delay so short the LED looks like it is always on
    } // 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 with the activity of the server starting/restarting
  // 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 (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');    }

  String Status = "Payload_String_for_Google_Sheet";
}
 
void loop(){   // Loop forever or until the Dallas Cowboys win a Super Bowl
  // Read the A0 pin and post based on the delay values set above.
  // The blue onboard LED will fast blink while polling
  sensorValue = analogRead(bell);
  //Serial.println (sensorValue);   //debug only

  // Fast Blink Blue LED while waiting for doorbell press
  digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED. Shows program is running
  Serial.println("Waiting for DoorBell....");
  delay(50);   

  // Use WiFiClient class to create TCP connections for IFTT
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
 
  if (sensorValue < 200 || sensorValue > 300) {  //  A0 values between 200-300 are normal.  Increases (apprx doubles) when DB is pressed
      Serial.println("----------Doorbell Dectected----------");

      if (logging == 1) { // is logging turned on? Non "1" is for debug...  Typically would be set = 1
        Serial.println("***** Logging is ON *****");

        // Build the IFTTT Webhoo Channel for SMS url
        url_SMS = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_SMS + "/with/key/" + MAKER_SECRET_KEY;
        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("SMS payload to IFTTT is:");
        Serial.println(url_SMS);   
        Serial.println(" ");  

        // This must be run before any IFTTT webhook
        const int httpPort = 80;
        if (!client.connect(host, httpPort)) {
          Serial.println("connection failed");
          return;
        }
           
        // Set up IFTTT Webhook Channel to update a Google sheet with the activity. 
        Status ="__Doorbell_on:";
        url_google_drive = "https://maker.ifttt.com/trigger/" + TRIGGER_NAME_google_drive + "/with/key/" + MAKER_SECRET_KEY + "?value1=" + String(Status);
        client.print(String("POST ") + url_google_drive + " HTTP/1.1\r\n" +
        "Host: " + host + "\r\n" +
        "Connection: close\r\n\r\n");
        Serial.println(" ");
        Serial.println("IFTTT url payload to Google Drive is:");
        Serial.println(url_google_drive);
        Serial.println(" ");
   
      } else {   // We are not sending to IFTTT.  Debug mode
         Serial.println("Logging is OFF.");
         Serial.println(" ");
      } // endif/else logging 
   
    for (int x = 0; x < Seconds_dwell_after_detect*2; x++) { // DoorBell dectected. Pause and LED flash for visual acknowledgement
      digitalWrite(led, !digitalRead(led));  // toggle state of the on board blue LED
      Serial.println("Doorbell dectected,  Now in BLINK Loop....");
      delay(500);   } // endfor DoorBell Dwell loop  
       
  }   // end doorbell A0 pressed
}  // end of endless loop
-----
That's it and thanks for stopping by!!!

Monday, July 8, 2019

WIll a High Voltage arc kill this USB thumb drive?

----
We had a 'taser' and an old 64Mb USB stick on the desk and just had to know.   The 60 second video tells all.
-----

Saturday, May 18, 2019

Ham Radio HT turns CW (Morse) 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 away from local repeater stations, stay in accordance to FCC Amateur Radio rules in FCC Section 97, and probably a few other things.  That said, let's continue....
-----
There was talk between the CW operators at the club to have some CW practice sessions or a CW Net on 2M FM.  We will probable never do that (for several reasons) but the idea of converting a ham radio HT into a CW transceiver was an interesting thought project.
-----
Really not much explanation needed; just connect as shown above.  This project uses an electronic keyer, but a simple straight key/oscillator combo could also be used.  Oh... and you will also need to know Morse Code.
-----
Here's the rig in action:
 
-----