Antique Radio to MP3 Player

I found this beautiful antique wood radio at an antique store for $12. The electronics were pretty far gone, so I thought it would be a great choice for a mp3 project.

I cleaned and oiled the wood case, and salvaged what radio parts I could for future projects. From Temu, I purchased a fine copper mesh to use as speaker cloth ($2) and a DFPlayer Mini ($2). I loaded an SD card up with music from the 1920s to 1940s, then I wrote a simple script that will continuously play random tracks from the SD card. Using an Arduino and a 3W speaker I already had, I wired the circuit up. I decided to use the original radio knobs to control the Arduino, because that’s a lot more fun. I had to make a custom speaker mount out of some salvaged aluminum sheet I had, which turned out well. Finally, I put a couple of LEDs behind the dial to replace the original incandescent bulbs, and assembled everything. Here is the final result:

Traffic Signal

I found this awesome vintage Eagle Traffic Signal at an antique shop; It’s solid aluminum with glass lenses. I wired it to a controller that allows me to program the light pattern. I also found used mounting hardware on eBay, so I could wall mount it in my workshop. How cool is that?

Ham Shack

I passed my Amateur Radio Technician license a couple of months ago (N4NEC), and I’ve just completed making a proper ham shack for myself. I installed a vertical dual-band 2m/70cm antenna on my roof, on top of a 10-foot mast (using a chain link top-rail). I built a window pass-through using pvc board to route the coaxial cable (LMR-400) into the house, and I grounded it with 8ft of copper grounding rod. I have a mobile Yaesu with an Astron RS-20A power supply, and I bought a WW2 Jeep Field Speaker at a local hamfest for $5 that I re-wired it to use as my external speaker. I also have an SDRplay setup which is great for scanning frequencies visually.

Next I’d like to get setup for HF, but for now I’m enjoying 2m.

Making a Voice Assistant – part 3

I decided to house my voice assistant in this cool antique bakelite radio that I found at an estate sale. (The radio was in pieces and non-working, so it was a perfect candidate for my project.) I also upgraded the Raspberry Pi Zero W to a Pi 3 B+ which runs my code a bit better without getting too hot.

After removing the radio’s internals and giving the case a thorough cleaning, I mounted the components to an aluminum board using standoffs and then mounted the board in the radio with more standoffs. I think the end result looks great on my desk, and you can still see the LEDs through the original cloth speaker cover.

Making a Voice Assistant – part 2

I have made some progress with my Python voice assistant. I have it running on a Raspberry Pi Zero W with an Adafruit Voice Bonnet. The code doesn’t run as fast on the Pi Zero as it does on my pc, and it runs a little hot, but it does work. I’ll experiment with a Pi 3B+ later to see how the performance differs. I’ve added the code to GitHub for anyone interested.

I still need to create the JavaScript side of things to give the assistant more utility. And I need to build an enclosure for it, but sadly my ancient 3D printer has just shuffled off its mortal coil, so until I can afford a new printer the enclosure will have to wait.

Making a Voice Assistant – part 1

I use my Alexa Echo devices daily for various purposes. While I find it incredibly useful, Alexa does have limitations, and it would be great if it were more customizable. I decided to try making my own voice assistant that I can fully customize to my needs. I attempted this many years ago when I was first learning how to code, and mostly failed. At the time, the only method available to me for speech synthesis was to have a database of pre-recorded audio files that I could call when appropriate, and that was very limiting. Now however, there is a nifty text-to-speech conversion Python library called “pyttsx3“. Using this library alongside Google’s cloud speech recognition API (which can be accessed using the SpeechRecognition 3.10.0 library) allowed me to put together a very capable voice assistant. So far, this is what I have:

# -*- coding: utf-8 -*-
"""
Created on Fri Oct 13 13:31:34 2023

@author: austin dixon
"""

import os
import time
import playsound
import speech_recognition as sr
from gtts import gTTS
import pyttsx3
from datetime import datetime
import wikipedia
import time
from datetime import date

def voiceChange():
    eng = pyttsx3.init() #initialize an instance
    voice = eng.getProperty('voices') #get the available voices
    # eng.setProperty('voice', voice[0].id) #set the voice to index 0 for male voice
    eng.setProperty('voice', voice[1].id) #changing voice to index 1 for female voice
if __name__ == "__main__":
    voiceChange()

def get_audio(): #listen to input from microphone
    r = sr.Recognizer()
    with sr.Microphone() as source:
        audio = r.listen(source)
        said = ""
        try:
            said = r.recognize_google(audio) #use Google Cloud to process language
            print(said)
        except Exception as e:
            print("Exception: " + str(e))

    return said

wake_word = "hey Darla"
break_word = "stop"

engine = pyttsx3.init() #start the voice engine

while True:
    text = get_audio() #get microphone input as string
    if break_word in text: #stop running loop
        break

    elif wake_word in text or "darling" in text: #listen for wake word
        text = text.replace(wake_word, '')

#########################################################################################################################
#smalltalk
        if "what is your name" in text or "who are you" in text or "what are you" in text:
            engine.say("My name is Darla. I am a virtual assistiant created by the, brilliant, Austin Dixon.")
            engine.runAndWait()
        elif "hello" in text:
            engine.say("Hello, how are you today?")
            engine.runAndWait()
        elif "how are you" in text or "how are you doing" in text or "how are you feeling" in text:
            engine.say("I'm doing ok, but I do feel a little artificial... Ha Ha.")
            engine.runAndWait()
        
