3Doodler Pen Fix

3D pens are great, especially for kids to get out their creativity. I was one of the first backers for the original 3Doodler on kickstarter years ago, so when I saw they had shifted to really low temp filament and focused on kids, I had to get our little one into the 3D scene. I bought the 3Doodler 3D, which has no motor and is hand-cranked.  If you use old filament, it can get clogged and stop working. Since you can’t make it any hotter, you’re kind of stuck.  Due to the feeding mechanism, you can force the plastic through by hand to some extent, but it eventually clogged irreparably after about a year. You cannot open this one to fix it without destroying it because it is ultrasonically welded together.

So after destroying the hand-cranked version, I got motorized pen version called the 3Doodler Start. This is a big upgrade on manually cranking as you can get more intricate results with what you are making.  However almost immediately after opening the 3Doodler Start pen, it stopped working. We had used some freshly bought, but apparently expired filament sticks from the local hobby store. Luckily this model is MUCH easier to take apart and put back together. Here’s how to do that!

 

How to add a Pedal Control to Your Blackstar ID10 Guitar Amplifier

I recently got a 10 watt Blackstar IDcore guitar amplifier (I had to get a power supply separately). It has a lot of really great built-in effects.  Unlike the larger versions of this amp (the 20watt and 40watt versions) it does not have a footswitch to control these settings. You just have to turn a knob with your hand to change the settings. You can plug this amp into your computer via USB and tweak the controls with the Blackstar Architect app. In the settings for this app, I noticed that there are indeed footswitch options a user has access to, but there’s no footswitch plug on the amp. It is set up for a 2-button footswitch. There are apparently two modes a footswitch can work with the amp.  One mode is called “Default” which allows you to assign each footswitch button to a particular setting (such as “Clean warm” and “Overdrive 1”).  The other option is called “Alternative mode” where you can use one button to increment through the presets, and the other button decrements through the them. I did a bit of googling and found that this hack has been around for a number of years so I got to fiddling…

    

You can see the parts below. All you have to do is solder up a stereo 1/4″ female jack, drill out the hole in the faceplate, and get a pedal to connect to it. Luckily I ordered 2 of these jacks because the pedal I bought had a janky plastic jack that was broken in the package. You’ll also need a stereo 1/4″ TRS cable like this. The cable must be stereo for this to work correctly. TRS stands for “Tip, Ring, Sleeve”.

 

 

Opening the amp you can clearly see the plastic plug on the faceplate (bottom middle circle). This faceplate is reused on the larger versions of the amp. Right next to it are some unpopulated holes on the circuit board.  Sure enough, carefully connecting wires to the right holes here gets the footswitch functions to work! Below you can see the holes labeled (top to bottom) W5, W6, W7, and W8.

 

I used the biggest drill I had on hand which was 3/8″, then I used an exactly to carefully widen the hole for the jack. Next I soldered up the jack itself. It is important to note that the lower solder plug is actually connected to the tip and the highest one is connected to the ground (sleeve).  Leave the wires 4-5 inches long so they will reach the holes on the circuit board. The way to connect them is as follows:

  • W5 connects to Tip.
  • W6 connects to the middle or Ring
  • W7 is NOT CONNECTED
  • W8 connects to the Sleeve (which is the base part connected to Ground)
  • You can see an additional red wire here that connects to the switch in the image below. You don’t touch that.

 

Once I had this soldered up , I was excited to use my footswitch. Sadly, when I opened my hosa footswitch, the 1/4 inch jack was loose because the plastic retainer nut was split.   I went ahead and used my other female 1/4″ jack to replace the broken plastic garbage making sure to keep the TRS connections correct.

That’s it! Enjoy your footswitch controlled Blackstar amp!

 

 

 

 

 

Adding Custom Desktop and Taskbar Icons to you Python Executable

After going through the process of setting up pyinstaller to stop throwing false virus warnings, you probably want your fancy new desktop app to have its own custom icon.  There is a special method required for each of these icons to work as you expect.

Normal windows programs are a single .EXE file with a custom icon. When you open them, there’s a GUI and the taskbar and window icons are the same. To accomplish this, I use pySimpleGUI to design the GUI. This is simple to install and there are several version available such as pysimpleguiQt. Install this in the command line with:

pip install pysimplegui

I actually cheat a little bit here. You can do everything on the command line, but pysimplegui has a great GUI for this that simplifies things called pysimplegui-exemaker.

