DIY Automatic Transfer Switch

I created an Automatic Transfer Switch (ATS) using a DPDT (2 switchover contacts) relay and 2 motor contactors linked with a mechanical interlock module.

Posted in Industrial Automation, Information, Projects | Tagged , , , , | Leave a comment

Wiring Schematic for Bad Boy ZTE Mower

I drew up a partial set (relay functions) of wiring schematics for a 2014 Bad Boy ZT Elite zero-turn mower. These hand-sketched drawings are based on the wiring diagram provided in the user manual. If you are like me, you need to see a schematic to understand the functionality and the diagram they provided is of limited use. Hopefully, these will help someone else out in the future!

Posted in Automotive, Information | Tagged , , , | Leave a comment

Aiden’s Picture in the local Newspaper

Two pictures of Aiden participating in a local trash pickup service project were published in today’s local newspaper.

Posted in Family | Tagged , , , | Leave a comment

Canadian BWCA Canoe Trip

Canoed 65 miles (not including taxi or fishing), 23 portages in BWCA (Boundry Waters Canoe Area) for 9 days and 8 nights. Traveled by van about 2400 miles from Allen TX to Ely MN. The total trip was 13 days and 12 nights. We had 2 crews, with a total of 15 people.

Day 1: 10.1 miles, 4 portages. Started at Prairie Portage, through Basswood Lake, Sunday Lake, Meadows Lake, and Agnes Lake. This was an exhausting day, both mentally and physically. The portages were very hard, the campsite we planned on staying at was already occupied, and the one we found was not great– lots of mosquitos. The highlight was the grilled flatiron steaks for dinner and getting to go to sleep right afterward. Sorted out food rations when at camp and realized we accidentally ate 2 lunches today instead of 1 and were short the meat from 1 more lunch. Our fresh eggs broke and leaked goo all over other items. Already used up 1 of our 5 propane bottles.

Day 2: 6.2 miles. Agnes Lake. A relaxing day, set up hammocks, and a little fishing. I slipped on the rocks near the shore while cleaning a plate and fell right on my tailbone. Very painful in the moment and for weeks later!

Day 3: 14.8 miles, 3 portages. Agnes Lake, Bird Lake, Anubis Lake, Kawnipi Lake. Big push to get through Agnes and on to Kawnipi. Struggled to find one of the portages, got lost once, and didn’t get to a campsite until sunset. Long and hard day on the water. Woke up at 3am shivering from the cold, and realized I needed a pad under my sleeping bag to retain heat.


Day 4: 4.1 miles. Kawnipi Lake. We moved campsites and spent the afternoon fishing. The crew caught enough fish to make a big dinner from it that night. I had the highest fish count of the day with 3. We caught small mouth bass and northern pike. We convinced our crew leader to shorten our trek a little to give us more slack time. Some of us were worried that we might not have enough time to make the return trip if anything went wrong.

Day 5: 6.0 miles, 3 portages. Kawnipi Lake, Keewatin Lake, Agnes Lake. I made the decision to switch out my water shoes for dry socks and boots at each portage. This eats up some time but gives me much better footing and support, which is much needed. The boys don’t have a problem slipping and falling as much as I do!


Day 6: 12.0 miles, 5 portages. Agnes Lake (big waves/wind), Silence Lake, Sultry Lake, Summer Lake, Noon Lake, and Shade Lake. (GPS batteries died) I slipped and fell on a wet slimey rock at a portage and got all my gear wet, including my sleeping bag. That made for a cold night! We accidently found the other crew from our troop and shared their campsite for the night. (it was a huge campsite, so space was not a problem) It was good to catch up and swap stories about our trek so far.

Day 7: 0 miles. Shade Lake. We all slept late, relaxed, took naps, and did some fishing. I made real coffee for the first time, which tasted much better than the instant. The highlight of the day was catching and eating my own fish. (only shared it with Bryson, who paddled me around the lake all afternoon)

