Cleaning Flux from Printed Circuit Boards (PCB)

I got some professional looking PCB boards manufactured for a project recently. The boards look great compared to anything I could do myself.

Problem is, after I solder on the components and try to clean the flux off, I’m always left with a mess. My great looking boards end up with white stains from trying to remove the flux.

In researching this problem, I’ve learned about water soluble solder and no clean solder. I will be trying those in the future, but I’m still left with my most recent board which needs to be cleaned.

After looking around the interweb and doing some experiments here is what worked very well (though not quite perfect).

  • Apply all liquids with the board vertical to avoid getting anymore than necessary on the front side of the board.
  • Apply 99.9% isopropyl alcohol with a toothbrush to remove the flux. I don’t seem to need to scrub long or hard to get it loosened up.
  • Apply Simple Green with a sprayer. Brush the whole board again with a toothbrush. It may help to apply plenty of Simple Green to help flush the flux away.
  • Spray the board repeatedly with distilled water until the simple green & flux are flushed from the board.
  • Blow excess water off board with compressed air.
  • Finally, dry the board with a heat gun or hair dryer, taking care not to let it get too hot.


Posted in c-electronics | Tagged | 2 Comments

Automating Testing Using Video

I found myself needing to verify caller ID operation of a couple of troublesome telephone handsets. To properly test, I want to run 1,000 calls to the handsets and verify they decode caller ID every single time.

During early testing, I would manually call the handsets about 20 times to see if they looked good. Typically the error occurs every 3rd-4th call so that was a little slow but do-able. But there is no way I’m sitting still to watch 1,000 calls.

I could video record the handsets, but watching the video is no faster and trying to fast forward was going to be clumsy as well.

What I really need is a way to toss out most of the video frames then I could just advance a few frames to see the next call.

I recorded the video off a webcam using VLC using this procedure:

After some research I found a utility call ffmpeg which does many things, but for my current need, you can tell it to extract <n> frames per second and save them as a file.

ffmpeg can be found here:

My first test was to extract one frame per second which I did with this command:

    ffmpeg -i myfile.mp4 -vf fps=1 c:\tmp\pics\out_%%03d.png

This created a PNG file once a second (1 frame per second), reading myfile.mp4 and creating a series of PNG files called out_001.png, … .

This worked pretty well, but a complete test cycle takes about 20 seconds so I was ending up with 20 PNG files / cycle to flip thru. That’s too many.

I watched the testing process, and both phones’ displays are on for about 10 seconds from the time the CID message comes thru. If I were to capture a frame every 5 seconds, that would be about perfect.

So I ended up using this command:

    ffmpeg -i myfile.mp4 -vf fps=0.2 c:\tmp\pics\out_%%03d.png

Now I end up with about 5 frames per test call.

Using picasa to view the first file, I can go to the first picture showing the caller ID message. Then I just press the right key 5 times and I’m on the same spot in the next test. That I can do very quickly.

I can process roughly 1 test every 2-3 seconds flipping thru 5 pics verses having to watch hours of video which just isn’t going to happen.



I’ve went thru this process quite a few times now. Works well, but having to constantly click thru still images is a pain.

So using ffmpeg again as directed here:

I created a video to watch. I can then stare blankly at the video and just pause when I think an event has been missed.

When I did the extract, I was extracting 1 frame from the original video every 10 seconds. When I create the new video, I want to see each of those extracted frames every 1/2 second (2 frames per sec). This is the command I used to construct the video:

"\Program Files\ffmpeg\bin\ffmpeg.exe" -framerate 2 -i f11b_%%04d.jpg -c:v libx2
64 -r 30 -pix_fmt yuv420p outx.mp4

My input file is f11b_0001.jpg, f11b_0002.jpg, …

My output file is outx.mp4

I’m reading these jpg files at a rate of 2 / sec (-framerate 2).

The output MP4 file contains 30 frames per sec (-r 30).


Posted in c-Misc | Tagged | Leave a comment

Migrating Raspberry Pi Version 2 SD card to Raspberry Pi 3 Hardware Platform