Step 1: Create a folder structure for your python project.

There’s likely easier ways to do this, but I typically start my projects by visiting github.com and creating a new repository on my account. Then I open github desktop and clone that directory to my computer. This gives me a correct structure for keeping track of any changes in that folder. I’ll create my main python file in this folder and edit the README file with a description and my project goals.

I create a folder to hold my assets named something like “assets” or “img” where I will save my custom icon file. This can be edited later, but I like having something here so I know from the beginning that it is set up correctly.

Step 2. Get or create a .ico file.

This is the image of your icon. They are really easy to find free ones online or you can make one from scratch using a free online editor or some image editors gimp.

Step 3. Setup Relative Filepaths

I add the following to the top of my main python script based on advice from arcade academy which allows relative filepaths for pyinstaller:

if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
os.chdir(sys._MEIPASS)

Step 4: Setting the Window Icons:

To get my custom icon in the pysimpleGUI you have to use a fill absolute path when you create your windows and all popup windows. I typically just create a global variable with the absolute path to the location of the icon.

program_icon = C:\Users\ALaptop\Documents\GitHub\myProjectFolder\assets\icon.ico
window = sg.Window('Program Title Goes Here', layout, icon =program_icon)
filename = sg.popup_get_file('Select a MPA file', no_window=True, file_types=(("myPythonApp Files", "*.mpa"), ("Text files", "*.txt"), ("All Files", "*")), icon =program_icon) 

When you run this code as a script (in VScode for example) you should see the custom icon at the top left of all the program’s windows. But your taskbar will still be a generic python icon.  You won’t see the icon in the windows taskbar until you create and run an executable using pysimplegui’s exemaker or pyinstaller. Simply running the script from the command line will NOT show the correct icon in the taskbar.

Step 5: Setting Desktop and Taskbar icons

Pyinstaller can set up a template for us to fill out for our project so it will be able to bring in all the external files we want (like icons). Simply run the following command in the command line to generate the template:

pyinstaller --onefile --noconsole .\my-Program.py
This creates a new file called “my-Program.spec” in the same folder as your code. Open this in a text editor and it’ll look something like this:
# -*- mode: python -*-

block_cipher = None

a = Analysis(['my-Program.py'],
pathex=['C:\\Users\\ALaptop\\Documents\\GitHub\\myProjectFolder'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='my-Program',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=False )

Step 6: Customizing the .spec file

Once the .spec file is created, you’ll want to edit it. In the Analysis section in datas I put the links to any assets the program will need such as images, sounds, etc. If I only have images in a subfolder named “img” it would be

datas=[( 'img/*png', 'img' )],

The first parenthesis is where the files are currently stored, and the second is the name of the folder inside the temporary folder that pyinstaller uses when the exe runs. Remember how I said Pyinstaller creates a self-extracting zip file? Here’s where that comes into play. You are telling pyinstaller where you stored your assets relative to your project’s folder, and then telling it where it can put these files later. This path is important especially if you used relative links in your python code. If your EXE can’t find the files it needs, it’ll crash giving you a popup stating “Failed to execute script my-Program”. This can be confusing to debug if you don’t know how to see what the executable is looking for. Also, this expects that you pasted the lines from Step 3 above into your code which sets up relative filepaths.

To understand and to debug this, you have to remember that the EXE pyinstaller creates is a zip file that is made up of a bootloader (which can actually run your python code), your python script, any libraries your script uses auto extracts a folder, and any other files needed to run your script (images, audio, etc). When you run the executable, it actually decompresses all this and sticks it in a folder in your C:\Users\<username>\AppData\Local\Temp in a directory named “_MEIxxxxx” where the ‘x’s are a random number. This folder exists only while the executable (or the error popup) is opened. As soon as you close it, this folder is deleted. You need to visit this folder to debug issues. To debug, you’ll need to pay close attention to the paths in the spec file and your code’s paths and then comparing them to the location of assets inside this temporary _MEIxxxxx folder.

For instance, in the datas entry above, the second set of quotes denotes the name of the folder INSIDE the temporary folder. That’s where pyinstaller is placing the PNGs I refer to in that line. If my app keeps crashing for some reason, I can make sure that these files exist in the correct folder in the C:\Users\<username>\AppData\Local\Temp\_MEIxxxxx\img folder.

Add the absolute path to your custom icon to the .spec file. This is added to the “EXE” section as part of the list of settings. I also added “console=False” so it would not open a console while executing.

console=False , icon='C:\\Users\\ALaptop\\Documents\\GitHub\\myProjectFolder\img\\icon.ico')

