Blog

Fakestream simulates streaming data to a file

John Peck
Published , updated

I've been trying to figure out a good way to plot some sensor data as it comes in, and I needed a way to simulate that data. I ultimately wanted to get timestamped data into gnuplot, and I knew gnuplot would take time data formatted as Unix Timestamps. I thought, maybe I can use Unix Timestamps with millisecond precision and avoid all the Day/Month/Year formatting. I found out it wasn't going to be that easy.

Gnuplot can accept floating point seconds, but only with the right formatting

Gnuplot won't accept Unix Timestamps with millisecond precision -- the number has to come in as an integer. But it will accept times formatted as %H:%M:%S with floating point seconds. So then I needed to create these millisecond precision stamps. Tcl will give you the milliseconds since 1970, but its clock format command will neither consume this number directly, nor will it consume this number in floating point seconds. The fix, as pointed out by Donal Fellows, is to bolt the seconds and milliseconds together with a format string.

Fakestream creates these stamps to simulate real-time data

I wrote fakestream to continuously write data stamped with these millisecond-precision stamps to a file. The plot below shows gnuplot periodically scanning this file and updating a plot.

gnuplot plot

The fakestream repository has the Tcl source for this script as well as single file executables for easy distribution. These Starkits and Starpacks are what keep me coming back to Tcl.

Set TCLLIBPATH on Windows with Emacs

John Peck
Published , updated

I do electronic design for a living, and the CAD package I use determines the operating system I spend most of my time in. This means Windows during the day, and Linux at home. Using Emacs on both platforms gives me a consistent look and feel. And Eshell is a very nice command shell for Windows.

I also need Tcl on both platforms, and Emacs gives me a nice way to set the TCLLIBPATH environment variable. This tells Tcl where to look for packages you bring in with package require. The TCLLIBPATH variable is a list of paths, and Tcl needs to be able to make a list variable out of whatever it finds in TCLLIBPATH. A space-separated list works very nicely. I have this in my .emacs:

;; Get extra emacs packages -- including some useful
;; string-manipulating functions like string-join
(require 'subr-x)

;; Add my local package directory to auto_path.  This will be a Tcl
;; list, so the entries should be separated by spaces.
;;
;; Get tklib from https://github.com/tcltk/tklib
(setenv "TCLLIBPATH"
    (string-join '("c:/Tcl/lib/local"
               "c:/Tcl/lib/local/tklib/modules")
             " "))

