Projects

PLC I/O Build

I’ll be taking PLC programming classes soon as I complete a degree in Industrial Electronics, so in preparation I decided to set up a PLC for tinkering at home. I chose a Siemens S7-1200 with TIA Portal as the automation software. Everything is mounted on din rails with pegboard brackets that I 3d printed.

Then I just needed to build the Input/Output trainer. I ordered all the parts from China via Aliexpress to save money. Everything went together smoothly, and it gave me an opportunity to use my new Knipex Ferrule Crimpers (they rock). The trainer has 4 Inputs (pushbuttons and switches) and 4 outputs (LEDs and an alarm). I also added a 24v fan to a rail as an additional output.

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?

Bipolar Electric Motor Restoration

I found this very early Bipolar Electric Motor (circa 1800s) at an estate sale last week. It was in poor condition and non-working, but still an amazing find. Since I love vintage technology, and am especially fascinated with electric motors, I decided to restore this piece of history to working condition.

I started by disassembling the motor and soaking the cast-iron parts in Evapo-Rust for a couple days to remove the rust. Afterwards, I painted the iron black to restore the original color. The gaskets that separate the coils and the base were made of paper and were disintegrating into powder, so I cut replacement gaskets out of rubber. Next, I turned my attention to the bottom coils. The original coils were cotton sheathed copper wire with paper dividers, and both the sheathing and dividers were badly deteriorated. I rewound the bottom coils using enameled copper wire, and I used electrical tape to divide the layers. This was a tedious process, but I just listened to an audiobook about Nikola Tesla while I worked, and the time flew by. I noticed that a couple of brass screws were missing, but I found matching screws in my hardware collection and just had to cut them down. Lastly, I oiled the armature and tried running power to it using my bench power supply (30v). You can see the result in the video below.

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.

Zippo Screwdriver Bit Holder

My favorite EDC screwdriver is the Victorinox Cybertool, which uses 4mm bits. I wanted a way to carry around extra bits for it and I couldn’t find anything on the market, so I decided to design my own solution. This is what I came up with. It’s an insert for a standard zippo shell that utilizes a spring/hammer closing system similar to the original lighter insert. It even sounds and feels like a regular zippo.

You can find the STL file here: https://www.thingiverse.com/thing:6570806

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.

RSS
Twitter
LinkedIn