Day 8: 8.2 miles, 7 portages. Shade Lake, West Lake, South Lake, a few beaver dams, and Basswood Lake. Camped at the only sandy beach, where we relaxed in hammocks, took naps, swims, and sat in the sun on the beach. The mosquitos were light due to the huge swarms of dragon flys, but the dragon flies disappeared at sundown and the blood-sucking devils had their way with us.

Day 9: 3.6 miles, 1 portage. Basswood Lake to Prairie Portage. A very leisurely float (the wind was at our back the whole time) to the pickup point. We at lunch in the shade under some trees on the lake, and explored the falls at Prairie Portage.

Posted in Events, Family, Leisure, Life, Outdoors | Tagged , , , , , , | Leave a comment

Barcode Format Converter

I’ve been working with systems that use 10-digit barcodes. Different systems require that the data be stored in different ways, and I usually can’t decode the values in my head, so I wound up creating a spreadsheet to do the conversion.

I thought this would be a good practice project to teach myself how to use javascript in a webpage. The biggest take-a-ways I learned are:

  • divide up webpage design into 3 parts: HTML, CSS, JavaScript
    • JavaScript is linked to HTML elements using id attributes.
    • Triggers to run your code are created by using event listeners, such as “clicked on” or “value changed”

Here is a link to the webpage if you want to try it out. You can change any of the values in a box and JavaScript will detect the change and recalculate all the other values on the page. https://briangallimore.com/barcodeconverter/

I didn’t bother styling or dressing up the webpage at all (maybe later).

Posted in Industrial Automation, learning, Technology, Work | Tagged , , , , , | Leave a comment

Private RoIP (Radio over IP) System

I often work in places that are spread out over large distances and are underground or filled with radio obstructions like thick concrete/steel walls and lots of metal equipment. Getting radios to work takes some infrastructure and money.

Something I usually have access to at these sites: a reliable, isolated, fast network that goes wherever the equipment is at. So I wondered if anyone connected radios to a network to ‘extend their range’. One evening down the rabbit hole taught me that yes, of course, they did! I came across the application “app_rpt” that works with the open-source PBX software “Asterisk“, and that seemed like a good way to go.

Ten years ago, there was a Linux distro freely available that made Asterisk setup pretty simple. I guess they figured out how hard it is to make money giving away free software, so that is no longer available. Then I found the “AllStarLink” project. The ASL has a Linux distribution that has everything you need, all packaged up and ready to go. It is made for amateur radio use over the Internet, but with a little modification, it will work on a local network also.

Server

The server is also a node, and I’ve also seen it called a hub. In my case, it is a virtual machine running ASL beta2.0 and configured to be ‘radioless’ which means the radio type is set to “dahdi/pseudo”pitfall warning: don’t bother trying to use the “stable” ASL 1.01 images. Asterisk won’t start due to a conflict. Best I can tell the Debian updates caused it to break.

in the file /etc/asterisk/rpt.conf, add node definitions for all the other nodes on your local network. For example, the server node is 1500, and my other node is 1501. The default port is 4569

[nodes]
1500 = radio@127.0.0.1:4569/1500,NONE
1501 = radio@192.168.7.7:4569/1501,NONE

in the file /etc/asterisk/iax.conf, comment out the line by adding a “;” to the beginning of the line in the [general] stanza pointing to the register.allstarlink.org site. This will prevent the server node from attempting to connect. (we are all local, no internet activity)

Node(s)

The nodes are a raspberry pi loaded with the ASL Beta2.0 image with a special USB radio interface. The interface is a sound card that converts the audio and also handles two extra signals needed to make radio communications work:
1) PTT (push to talk) – this is used when the node wants the radio to transmit
2) COS (carrier operated switch) – the radio turns on this signal when the squelch is open to notify the node that someone is talking

I found 2 options for pre-assembled units in the $50 range:
1) Repeater Builder USB RIM Lite: repeater-builder.com/products/usb-rim-lite
2) ARA-1 Sound FOB by TechNo By George: technobygeorge.com