You can see my full spec file below. Once you’ve saved the spec file changes, you will issue the same command as before, but use the .spec file instead of the python file.

pyinstaller --onefile .\my-Program.spec

Just for good measure, I also put the fullpath in the pysintaller command as well sometimes:

pyinstaller --onefile --noconsole --icon "C:\\Users\\ALaptop\\Documents\\GitHub\\myProjectFolder\\icon.ico" --add-data "*png;." .\my-Program.spec

Here’s the full final .spec file I would use:

 # -*- mode: python -*-

block_cipher = None


a = Analysis(['my-Program.py'],
             pathex=['C:\\Users\\ALaptop\\Documents\\GitHub\\myProjectFolder'],
             binaries=[],
             datas=[( 'img/*png', 'img' )],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)

             
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='my-Program',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=False , icon='C:\\Users\\ALaptop\\Documents\\GitHub\\myProjectFolder\\img\\icon.ico')

 

Program Icon (Desktop Icon):

This will be the icon users see and doubleclick on their desktops to open your app.

After running pysimplegui’s exemaker one time for your project as normal, it will create a .spec file template for you.  Once the .spec file is created, you have to put the absolute path to the icon you want to use in that .spec file. For instance, I had my icon in a folder called “img” inside my python’s project folder. Paste the path at the bottom of the EXE section like this:

console=False , icon='C:\\Users\\ALaptop\\Documents\\GitHub\\myPythonApp\\img\\icon.ico')

Just for good measure, I also put the fullpath in the pysintaller command as well:

pyinstaller --onefile --noconsole --icon "C:\\Users\\ALaptop\\Documents\\GitHub\\myPythonApp\\icon.ico" --add-data "*png;." .\myPythonApp.spec

Window and Taskbar Icon:

This is set in pysimgplegui when you create any window (even popups can be given a different icons). The only way this works is if you code the full absolute path in the python script, but you won’t see it in the taskbar until you create and run an executable using pysimplegui’s exemaker or pyinstaller. Simply running the script from the command line will NOT show the correct icon in the taskbar.

program_icon = 'C:/Users/ALaptop/Documents/GitHub/myPythonApp/img/icon.ico'

filename = sg.popup_get_file('Select a MPA file', no_window=True, file_types=(("myPythonApp Files", "*.mpa"), ("Text files", "*.txt"), ("All Files", "*")), icon =program_icon)

 

 

Best way to make GUIs and Executables in Python for Windows, Mac and Linux

Typically when making a program, I want users to have a familiar experience: a single .EXE file instead of some weird scripts that requires other programs to run. There are a few different ways of accomplishing this using python,. On this page I’ll explain the simplest way I’ve found to get this result, and how to debug if you run into problems with this method.

I wrote about using pySimeplGui for making dead simple GUI interfaces for python code before, and even have a simple example project,. Check those two articles out for that aspect.

As for creating the .EXE file, there are several packages that will allow you to create executables of your python scripts. The reason to do this is that you don’t want end users to have to install python  (simplified usage of your app) or you don’t want anyone seeing the actual python code. The way they work is that they create a self-extracting zip file that has your code, all associated libraries (including DLLs), and most crucially, they have a small bootloader that is a python interpreter executable. There are several available such as cx_Freeze, bbFreeze, Py2App, Py2Exe, Pyinsaller, or you can create your own from scratch  (See a chart comparing them here).

There are some problems with these tools. Several of these are not currently updated. Some don’t allow you to create a “One File” solution, meaning they require additional folders of files, etc. which in my view isn’t a true executable experience from the user perspective.  For some reason, there’s a known issue with some of these which makes the resulting executable get incorrectly flagged as a virus by virus software. There are some ways around this however.

I’ve tried out a few of these and given my recent experience with PySimuleGui, and the features I wanted, I settled on pyinstaller.

PysimpleGUI has its own interface for pysintaller to simplify things called pysinstaller-exemaker.

For some reason, my resulting executables kept getting flagged with false virus warnings on windows. I tested in Virus Total which runs multiple virus scanners at once on your file. Sure enough, lots came back with false positives.

I found two ways to fix this problem. As with most things, there’s the easy way, and then there’s the right way.

The easy way requires specific versions of python and pyinstaller on your machine.