#########################################################################################################################
#search wikipedia
        elif "search" in text:
            text = text.replace('search', '')
            text = text.replace('for', '')
            text = text.replace('the', '')
            text = text.replace('internet', '')
            text = text.replace('wikipedia', '')
            result = ""
            try:
                result = wikipedia.summary(text)
            except Exception:
                pass
            if result == "":
                engine.say("Sorry, I didn't find any results for " + text)
                engine.runAndWait()
            else:
                engine.say(result)
                engine.runAndWait() 

#########################################################################################################################
# timer
        elif "timer" in text:
            text = text.replace('set', '')
            text = text.replace('a', '')
            text = text.replace('timer', '')
            text = text.replace('for', '')
            if "coffee" in text:
                engine.say("Setting coffee timer for 5 minutes.")
                engine.runAndWait()
                time.sleep(300) #set timer for five mins for coffee
                engine.say("Your coffee is ready! .... Your coffee is ready! .... Your coffee is ready!")
                engine.runAndWait()
            elif "hour" in text:
                if "hours" in text:
                    text = text.replace('hours', '')
                    engine.say("Setting timer for " + text + " hours")
                    engine.runAndWait()
                else:
                    text = text.replace('hour', '')
                    engine.say("Setting timer for one hour")
                    engine.runAndWait()
                hours = int(text) #convert str to int to get hours
                secs = hours * 3600 #convert hours to secs
                time.sleep(secs)
                engine.say("Your time is up! .... Your time is up! .... Your time is up!")
                engine.runAndWait()
            elif "minute" in text:
                if "minutes" in text:
                    text = text.replace('minutes', '')
                    engine.say("Setting timer for " + text + " minutes")
                    engine.runAndWait()
                else:
                    text = text.replace('minute', '')
                    engine.say("Setting timer for one minute")
                    engine.runAndWait()
                mins = int(text) #convert str to int to get mins
                secs = mins * 60 #convert mins to secs
                time.sleep(secs)
                engine.say("Your time is up! .... Your time is up! .... Your time is up!")
                engine.runAndWait()
            elif "seconds" in text:
                secs = int(text.replace('seconds', '')) #get the number from text and convert str to int
                engine.say("Setting timer for " + str(secs) + " seconds")
                engine.runAndWait()
                time.sleep(secs)
                engine.say("Your time is up! .... Your time is up! .... Your time is up!")
                engine.runAndWait()
        
#########################################################################################################################
#time/date
        elif "time" in text:
            time_now = datetime.now()
            current_time = time_now.strftime("%I:%M %p")
            engine.say("The current time is " + current_time)
            engine.runAndWait()
        elif "date" in text:
            today = date.today()
            engine.say("Today's date is " + str(today))
            engine.runAndWait()
            
#########################################################################################################################
#if input doesn't match any trigger words
        else:
            engine.say("You just asked me " + text + "... sorry, but I do not know anything about that yet.")
            engine.runAndWait()

At the moment, the voice assistant only has a few capabilities. It listens for a wake word to activate, and then can give you the current time or date, it can set a timer, it can search Wikipedia to answer questions, and it has some small-talk options. I intend to build in many more features, including fetching news headlines, giving weather forecasts, web scrapping various sites, setting reminders, sending emails, and controlling some of my smart home gadgets.

Some of these features are going to require a web server running some custom JavaScript that can gather data from online sources and send that data to my voice assistant via JSON requests. So building the web app that will serve as an API to my voice assistant is one of my next steps.

I also want the voice assistant to run on hardware as an IoT device, so that is going to take some tinkering. I have ordered the components I need to build this, and I am waiting for them to arrive. The final step will be deciding what to use to house my project. Maybe 3D printing an animatronic, talking head? Or recreating the Hal 9000? I haven’t decided yet.

Built a LAMP server

I just finished turning a Raspberry Pi into my own personal LAMP server. I used hardware I had lying around, including a vintage amber monitor (from the Apple II era).

Ran into a few problems, including having to edit the config file to create overscans for fitting the display better on the curved monitor, and it seems a recent OS change makes most tutorials on setting up phpMyAdmin user privileges on a pi wrong now, but I was able to figure it out. Now I have a working server I can SSH into.

Adventures in Commodore 64

I consider myself something of a videogame historian: I like to collect and restore vintage computers, and then run original games on the original hardware. One of my recent adventures has been exploring the world of Commodore 64’s. I purchased my first C64 from a local Frameshop that used it as their primary computer for about 32 years, until the store owner recently passed away. The new owner wasn’t interested in using a Commodore as her Point-Of-Sale system, so she sold me the computer and even threw in the POS software (on a 5.25″ floppy) that the previous owner had written himself.

Since I now own the only copy of this software, I felt that I should try preserving it. To that end, I began experimenting, and I was eventually able to use a SD2IEC in combination with CBM Command to save a d64 image of the floppy disk onto a SD card. Then, I uploaded the Frameshop POS to Internet Archive.

While I was at it, I also uploaded some other obscure C64 files I happen to have in my collection: COSMI Top 20 Tools for Commodore 64/128 (has a neat spinning menu), and MFJ MultiCom64 (software for controlling Ham Radio).

RSS
Twitter
LinkedIn