Why do I need to (require 'subr-x)? The string-join command is supposed to be part of Emacs 25, but my Emacs 25.2.2 still chokes on it at startup without the subr-x package. After evaluating .emacs with M-x eval-buffer:

eshell_output

...you can see that the TCLLIBPATH variable is set, and that Tcl uses it in its auto_path list. I originally installed Tcl using ActiveState's installer, which makes its own changes to auto_path.

I have the very interesting Gub package saved here:

gub_path

and I can now require it with

gub_invoke

...to show that auto_path allowed Tcl to find the local package.

First build of Afterglow by Slingshot Assembly

John Peck
Published , updated

I've been working on a PCB for a small loudspeaker project called Amey. I showed a rendering of the bare PCB a few weeks before I sent the design to Slingshot Assembly in Denver. I got the assembled PCBs today:

afterglow

They installed the snap-in standoffs at each corner on the component side, which helps to protect the other components during shipping. That was a nice touch.

Update -- oops, the ADC doesn't have a clock

I made a showstopper mistake with the rev A boards -- I didn't provide a clock to the I2S ADC. The PCM1802 ADC from TI can be an I2S master, but it has no way of generating its own timebase. The fix is to figure out how to get a clock to the PCM1802. I made a second PCB to hold the DSC60xx 16.9344 MHz oscillator and its bypass capacitor. You can see the second PCB below.

Afterglow mod

I carefully wired up the little PCB, and now I see the correct clocks:

Afterglow clocks

Connecting to the Bus Pirate

John Peck
Published , updated

The Bus Pirate is a cheap way to talk to I2C (and a lot of other serial protocol) devices from your laptop. I use it to bring up new boards -- making sure everything works before they get integrated into a bigger platform. Specifically, I've been using the Bus Pirate version 4 (BPv4) shown below.

bpv4

Dangerous Prototypes has built the Bus Pirate's API into the hardware with its binary bitbang firmware mode. This is great, since it means you don't need a separate piece of software running on your laptop to run the API -- you can use whatever scripting language you want.

Connecting to the BPv4 is just like connecting to any other USB CDC (ACM) device. The version 3 Bus Pirate has an FTDI device to handle the communication, while the BPv4 moves the USB stack into a Microchip PIC. You'll have the usual first-time problems: Windows wants an INF file, and Ubuntu wants your user to be in the same group as the device node. I linked the INF file I used below.

Once those basics are in place, the details of communicating over the channel are determined by your choice of scripting language. I use Tcl for things like this, so I need to use commands like chan configure. The debug log shown below shows the script doing a brute-force search of all connected devices.

bpv4<em>connection</em>trace

I'll go into what this potset script is later. For right now, notice that the script identified two potential device nodes: ttyACM0 and ttyACM1. The script will connect with the first device that reponds to a carriage return with HiZ>. The busbridge repository shows how I did things. The BPv4 actually has an eeprom that could be used to "tag" different Bus Pirates if you wanted to work with more than one at once.

Going forward

The next step is to activate the BPv4's API to set up SPI or I2C communication. I'll talk about that later.

References

Busbridge

BPv4 Windows INF file

Photorealistic Afterglow PCB

John Peck
Published , updated

I name my PCB projects after lakes in Wisconsin, and this one is named Afterglow. I used PCB to create the rendering shown below.

bare pcb

I'm excited to be using SlingShot Assembly to fabricate and assemble these boards.

Illustrate concurrency with timebars

John Peck
Published , updated

I needed to document some concurrent processes, so I put together a script that generates figures like these:

mario example

Download single-file executables here.

Creating the input file

The input file is simply Tcl, and is sourced by the main program. Starting the program with no inputs will create an example.tbi file in an input directory. This is just some basic organization -- the program doesn't care about the input file location or its extension.

The seconds_per_inch variable controls how large timeslices will be relative to their labels. If your timeslice labels don't fit, try reducing this number.

Creating timeslices

The timeslice::timeslice function creates a timeslice. For example:

set mario_airborne [timeslice::timeslice 100e-3 red "Mario has jumped"]

...creates a 100ms-long red timeslice with a label. Recognized colors are black, blue, green, cyan, red, magenta, yellow, and white.

Creating reference lines (timestamps)

The timeslice::reference function creates a reference line. For example:

set mario_lands [timeslice::reference "Mario lands on goomba"]

...creates a reference line with a label. The program will assign a timestamp to the reference line depending on where it lands in its timeline.

Creating timelines

The timeline::timeline function assembles lists of timeslices into a timeline. For example:

set mario_list [list $mario_airborne $mario_lands $mario_recovers]
set mario_timeline [timeline::timeline "Mario" $mario_list]

...creates the mario_timeline timeline. Notice that the mario_lands reference line is in the list of timeslices along with regular timeslices.

Processing the input file

I have a history of creating Tcl software used by manufacturing technicians. These people usually use Windows machines, and they like being able to choose which version they can run. My executables thus have their version numbers in their filenames. Use the -h option to see the usage:

~/projects/eventual/timebars/starpacks $ ./timebars-1.0.2-win32-ix86.exe -h
timebars usage: timebars [options] filename
 -d value             Minimum depth <50>
 -o value             Output file name <timebars.fig>
 --                   Forcibly stop option processing
 -help                Print this message
 -?                   Print this message

If you don't specify an input file (call the script with no arguemnts), the script will generate an input directory and an example file in that directory.

The "minimum depth" parameter is for Xfig. If you already have graphics drawn in Xfig and you want to add this figure, you'll need to make sure the depths cooperate to make overlapping elements visible.

Create arcs of boxes with xfig

John Peck
Published , updated

I needed to add an array of 0603 LEDs to a loudspeaker drawing (shown below). Since I've done some scripting for xfig files before, I thought I'd try that again.

loudspeaker face

You can see the tiny green LEDs distributed over the big middle driver. You can find the script here. You'll need Tcl and Tcl's cmdline package to run it. Once you've got things set up, you can see the usage with

~/p/eventual/scripts/boxarc λ tclsh boxarc.tcl -h
boxarc usage: boxarc [options]
-l value             Box length (mils) <100>
-w value             Box width (mils) <100>
-d value             Minimum depth <50>
-r value             Arc radius (mils) <1000>
-s value             Start angle (degrees) <0>
-e value             End angle (degrees) <90>
-n value             Number of boxes <10>
-o value             Output file name <none>
--                   Forcibly stop option processing
-help                Print this message
-?                   Print this message

...and you can get the LEDs shown in the above image with

tclsh boxarc.tcl -l 63 -w 31 -r 2500 -s 30 -e 150 -n 32 -d 10

...which puts 32 0.063 x 0.031 inch boxes on a 2.5 inch radius between angles 30 and 150 degrees. The depth setting of 10 puts the LEDs "on top" and visible in the image.

Fix xfig's font problems on Windows (Cygwin)

John Peck
Published , updated

Xfig is still a very convenient tool for me, and I need it to work under Cygwin. I've tried to document how I've been able to get it to work. You will, of course, need to start by installing Cygwin.

Download setup-x86.exe

Download the 32-bit (or 64-bit if you're feeling lucky) setup.exe from cygwin.com. I like to copy it to my Windows desktop so I can easily run it again when I need to add packages. The 64-bit version seemed to be missing a few packages the last time I tried it, and I haven't tried it since then.

Run the installer

Select install from internet. The default installation directory (C:\cygwin) works for me. I also like to store package information to C:\cygstore, but this isn't important. After selecting file locations, you can use the mirror sites page to find a local mirror.

Choose these packages for installation:

  1. xorg-server
  2. xinit
  3. xfig
  4. xfig-lib
  5. ghostscript
  6. ghostscript-fonts-other
  7. ghostscript-fonts-std

...and then Cygwin will decide which dependencies will also need to be installed. The initial installation takes me about 15 minutes.

Start the Cygwin Terminal

This creates your home directory and some useful configuration files.

Start the X server

Starting the X server with

export DISPLAY=:0
startxwin &

...will let you keep using the same terminal after the server starts. I've had some strange problems with this sequence of commands -- it works for me on a host OS, but it failed at first on a VirtualBox Windows 7 guest. The fix was to start the XWin Server via the start menu instead of the command line. After I did that, the command line started working. Maybe a config file got written? Anyway, now X is running.

Start xfig to see the problem

I've got xfig 3.2 patchlevel 5c. I add some text to the canvas, then zoom in. The error message is:

Font size 17 not found, using smaller 12 point

...and the glyphs don't scale with the rest of the canvas -- extremely annoying.

Install some font tools

I needed to install the:

  1. xset
  2. mkfontdir
  3. mkfontscale

...packages via the cygwin installer.

Download ghostscript fonts

I'm not sure where the fonts should be archived, but the file you want is ghostscript-fonts-std-8.11.tar.gz. It looks like it's hosted at SourceForge. I make the directory ~/fonts and unpack the file there. This will make its own fonts directory. Descend into this directory and:

mkfontdir
mkfontscale

Add this new fonts directory to the list known by X

With the X server running,

xset fp+ ~/fonts/fonts

...and you won't see any output.

Test the fix

Fire up xfig again and type some text. Enjoy the nice scaling glyphs when you change the zoom factor!

You'll probably want to add the export DISPLAY=:0 line to your .bash_profile or your .bashrc file. Unfortunately, the xset command won't work until X is actually running. You could add that line to your .bashrc, but you'd have to make sure you started X via the start menu before you started the Cygwin Terminal. You could also simply type bash after starting X to re-run the .bashrc commands. And there are probably many better ways of doing all this.

Create pipe tables from PCB's drill files

John Peck
Published , updated

I use PCB to design PCBs, and I recently needed to embed a list of drills and their uses in a plain text file. PCB's drill file looks like this:

M48
INCH
T72C0.010
T71C0.015
T70C0.067
T69C0.039
T68C0.030
T67C0.046
T66C0.138
%
T72
X010249Y009035
X010249Y005886
X010268Y008256
X010268Y007075
X010268Y005107

...and I wrote drilltable.tcl to generate tables like this:

|------------+----------------------+------------|
| Tool       | Hole size (inch)     | Count      | 
|------------+----------------------+------------|
| T72        | 0.010                | 218        | 
| T71        | 0.015                | 95         | 
| T68        | 0.030                | 3          | 
| T69        | 0.039                | 10         | 
| T67        | 0.046                | 15         | 
| T70        | 0.067                | 1          | 
| T66        | 0.138                | 4          | 
|------------+----------------------+------------|

This borrows from an excellent usage example of Tcl's format command at the Tclers Wiki.

Use teacup to install Tcl's math packages on Ubuntu

John Peck
Published , updated

Download ActiveTcl from ActiveState

ActiveTcl provides teacup, which is a client for the TEApot package server. The Tclers wiki provides much more information about all this.

I unpack the downloaded file in some temporary directory. There's an install.sh file in the root of the unpacked archive.

$ sudo ./install.sh

...will start the graphical installer. I just accept the default /opt/ActiveTcl-8.6 installation directory and accept all the terms.

View the available packages list

With the default installation directory, I need to be root to use teacup. I also need to add it to my path.

$ sudo su
# PATH=/opt/ActiveTcl-8.6/bin:$PATH
# teacup list

See the edit below for more about problems with permissions.

Install your package

I want to install math::statistics, so

# teacup install math::statistics

<snip>

Retrieving package math::statistics 1.0 tcl ...@ http://teapot.activestate.com ... Ok

Installing into /opt/ActiveTcl-8.6/lib/teapot

Installing package math::statistics 1.0 tcl

Check your work

Start tclsh to make sure you can require math::statistics as an ordinary user.

# exit
$ PATH=/opt/ActiveTcl-8.6/bin:$PATH
$ tclsh
% package require math::statistics
1.0

...and that's success! Of course, you can make your life easier by adding the PATH command to your .bashrc or .bash_profile script.

Edit on Saturday, September 24, 2016

I could not install ActiveTcl in a way that allowed an ordinary user to use teacup. I tried installing everything into /home/john/opt instead of /opt, but teacup then created a ~/.teapot directory owned by root. So I guess users of "locked down" systems will need to find another way to get the packages they need.