The other way to prevent false positive virus scans is to recompile pyinstaller’s bootloader from scratch. While I did this (and explain it below), it is non-trivial.

The Easy Way: Install Correct Versions:

The easiest way to not have the virus issue is to use the correct versions of pyhton and pyinstaller as described on a no-dead link on yuriss.com.  This Completely solved the problem and is SOOO simple!  Basically you just install the correct version of python (Version 3.7.4) from python.org. If getting the windows version, make sure it is the 64-bit version, other users seem to have had issues with the 32-bit version.

Once this is installed, you can use pip on the command line to install Pyinstaller 3.4:

 pip install pyinstaller==3.4

The Right Way: Recompiling pyinstaller’s bootloader from scratch

This may be needed for future version of python or pyinstaller. Since I already went through the headache of figuring out how to do it, I’m documenting it here.

If using a version of pyinstaller that throws the virus warnings, you can’t just go to the folder PIP installed it to and compile it there. That’d be too easy of course! (This took me a long time to figure out)… If you try to do that, it’ll fail with cryptic errors.  The reason is that the file path is too long.

To overcome this, you have to perform the following steps:

  1. Clone pyinstaller’s source to a folder in your C drive, then
  2. Rebuild the bootloaders,
  3. Install pyinstaller with pip,
  4. Overwrite your pip installation with your newly built bootloader files…

Duh, obvious right?! (omgwtfwhyisthisalwayssohard!?)

Details for the steps are below:

Step 1: Open a powershell as admin and go to C:\\

cd c:\\

Download the source of pyinstaller. This will create its own folder for pyinstall:
>pre>git clone https://github.com/pyinstaller/pyinstaller

Step 2: Cd into the bootloader’s build folder:

cd .\\PyInstaller\\bootloader\\

Then run the script to reinstall. If you get an error telling you there’s no such thing as ./waf then you are in the wrong folder.

python ./waf all

Step 3: Once this is done, you can go back to vscode or wherever and install pyinstaller from pip

pip install pyinstaller

Step 4: Then navigate to python’s site packages, and copy the newly built bootloaders into the appropriate place. NOTE: PyInstaller is case sensitive here, so be careful. We’ll first make a backup of the original bootloader folder:

 mv C:\\Users\\ALaptop\\AppData\\Roaming\\Python\\Python38\\site-packages\\PyInstaller C:\\Users\\ALaptop\\AppData\\Roaming\\Python\\Python38\\site-packages\\PyInstaller.bak

Then copy in our freshly compiled bootloader:

mv C:\\PyInstaller\\bootloader C:\\Users\\ALaptop\\AppData\\Roaming\\Python\\Python38\\site-packages\\PyInstaller

Note: Now to use pysimplegui-exemaker, you must edit your computer’s %PATH environment variable to locate pyinstall. Click the windows key on the keyboard, type “environment” and click to open the first suggestion. This window will pop up that has a button towards the bottom named “Environment Variables” that you must click. In the top window pane, find “path” or “PATH” and doubleclick that line to edit it. You’ll now be able to enter a new value. You want to add the path to where pip installs its scripts.  In my case, I pasted in the following:

 C:\\Users\\ALaptop\\AppData\\Roaming\\Python\\Python38\\Scripts

Then test it out:

python -m pysimplegui-exemaker.pysimplegui-exemaker #<--If you use pysimplegui's exemaker (NOT a typo, must exactly this way) OR

pyinstall --onefile ./myProgram.py #<-- If you just use pyinstaller directly

Tada! No more virus warnings!!!!

 

Check out my other post about how to replace the default python icon in your executable files.

2nd Weather Balloon (from 2010)

Back in 2010 I was part of a team that sent up a couple of weather balloons on a NC spacegrant. I posted about the first one (which flew straight into a thunderstorm) a long time ago, but with the recent weather balloons in the news, I decided to go back and look up my old photos from the second balloon.  In the pic above the yellow balloon was the first one, the green plot is of this second balloon.

We launched from Monroe Airport in NC and the path of the balloon followed the path of HWY 74, which is the main road in the area. There are a couple of good pics of Wadesboro, NC and Lake Tillery as well.

This one went about 75k ft. in elevation. You can *just* make out the curvature of the earth in some of the photos. We launched on a beautiful clear day and we were able to visually track the balloon’s full ascent AND descent. Fun times! Luckily it didn’t freeze on the ascent so we got some better pics. We stocked this one with a bunch of candy like last time and it was fun eating space candy again!