When looking for radios, keep a few things in mind:
1) the radio needs to provide a COS signal – I found one that I didn’t have to open up and modify, I could just plug into the speaker/mic jack to get all four signals I need (audio in/out, PTT, COS)
2) you need a license to use most radios (FRS is an exception)

in the file /etc/asterisk/rpt.conf, add node definitions for all the other nodes on your local network. For example, the server node is 1500, and my other node is 1501.

[nodes]
1501 = radio@127.0.0.1:4569/1501,NONE
1500 = radio@192.168.7.6:5469/1500,NONE

in the file /etc/asterisk/iax.conf, comment out the line by adding a “;” to the beginning of the line in the [general] stanza pointing to the register.allstarlink.org site. This will prevent the node from attempting to connect. (we are all local, no internet activity)

Laptop Software

If you are already sitting in front of a computer that is connected to the ‘radio’ network, there is really no reason you need a radio, your computer can run software that interfaces with Asterisk. I found a windows program called “IaxRpt” that runs on Linux using WINE. It is basically a SIP softphone application with PTT functionality.

To use this software, a few edits have to be made to your server node. In the /etc/asterisk/iax.conf file, find or add the stanza below and set up a password in the ‘secret =’:

[iaxrpt]
type = user
context = iaxrpt ; Context to jump to in extensions.conf
auth = md5
secret = xxxxxxxxxx
host = dynamic
disallow = all
allow = ulaw
allow = adpcm
allow = gsm
transfer = no

in my version of ASL, the /etc/asterisk/extensions.conf is setup with slick variables that get auto-populated with the correct node number and didn’t require any modifications as the wiki instructions indicated

[iaxrpt] ; entered from iaxrpt in iax.conf
exten => ${NODE},1,rpt(${NODE}|X)

When creating an account in IaxRpt, use the server’s node number (1500 in my case) as the “account” or “name”. (this was not obvious to me and is required for it to connect) The “host” is the IP address of the server node and the “username” is “iaxrpt”. The “password” is whatever you set “secret” to in the step 3 above here.

Click ‘connect’

Then use the keypad in the software to dial “* 3 1501” (replace 1501 with your node number) — this command connects the server node to the other node. It took me a while to figure out this step was required. I know there are other ways of connecting the two nodes, but the important thing to know is that you have to command it to happen.

Click the “TRANSMIT” button to talk to the other node, which will key up its radio and transmit your voice remotely.

Posted in How-To, Projects, Technology | Tagged , , , , , , , | 4 Comments

ODE to Poison Ivy

oh poison ivy!
oh poison ivy!

let me explain,
how much I’m in pain

you grow so well,
but you create a hell

your oil is attracted to my skin,
and then works to dissolve me again

oh poison ivy!
oh poison ivy!

let me explain,
you are making me insane!

Posted in Outdoors, Rant | Tagged , | Leave a comment

MQQT using Node-RED

When I started searching for how to transfer data between 2 computers using MQQT, I saw articles talking about Node-RED, but I dismissed it as being some sort of toy for children. That was probably a mistake because once I installed it, I realized it was both genius and a powerful tool. It lets you do amazing, complicated things without having to get into the weeds in every little detail.

In the screenshot below, the NR session from my Raspberry Pi is on top. The first block monitors a file to see if it changed. When it sees a change, it fires the next 2 blocks, which read the data I am looking for from a file. That data is passed on to the 3rd set of blocks (in purple) which publish the data via an MQQT broker running on the same computer. (mosquitto) The green block is just a debug block and is not needed.

The NR session on the bottom is running on my desktop. A single block (MQQT in) connects to the broker running on the Raspberry Pi and reads to values.

Here is python code running on the Raspberry Pi that retrieves the values and stores them in a pseudo-file. (the /var directory in a *nix machine is actually a location in RAM, not on the HDD or SD card)

#!/usr/bin/env python3
########################################################################
# Filename    : myProg2.py
# Description : write pi ADC values to file
# Author      : bg
# modification: 20210504
########################################################################

from time import sleep
import myADC
 
mydata = [0,0,0,0,0,0,0,0]  #create python list