My development RPI has been an RPI version 2 since version 2 was first released. Further, everything except the boot files have been moved to a USB-based hard drive to increase performance (using a procedure much like this:

I needed a new RPI for a project and found version 2s are more expensive than version 3s so I purchased a 3 to be my new dev machine and I’ll use the old hardware for the new project.

The problem with upgrading my dev hardware is the last thing I want to do is screw with the software on it. It has taken a lot of time to get it where I want it.  So it is important that I can just transfer the SD card and USB drive to the new hardware.

Here is the procedure I followed which worked just fine. I won’t waste time describing each step blow-by-blow. If you need to know the details, you can google them as I did.

Backup The System

If something goes wrong, you will want a backup. Expect to spend a few hours backing everything up (at least if you have a very big USB drive).

  • Poweroff the old RPI2 system.
  • Backup the SD card using Win32DiskImager
  • Mount the USB drive to a PC based linux system.
  • Zero free space on the USB drive:
sudo cp /dev/zero /mnt/usb/bigfile.zer
sudo rm /mnt/usb/bigfile.zer
  • Unmount the USB drive
  • Use fdisk -l to determine the device of the USB drive
  • Use dd to backup the entire drive to a location of your choosing:
dd if=/dev/sdb conv=sync,noerror | pv | gzip --fast > sdb-dd-yymmdd.gzip

In above example, I determined my USB drive was /dev/sdb so that is my source. I like to name the output file the drive name + backup type (dd or ntfsclone usually) +  date.

  • At this point, I put the SD card and USB drive back on the old version 2 RPI and restarted it.
  • I then did a DUMP of all files to a remote location so I can recover individual files if necessary.
  • Finally, I created a list of all installed packages using:
dpkg --get-selections | grep -v deinstall > //mnt/netdrive/tmp/installed-packages.lst

Upgrade the Operating System

My RPI Version 2 was running Raspian version Wheezy. You MUST be running Jessie (or later) OR do the following dist-upgrade.

As I understand it, dist-upgrade doesn’t upgrade you to Jessie, but makes sure you get ALL available packages (apt-get upgrade may hold back packages). My RPI 2 is using Wheezy, I followed this update and it worked fine for me.

  • Update the list of packages:
sudo apt-get update
  • Do the dist-update:
sudo apt-get dist-upgrade
  • Reboot to load the changes:
sudo reboot
  • Make sure things are working, then power off your RPI 2:
sudo poweroff

Upgrade The Hardware

At this time, pull the old RPI2 out. Transfer it’s SD card and connections to the RPI3. Power the RPI3 up.

Mine came up flawlessly following the procedure.

Good luck!


Posted in c-rpi | Tagged | Leave a comment

Making a Data Only Cable For Teensy/Arduino/Nano

Been working on a complicated teensy project that is going to the other side of the state for testing. So I’ve been building a testing platform that consists of a Raspberry Pi connected to the Teensy via USB. I can connect to the RPI and monitor/update the Teensy.

One of the requirements is that I be able to cycle power on the teensy just in case duty hits the fan. I’ve got this great little device for that very purpose:

found at

The one problem I’ve realized with this idea is I cannot just remove power from my device to reset it because the RPI will continue to feed power to the Teensy via the USB cable. (Actually there is a way to have RPI kill power to its USB hub but it also kills power to the ethernet module. It has worked in testing but seems a little dicey to really rely upon).

I need to kill power from the USB cable. The obvious way to do this is to slice the USB cable open and cut the power line. Not too hard to do, but I really don’t want to send a unit out to the ‘customer’ with electrical tape around one of the cables. That’s not cool.

I was looking around for data only USB cables (which are available but kind of expensive) and stumbled across someone that was doing the reverse of what I wanted – he was getting rid of the data signal. BUT, his method was perfect. See

I applied the same idea and cut a tiny piece of clear packing tape and applied it to the +5V contact on the A side of the USB cable:

dataOnlyYou should be able to see the tape covering the contact on the far right.

This works great and now when I kill power to the device, it actually turns off.

Nov 2016 Update:

The size of tape is pretty close to 3mm x 25mm.

Posted in c-arduino, c-rpi, c-teensy, Uncategorized | Tagged | 1 Comment

Remote Monitoring and Upgrading of Arduino/Teensy via Networked Raspberry Pi

This post covers how to remotely monitor / upgrade an Arduino or other MCU behind a firewall.

(Jump down to the Dec 2016 Update for Notes about the Duplicity Service that will easily and quickly allow remote access to an RPI)

Let’s look at an example:


On the far right of the diagram is an Arduino ‘in the field’ and I want to access it from a local PC which is on the far left.

The first step to accessing the remote Arduino is to connect it serially to a networked computer. I propose using a Raspberry Pi for this purpose since they are cheap. I then wish to use putty and VNC to access remoteRPI to finally access the Arduino. But just adding remoteRPI doesn’t make either accessible.

There are a couple of problems with this solution. First, remoteRPI will most  probably be assigned a private IP address by DHCP. There is no direct access of remoteRPI due to the remote firewall, remoteFW. A hole is going to be needed in the firewall.

Putting holes in ‘customer’ firewalls is a difficult proposition, at best. Having the ‘customer’ create the hole is probably impossible. Gaining access and doing it yourself is equally impossible.

The usual way to get around the firewall access issue is to have the remoteRPI create the connection back to the local network. The remoteFW has no issues with outbound connections. We create and use that connection when necessary.

Using remoteRPI to create the connection is the access method I will implement here. This will be done using an SSH reverse tunnel.

At boot time, remoteRPI will open an SSH reverse tunnel to localRPI. I’m using a Raspberry Pi for localRPI, but any linux system will work. This tunnel remains open continuously. When you want to gain access to remotePRI, you make an SSH connection to localPRI which forwards to remotePRI.

I was unable to find any references that fully showed implementing the diagrammed solution from begin to end. This blog will cover all of the config changes and commands to implement this tunnel but not the whys. You can google all of the commands and learn the why easily enough so I won’t try to duplicate the effort.

Allocating TCP Ports

We are going to need to define 3 TCP ports for our project. I like to use a random number generator (google random number generator) to select a port between 10,000 and 32,767.

27045 – Local Firewall NAT Port

This is the port that will allow remoteRPI access to localRPI via SSH (port 22).

27046 – SSH forwarding port

We will connect to this port on localRPI when we want to access SSH on  remoteRPI.

27047 – VNC forwarding port

We will connect to this port on localRPI when we want to access VNC on  remoteRPI.

Create NAT Rule on localFW

remoteRPI needs to connect to localRPI via SSH (port 22). We will create a port forward rule on the localFW to allow this access; however, we will expect port 27045 to be the destination port on the firewall and we will translate that to port 22:

Application Protocol Source Net Port From IP Address Port To
sshRevTun TCP 27045 [localRPI] 22

This rule states any inbound packet with destination port of 27045 will be sent to IP address (localRPI) using destination port 22.

Activate the firewall rule.

You can then do a simple test on the rule by using a remote port check utility such  as and enter the external IP address of your firewall and port 27045 to verify the port is open.

Enable Global Port Forwarding

By default, any reverse SSH tunnel built on localRPI will only be available to localRPI. My requirement is that I be able to use any PC on my local network to access remoteRPI, so we need to allow others the ability to use the reverse SSH tunnel.

On localRPI, in the file /etc/ssh/sshd_config, add the following line anywhere:

GatewayPorts yes

Save the file and restart SSH with

service ssh restart

Make Scripts to Create the Tunnels

We need two scripts to build the two SSH reverse tunnels – one for each protocol (SSH and VNC).

I create these using the standard pi user and simply place them in pi’s home directory.

Put these commands in a file named sshRevTunSsh:


sleep 60

while [ true ] ; do
  ssh -p 27045 -N -R \*:27046:localhost:22 -o "ServerAliveInterval 30" \
    -o "ServerAliveCountMax 3"
  sleep 30

And put these commands in a file named sshRevTunVnc:


sleep 60

while [ true ] ; do
  ssh -p 27045 -N -R \*:27047:localhost:5900 -o "ServerAliveInterval 30" \
    -o "ServerAliveCountMax 3"
  sleep 30

don’t forget to make them executable:

chmod 577 sshRevTunSsh sshRevTunVnc

These scripts will connect to localRPI by routing to the localFW ( and then being forwarded by the firewall to the localRPI system where they will attempt to log on as the pi user.

I am using a DNS name You can use a DNS name or the external IP address of your router as well. If your router is assigned its WAN IP address using DHCP, you should seriously consider using a dynamic DNS service such as Otherwise, when your ISP finally forces the IP address on your router to change, the SSH reverse tunnel will fail, and it will be be difficult to fix.

Test Scripts

You might want to comment out the initial sleep 60 command as this is really only necessary when the script is executed at boot time.

To start the SSH reverse tunnel for SSH, type


You will be asked for the pi user password for localRPI. Then there will be no further output, it just runs.

Now from a local PC, run putty. For the hostname/IP address, enter the hostname for localRPI and specify 27046 as the port:

	localRPI		27046

This will connect you to remoteRPI. Enter a user/password for the remoteRPI system.

Should the script fail, you can place -v in the SSH cmd of the script to get debugging output.

Now run the script for sshRevTunVnc. From a local PC, run VNC and login using


This will connect you to VNC on remoteRPI.

Create SSH Reverse Tunnel without Requring a Password

The scripts to start the SSH reverse tunnels allow automation, but having to enter a password prevents us from actually automating the process.

There are many locations on the web explaining this process. I will do a very brief example of it.

On remoteRPI, logon to the pi user and type:

cd ~/.ssh
ssh-keygen -t rsa

This creates a public/private key pair for password-free logins.

Now copy the remote RPI’s public key to the local RPI

scp -P 27045

On the local RPI, you want to append that key (in the file temp.key) to the authorized_keys file:

cd ~/.ssh
cat temp.key >> authorized_keys

Rerun the scripts and they will no longer require passwords.

Dealing with IP Address / Key Changes

Since originally writing this, I’ve had to deal with changing the local RPI host. SSH knows the host has changed which causes a message along the lines of

Someone could be eavesdropping on you right now (man-in-the-middle attack)!

To fix this problem, you need to use ssh-keygen to reset the key:

ssh-keygen -R <ipaddress>

Because a non standard port is being used, it appears you must specify that as well for this specific type of access, so specify that as

ssh-keygen -R [<dnsname>]:<port>

Once the old key is deleted, follow the procedure above to regen and redistribute keys.

Fully Automate the SSH Reverse Tunnels

Everything is now in place to allow the SSH reverse tunnels to be created at boot time. Should the tunnel go down, the script will automatically restart it.

We will run the scripts at boot time using cron:

sudo crontab -e

and add the lines

@reboot su pi -c "/home/pi/sshRevTunSsh " >/dev/null 2>&1
@reboot su pi -c "/home/pi/sshRevTunVnc " >/dev/null 2>&1

Don’t forget to restore the ‘sleep 60’ commands in the script files if you  commented them out.

Reboot the system. You can verify the scripts are running:

pstree | grep sshR
        |      `-cron---sh---su---sshRevTunSsh---ssh

Finally, again test that you can access remoteRPI from your local PCs.

Issue Programming Arudino Nano from Raspberry Pi

I’m sticking this note here because I don’t have a better place for it yet.

Now that I’ve got the remoteRPI operational, I’m starting to experiment with actually controlling / updating an Arduino.

I started with a Nano and have found there is a problem with Nanos. When you first connect the Nano to the RPI via USB, it will come to life and populate /dev/tty properly and you can access it via /dev/ttyUSB<n>.

But, when the RPI is rebooted, the Nano disappears. Nothing seems to bring it back short of unplugging the USB cable and reconnecting. Not acceptable.

This problem appears to only occur with Nanos due to a design mistake when implementing FTDI. This is covered here:

I have since moved on to an Arduino Uno for testing and it works fine – when the RPI is rebooted it is reconnected properly to the USB port.

Dec 2016 Update:

Reverse Tunnel Status:

I’ve been using the aforementioned scheme to access a remote RPI for 4 months now and in general it works great. The only issue I have is for some reason the local linux server where the ssh tunnels terminate periodically has an issue such that I can no longer SSH into the tunnel. The only solution has been to reboot the local system which then causes the RPI to reestablish the tunnels and all is fine.


I recently learned about, a 3rd party service to allow remote access to your RPI.

It is super easy to get your RPI up and running on this service. They give you a command to type at the RPI’s bash prompt and it fully installs and starts the duplicity service. Then you go to your devices at and can get to a shell prompt on their web page.

They also provide ‘wormholes’ that allow you web access and VNC access to the RPI. But this access requires manually installing all the necessary services, etc.

The service is free, at least at the moment. How they do this for free is puzzling. I’m not complaining, but if I were going to use this for anything ‘production’ I would want to know they aren’t going to go out of business because they are giving the service away. It might be a royal pain to recall devices and come up with a different mechanism if they were to vanish (or start charging more $$$ than I could justify).

At the moment I don’t see a way to transfer files TO the RPI. It may be this needs to be done by creating a webdav directory that allows write access. FTP/SSH access, like I can use with the reverse tunnels I create in my scheme is not possible as far as I can tell.

Still, for easy remote access of the shell, this is a fantastic alternative.

I decided to use dataplicity for an emergency backdoor to remote RPI in case the sshtunnels completely fail. I’ve also noticed there is no way to cut/paste in their terminal emulator which is makes it not quite as useful as one would hope.

Another update for Dataplicity:

My ‘puzzlement’ has been answered quickly. I just received an email that they will be charging between $2 – $3.50 / mo.

Oct 2017 Update

I have three RPIs that maintain a reverse SSH tunnel as outlined, but they have driven me crazy because if the local firewall router is rebooted, the tunnel is not re-established and I have to do back flips trying to restart the tunnels (either have the user reboot the RPI which is risky since they can only remove/reapply power OR use dataplicity).

I finally had time to work on this issue and I believe I have solved the problem. There is a utility called autossh that will monitor the tunnels and restart them if they go down. I would think the keep-alives would do that, but they don’t.

Install autossh. Then in your startup script, use:

autossh -M 0 <user>@<dnsName> -p <sshPort> -N -R <inputPort>:localhost:<outputPort> \
 -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \
 -o ServerAliveCountMax=2

Using my example above, this would be setup as:

autossh -M 0 -p 27045 -N -R 27046:localhost:22 \
 -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \
 -o ServerAliveCountMax=2

So far, this has worked without problem.

Posted in c-arduino, c-rpi, c-teensy | Tagged | Leave a comment

Refurbishing a Skimmer Weir Gate

A weir gate is attached to swimming pool skimmers to keep the rubbish collected by the skimmer from floating back out into the pool.

The ones I’ve seen use a Styrofoam float to keep the gate up.  I noticed my pool has been hard to keep clean lately, and I realized the old weir gate was no longer floating properly.

OK, I should say there is very little good reason to refurbish a weir gate because they are really cheap. Unless you are really cheap (nothing wrong with that), OR, as in my case, the new one you ordered doesn’t quite fit.

The weir gate I ordered was just a smidge too large. I was going to need to trim maybe a 1/4″ off. But first I needed to get the old one out which was kind of a mystery. All instructions I have found talk about installing the new one not removing the old one.

As I looked carefully at it I looked like I could get a very thin screw driver under the ‘post’ I was seeing and maybe pry it out.  Sure enough I was able to work the ‘post’ out of its socket and I realized it wasn’t little pins holding the weir gate in place, but the posts set in shallow sockets.

I don’t know if they all work the same, but the weir gates I have have a rod inside them that is like a compression curtain rod as you can see from the picture.


If you can remove the weir gate intact, it is perfectly easy to refurbish.

Once the weir gate was out I could remove the Styrofoam and sure enough it was badly water logged. It weighed as much as a small brick (pictured at the top).

As I looked at the Styrofoam, I realized I had extra Styrofoam in my parts bins I’d saved from packing material – it comes in handy once in a while. I located my stock and it has the same texture as that in the new weir gate, so I decided to use it (leaving the entire new weir gate for future use should I need it).

I cut my stock down to the same dimensions (2nd block of Styrofoam above) and inserted into the weir gate.

Now to reassemble. The new weir gate has pins holding the compression rod in place. I had tiny picture nails of about the same size. I stuck one nail in on one side, then used a dowel to compress the rod into place so I could get the 2nd nail positioned (having a helper here is very, well, helpful).

Once the pins were in place my old weir gate looks just like the new:


Note the nails are sticking out on the flat side – this is the side you will be able to access with pliers once the gate is positioned properly.

At this point, installation is simple – position the gate so the posts are aligned roughly with the sockets. Pull the first nail, check alignment again, then pull the 2nd nail and you are done.

Try not to drop the nails in the pool!

Posted in c-Misc | Tagged | Leave a comment

Upgrading Teensy Code in the Field

I’ve got a few Teensy projects in ‘production’ now and I know I’m going to have to update the software onsite. In fact, I need to be prepared to allow an end-user to upgrade the software as one Teensy that is located 1000’s of miles away now.

In the back of my head I figured this must not be too hard since the Teensy has a nice windows based programmer. Sure enough, it is slam dunk. Well, pretty close.

This procedure assumes that the necessary files will be gathered together, sent to a remote site, and a reasonably technical user there will be responsible for doing the install (not necessarily someone familiar with programming arduinos, but one able to do normal PC maintenance).

Put Together the Files

To update a Teensy in the field, you are going to need the Windows serial installer, the Teensy programmer application, and the binary code for your own program which consists of a .HEX file and a .ELF file.

On the Teensy download website,, you will find the Windows Serial Installer, get a copy of it to install on the PC that will handle the update.

The programmer is called teensy.exe and can be found in <ardinuoDir>\hardware\tools. Here is its location on one of my development systems:

[C:\]dir \arduino-sj\hardware\tools

 Volume in drive C is c140527        Serial number is D467:78F2
 Directory of  C:\arduino-sj\hardware\tools\*

 5/03/2016  14:50         <DIR>    .
 5/03/2016  14:50         <DIR>    ..
 5/03/2016  14:50         <DIR>    arm
 5/03/2016  14:51         <DIR>    avr
 2/06/2016  17:25               0  .keep
 2/06/2016  17:25          45,608  listComPorts.exe
 3/10/2016  22:09          33,448  mktinyfat.exe
 3/10/2016  22:09       2,486,456  teensy.exe
 3/10/2016  22:09          24,744  teensy_gateway.exe
 3/10/2016  22:09          26,280  teensy_post_compile.exe
 3/10/2016  22:09          28,328  teensy_reboot.exe
 3/10/2016  22:09          21,672  teensy_restart.exe

Now you need the binary code for your own program.

  • Start the arduino IDE (which has Teensy support).
  • Do a Verify/Compile (ctl-R) to create the hex file of your code.
  • The hex file is created in the temp directory for your user. For windows 7 (at least for my installation), this is in c:\users\<username>\appdata\local\temp.
  • In the temp directory you should find a directory starting with the word build:

 Volume in drive C is c140527        Serial number is D467:78F2
 Directory of  C:\Users\xxx\AppData\Local\Temp\*

 6/06/2016  15:28         <DIR>    .
 6/06/2016  15:28         <DIR>    ..
 6/06/2016  15:24         <DIR>    build1e37ea4638dee8a2fbba645dea41b283.tmp
 6/06/2016  15:23         <DIR>    hsperfdata
 6/06/2016  15:23         <DIR>    jna-3075831
 5/27/2014  21:40               0  FXSAPIDebugLogFile.txt
              0 bytes in 1 file and 5 dirs    0 bytes allocated
153,325,252,608 bytes free

  • Go into this directory and you will find the hex file (if there is more than one build directory, the one with the most recent date is probably the correct one):
 6/06/2016  15:24         <DIR>    .
 6/06/2016  15:24         <DIR>    ..
 6/06/2016  15:24         <DIR>    core
 6/06/2016  15:23         <DIR>    libraries
 6/06/2016  15:23         <DIR>    preproc
 6/06/2016  15:23         <DIR>    sketch
 6/06/2016  15:23             661  build.options.json
 6/06/2016  15:24              13  test.ino.eep
 6/06/2016  15:24         790,716  test.ino.elf
 6/06/2016  15:24         226,676  test.ino.hex
  • If you cannot find the file search for <project>.ino.hex. I prefer to do this in the cmd box as windows 7 search only finds files I KNOW exist about 1/2 the time:
dir \users\xxx\appdata\Local\*.hex /s
  • Once you have located the .HEX file, the .ELF file will be in the same directory. You will need it as well.
  • Now I have all the files ready to take to the Teensy to be updated:
 6/06/2016  16:09         117,936  serial_install.exe
 6/06/2016  15:54       2,486,456  teensy.exe
 6/06/2016  15:24         790,716  test.ino.elf
 6/06/2016  15:53         226,676  test.ino.hex

Install Serial Driver

Once ready to update, Install the Serial Driver First!

Assuming the PC used to to the upgrade doesn’t already have the Arduino/Teensy software installed, we are going to install just the files necessary to perform the update.

Right click on the serial_install.exe file and run as Admin to let it install the virtual serial driver.

Connect to the Teensy

  • Plug the Teensy into the PC’s USB port.
  • Windows should see the device and start looking for drivers. Skip searching the internet for the update.
  • Once the driver is installed, there is no indication I can find that device manager sees the Teensy (it won’t update the serial port list). But you should still hear the sound effect when you unplug/plug the teensy in.

Update the Code

  • Start the Teensy.exe program
  • Click on Help | Verbose – You will see a screen which will indicate the program is ‘listening for remote control’.
  • In Teensy.exe, do a file | open and open the HEX file. The log indicates the file has been opened.
  • Press the ‘Auto’ button in teensy.exe.
  • Press the reset button on the Teensy.
  • You should see messages in the log indicating the download and reboot were successful:
16:55:40: Board is: Teensy 3.2 (MK20DX256), version 1.03
16:55:40: File "test.ino.hex". 80576 bytes, 31% used
16:55:40: File "test.ino.hex". 80576 bytes, 31% used
16:55:40: elf size appears to be 262144
16:55:40: elf binary data matches hex file
16:55:40: Code size from .elf file = 262144
16:55:40: begin operation
16:55:40: flash, block=0, bs=1024, auto=1
16:55:40: flash, block=1, bs=1024, auto=1
16:55:40: flash, block=2, bs=1024, auto=1
16:55:41: flash, block=76, bs=1024, auto=1
16:55:41: flash, block=77, bs=1024, auto=1
16:55:41: flash, block=78, bs=1024, auto=1
16:55:41: sending reboot
16:55:41: begin wait_until_offline
16:55:41: offline, waited 2
16:55:41: end operation
16:55:41: redraw timer set, image 14 to show for 1200 ms
16:55:41: HID/win32:  vid:05A4 pid:9881 ver:0120
16:55:41: HID/win32:  vid:05A4 pid:9881 ver:0120
16:55:42: redraw, image 9

Maintaining Executable Code

Once I had this process working, it became evident I no longer have to recompile programs every time I want to use them.

This is most helpful on my current project. There are quite a few hardware subsystems involved. After I build a new PCB, I want to make sure all of the hardware is fully functional, so I have a hardware test suite I use.

I can now download and execute the hardware test suite w/o compiling. Once the hardware is tested, I can then download and execute the stable version of the software without having to go back to the source and recompile it.


Nov 2016 Update:

Periodically, I have an issue getting this process to work. When I do a file | open in teensy.exe and specify the HEX file, I will get an error indicating file too large.

It seems teensy.exe defaults to an older model of teensy with less program space. Supposedly if you have both the HEX and ELF files available this isn’t supposed to be an issue, but sometimes it is.

It seems that if I build the HEX file by doing a sketch | upload this problem will not occur. But sometimes I don’t want to upload the version I’m compiling to the teensy that I have connected so I do a sketch | compile. I don’t know why that would make a difference, but so far my observations have been it does.

What to do when this happens? Today I seem to have stumbled across a solution. I have not been able to replicate the failure so I’m not 100% I got the correction sequence right:

  • After doing the file | load, you see the file too large error in Teensy.exe.
  • Double click on teensy_reboot.exe – this will upload the file anyway.
  • Then double click on teensy_restart.exe – this will restart the teensy.


Posted in c-teensy | Tagged | 4 Comments

Using Modulus Arithmetic to Navigate a Circular List

I have to go thru my notes every so often to find the formula for navigating backwards, so I’ll post this stuff here in case anyone else finds it useful.

Modulus math is very handy for dealing with circular functions like time. In fact, I use this to blow the minds of kids (I’m always trying to pique their interest in math and other technical stuff).

I’ll say something like “When is 11 + 2 = 1”? They will insist it cannot be and I tell them they see that very computation on a regular basis. After I have them telling me there is ABSOLUTELY NO WAY 11+2 EQUALS 1, I ask them what they get when they add 2 hours to 11:00. 1 O’CLOCK!!

Anyway, when writing software it is really useful to use modulus math to solve these little problems. To get 1:00 in software, I’d write

x = (11 + 2) % 12

x will contain 1

If you aren’t familiar with the C % operator (a.k.a the mod operator in Pascal), in essence it returns the remainder.  A / B (assuming A and B are ints) returns the quotient. A % B returns the remainder.

int(11 / 2) is 5
11 % 2 is 1

In fact, long ago when I wrote COBOL code, if I needed to do a MOD operation it was actually part of the DIVIDE statement:

DIVIDE  < literal-1 / data-item-1 >   INTO  < literal-2 / data-item-2 >
             GIVING  data-item-3... REMAINDER data-item-4...

Besides doing time calculations, I find modulus math very handy for treating an array as a circular list.

Most recently I implemented a simple LCD menu using the array:

const int listLen = 5;
char * list[listLen] = {"A","B","C","D","E"};

int i = 0;

When the program starts, it prints the first string in the list. It then waits for either an up or down button to be pressed:

// C like psuedo code
while (!done) {
    if (!keyAvail()) {}
    key = getKey();
    if (key == keyUp)
        // compute new i where we go forward in the list
        i = i + 1;
    else if (key == keyDown)
        // compute new i where we go backward in the list
        i = i - 1;

This works OK until we get to the end of the list. We need to wrap around when the user presses the up or down key.

Formula 1: Going forward from the last element to the first
i = (i + 1) % listLen

If i is 4, pointing to the last element in the array, formula 1 will add 1, giving 5. Then 5 % 5 is computed which is 0. We are now pointing back to the beginning of the list.

To go the other way:

Forumla 2: going backwards from the first element to the last
i = (i + (listLen-1)) % listLen

If i is currently 0, we add 4 (listLen-1), and get 4. Then 4 % 5 is 4, so we are correctly point to the last element in the list.

Formula 1 is easy to remember. Formula 2 I can never seem to make stick and have to look it up every time.

Here is the entire program in C like psuedo-code:

while (!done) {
    if (!keyAvail()) {}
    key = getKey();
    if (key == keyUp)
        // compute new i where we go forward in the list
        i = (i + 1) % listLen;
    else if (key == keyDown)
        // compute new i where we go backward in the list
        i = (i + (listLen - 1)) % listLen;

and Pascal-like psuedo-code:

while (not done) do
    if (not keyAvail) {}
    key = getKey;
    if key = keyUp then
        // compute new i where we go forward in the list
        i := (i + 1) mod listLen
    else if key = keyDown then
        // compute new i where we go backward in the list
        i := (i + (listLen - 1)) mod listLen;
Posted in c-arduino, c-lazarus | Tagged | Leave a comment

Writing Code to Handle Arduino’s millis() Roll Over

The Arduino’s millis() function returns the number of milliseconds since the arduino started running. It returns an unsigned long, 32 bit, value.

A 32 bit unsigned word can contain 0 – 4,294,967,285 (2^32-1). When millis() gets to 4,294,967,285 milliseconds and adds 1, it ‘rolls over’ to zero. It will take 49.7 days (4294967286 / 1000 / 60 / 60 / 24) for this to occur.

If you want your Arduino project to run continuously for more than 49 days you will want to take this roll over into account.

Unsigned Subtraction

Getting around the roll over issue is handled by using the subtraction property of unsigned words.

I’m going most of my examples using 8 bit unsigned words (or bytes). These are declared as uint8_t and can have the values 0 – 255 (2^8 – 1).

You cannot have a negative number stored in an unsigned word. If you have an uint8_t and subtract a large enough number such that the result is negative what happens?

uint8_t      x;

x = 0 - 1;

In binary, we start with zero


and subtracting 1 gives


or 255 in decimal. S0 0 – 1 is 255 when using uint8_t.

Here is the general algorithm the CPU is going to use to subtract two unsigned words, x – y:

if (x - y) < 0 then
  z = x - y + 2^ws
  z = x - y;

If (x-y) is positive, nothing special happens. If it is negative, we must add 2^ws where ws is the word size (we are currently using 8 bits).

Using this general rule, if you want to subtract 0 – 1, the result is going to be negative, so calculate z as

z = 0 - 1 + 256
z = 255

That’s exactly what was expected.

w = 255;

To be clear, YOU do not have do the above algorithm. It is done for you when you subtract two unsigned words:

uint8_t        a,c,x;
a = 0;
b = 1;
x = a - b;

and x now contains 255 because were are using uint8_t

Examples of Roll Overs

Let’s watch how subtraction works as roll overs occur. Assume x is increasing and rolls over. Let’s subtract 10 from each value of x and see what happens before and after the roll over (again, this is using an 8 bit unsigned word):

  x       x-10      x-10+2^8     z
254        244           n/a   244
255        245           n/a   245
  0        -10           246   246
  1         -9           247   247

as x approaches roll over (254 & 255)  x-10 returns a positive value and nothing more needs to be done; however, once x rolls over, a negative value is calculated and so we must add 2^8 which gives us the correct answer thru the entire sequence: 244, 245, 246, 247.

Now let’s consider the same thing with a 32 bit unsigned word:

x            x-10         x-10+2^32    z
4294967294   4294967284   n/a          4294967284
4294967295   4294967285   n/a          4294967285
0            -10          4294967286   4294967286
1            -9           4294967287   4294967287

Now imagine x is the current value of millis() and the constant 10 was the initial value of millis().  millis() – oldMillis returns the next proper value when millis() rolls over.

You may be looking at the x-10 result which is also nearing 2^32-1, and thinking that’s about to roll over anyway – this didn’t buy anything. This is only because I selected such a low value of 10 for the subtraction to keep the example simple. In real life this most likely will not be an issue (see The Catch).

Using Unsigned Subtraction to Our Advantage

Now that you’ve seen how unsigned subtraction works during roll over, let’s take advantage of it in a program.

We need to track the initial value of millis() when we start the timer and we need to know how long the timer should last. I typically use the names xxxTimer and xxxTimeout for these variables and define them something like this:

const unsigned long keyTimeout = 1000UL; 

unsigned long keyTimer;

You start the timer by assigning the current value of millis() to it:

keyTimer = millis();

This is the important part: you must subtract the initial timer from the current millis() value and compare that to your timeout. As long as you do that, your program will handle a roll over just fine:

while (test) {
  if (millis() - keyTimer > keyTimeout){ 
    << code to handle the timeout >>
  << rest of the code >>

The Catch

Well, this isn’t really a catch as much as a usage consideration. The word size of  the return value of millis() limits the length of the timeout. You cannot have a timeout larger than 2^32-1 milliseconds (49.7 days) even if roll over does work properly.

In the 32 bit example above, I set the initial value of millis() of 10. When millis() rolls over, it will be just 10 msecs short of exceeding the maximum allowed timeout. So while the roll over works fine, the I’m about to exceed the maximum possible timeout.

Note on UL Constants

You may have noticed that I used UL on my constants to force their typing such as 1000UL. You may wonder why.

For simple assignments, this really buys nothing:

xxxTimeout = 1000UL;

However, I tend to use constant expressions so I can read the code a little easier. For example, if I want a timeout of an hour I will code it as:

xxxTimeout = 1UL * 60UL * 60UL * 1000UL;

(1 hour * 60 minutes * 60 seconds * 1000 msecs)

rather than

xxxTimeout = 3600000UL;

If I need to make a change I’ll see that expression and realize it is for 1 hour and if I need 2, I just change the first constant (since the expression is evaluated at compile time I loose nothing do this).

The problem I’ve had is the C++ compiler periodically will NOT compute the constant expression properly if I don’t typecast each constant. This has bit me enough times that I simply never leave UL off any constant (or really any other non-integer constant for that matter).

I cannot say what the exact circumstances are to cause this issue because in every case, by the time I figured out what was going wrong I was too irritated to research the root of the problem.

Posted in c-arduino | Tagged | Leave a comment

Obtaining a Local Phone Number for Google Voice

I’ve been through this process twice now, so I figured I’d document it if anyone else needs it.

I’ve created several Google Voice accounts in the past 5 years, and there are never any local phone numbers available. My city is medium-sized, but I guess all the numbers GV allocated have been taken.

On my first attempt 5 years ago, the nearest number was in a town 30 miles away. Not long distance, but I really wanted an in-town number. On my most recent attempt, the only numbers available were in the megatropolis 250 miles away.

The problem can be resolved by obtaining and porting a cell phone number. This isn’t free, but it will work.

  • Create a GV account. Let it assign whatever free number you can get for initial testing. If you’ve never used Google Voice, take some time to learn it. You might decide you don’t need a local number.
  • I’m going to assume you have an unlocked GSM cell phone available. Using locked phones or CDMA phones adds more twists to the process and I’ve not done it that way myself.
  • If you don’t have an unlocked GSM phone, you can probably find one dirt cheap on ebay or amazon. You are only going to need to use it for a day.
  • Purchase a pay-as-you SIM card which will be assigned its own phone number. I went to Walmart and picked up an AT&T GO phone SIM card for $10. I strongly suggest using a big name company like AT&T or T-mobile. You may have issues with the porting process for small companies (I tried using Consumer Cellular on my latest attempt but had some problems so I had to fall back to AT&T).
  • Follow the instructions to activate the SIM card.
  • When you register the SIM card, put in your address. Google will want ask for this for porting and I can’t tell you not using it will work.
  • I didn’t get any choice regarding the phone #, but it was tied to the zipcode entered, so it is a local number. In other words, those in my town won’t have to call long distance to reach me.
  • You will need to buy some air time. I used the unlimited usage for $2 / day plan and bought the bare minimum time which was another $10.
  • Make sure the phone is working and you can place/receive calls on the new SIM card.
  • You are going to need your account number and possibly the pin number. With AT&T, you cannot determine the account number yourself. I had to call AT&T customer service (611) and ask for my account #. The nice Indian chap (I’m not being sarcastic), asked me why I wanted it (he knows why I want it), but I gave him a vague “I’d like to have it for my records” kind of response. He didn’t say anything, but I have to wonder if he could see my account had been activated only 10 minutes prior. Never the less, he gave it to me without any additional questioning.
  • Now with the account #, pin #, and valid account info (name/addr), you have enough information to port the number.
  • Return to the Google Voice website and go to Settings | Phone. You will see your original phone number and a Change/Port link next to it.
  • Click on this link and enter the phone number of the cell phone which you want to port (assign) to your Google Voice Account.
  • You will be asked to confirm about 10 questions acknowledging you really want to do this). Once you click on them all, you will be in the porting request screen.
  • The porting request screen should properly identify your carrier and you can enter your account number and identification information. You may or may not need to enter your PIN.
  • Finally, you will be required to pay a $20 porting fee. If something fails during the port, this will be refunded.
  • Once you are done, the porting process starts and will take place in about 24 hours. During that time, the old numbers will continue to work right up until the port occurs.

Total cost to get a local phone number: $40. Not free, but not too much to have a number that is a local call for all my land-line friends.

Obihai users: The Google voice account I did this with had my Obihai VoIP box connected to it which had been configured and was running fine. When the new number was ported to GV, the Obihai continued to work just fine using the new number. I didn’t have to change anything in its configuration.

Posted in c-Misc | Tagged | Leave a comment