def loop():
        while(True):
            for i in range(8):
                mydata[i] = myADC.getValue(i)  #bring ADC values into list
                filename = '/var/adc/'+str(i) #create the filename
                ramdisk = open(filename,'w')  #open file in writeover mode
                ramdisk.write(str(mydata[i])) #write data to file
                ramdisk.close()
            sleep(5)

if __name__ == '__main__':
    print ('Program is starting ... ')
#     print(myADC.getValue(0))
#     print(myADC.getValue(1))
    try:
        loop()
    except KeyboardInterrupt:
        #destroy()
        pass
Posted in Industrial Automation | Tagged , , , | Leave a comment

Raspberry Pi Data to Google Sheets

A Raspberry Pi 3B is configured to bring in sensor data through a ADC (analog to digital converter) connected to the pi’s I2C (Inter-Integrated Circuit) serial interface. (I’m using the ADS7830 module that came with a kit that contained all kinds of fun project goodies). I have 2 potentiometers wired to the ADC that I can turn by hand to give me 2 real voltage values. The pi has internet access through wifi.

Raspberry Pi 3B connected to a prototyping breadboard with the ADS7830 module and 2 potentiometers. A backlight LCD is also shown, but not part of this project.

ADC to Pi

I followed the kit‘s instructions for the python language to

  • enable the I2C interface in the Pi’s configuration
  • install the needed os packages
  • import the needed python modules
  • wire the ADC module to the Pi
  • wire the pots to the ADC

I wrote a function so I can get the ADC values from other programs:

#!/usr/bin/env python3
########################################################################
# Filename    : myADC.py
# Description : Use ADC module to read the voltage values
# Author      : sparkygeek.com
# modification: 2020/04/26
########################################################################
from ADCDevice import *
adc = ADS7830()
    
def getValue(chan = 0):
    value = adc.analogRead(chan)    # read the ADC value of channel 0
    voltage = value / 255.0 * 3.3  # calculate the voltage value
    print ('Channel %d ADC Value : %d, Voltage : %.2f'%(chan,value,voltage))
    return voltage

Pi to Google

Follow the directions for getting the Google Python Quickstart project working. (Enable Google Cloud Platform Project API, Create credentials, download your credential file, and install the needed Google client libraries) The quickstart code uses the spreadsheets.values.get method, but we are going to use the spreadsheets.values.append method to add new values to our spreadsheet. Here is the code I’m using to do this:

from __future__ import print_function
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
import myADC
from time import sleep

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']

# The ID and range of a sample spreadsheet.
SPREADSHEET_ID = 'xxxxxxxxxxRb6BXNBORw72feWN3iiaz_xxxxxx'
RANGE_NAME = 'Sheet1'

def main():
    """Shows basic usage of the Sheets API.
    Prints values from a sample spreadsheet.
    """
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    service = build('sheets', 'v4', credentials=creds)

    # Call the Sheets API
    sheet = service.spreadsheets()

    newData = [myADC.getValue(0),myADC.getValue(1)]  # get data from ADC module

    body = {
            "values": [
                newData
            ]
           }
    result = sheet.values().append(
           spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME,
           valueInputOption='USER_ENTERED', body=body).execute()
    print('{0} cells appended.'.format(result \
                                          .get('updates') \
                                          .get('updatedCells')))

if __name__ == '__main__':
    while(True):
        main()
        sleep(2.5)

See it in action!

Posted in Industrial Automation, Projects | Tagged , , , , | Leave a comment

Ignition User Pop Up Data Entry Box

If you want a data-entry pop-up in Inductive Automation’s Ignition, you just call the function to open an input box. This seems simple to computer programmers, but it is different than how typical industrial automation systems accomplish the task. Ignition marries the two worlds, which is one of the things that makes it awesome.

the blue button at the top of the screen has a script that executes when pressed
the script calls the input box, converts to a float, then stores the value in a system tag
standard input box with the parameters from the script
Posted in Industrial Automation | Tagged , , | 2 Comments