Fort Wayne Hamfest 2010

November 13-14 (Saturday 9AM-4PM, Sunday 9AM-3PM)

I just barely missed the 2009 Hamfest…happened to check the calendar for it the following Monday. Going to try to get to this one.

Google, simplified

Google’s main page has accumulated an unfortunate amount of useless bloat (such as that silly little script that hides the menus until you move the mouse) with the result that I can no longer just open a window and start typing a search…the current page takes long enough to load that I regularly lose the first few characters of what I’m trying to search for. If I wanted fancy transitions and background pictures, I’d be using the iGoogle interface.

However, there’s a quick workaround…there’s a version of Google’s search page that’s stripped-down for mobile devices at It’s not optimal, being designed for devices with tiny screens, but it loads instantly, letting you get on to the important business of searching, getting results from Google Calculator, etc. The non-mobile version and iGoogle page are accessible from the mobile site via links at the bottom of the page. iGoogle may actually prove useful to me now, since I won’t be forced to load it every time I want to search for something.

Site migration

I’m essentially done migrating the site over to the new Linode VM. Posts and pages were copied over, but I did not attempt to copy what few non-spam user accounts and comments there were. I’m glad I’m not a more prolific blogger, saved me some work…

My old gallery is up here. I’ve also got a few photos up on Picasa here. I think I’ll be dropping Picasa soon though…it is rather extraordinarily limited in some ways. (Why they felt it made sense to allow download of full-size images, but not allow you to view them, I will never understand.) I’ll be looking at WordPress gallery options, Gallery3, and the possibility of rolling my own gallery when I have time to spend on it.

ARM GCC toolchain build

I recently needed an ARM toolchain for a Luminary Cortex M3 microcontroller, and found that much of the information out there was aggravatingly vague and fragmentary, or simply out of date. So, to save others some trouble, here’s the process I used to put together an ARM toolchain using GCC 4.5.0, applicable to both Mac OS X and Linux.

First, some notes about my setup…I like to put my entire toolchain in a subdirectory of my home directory…for example, ~/arm-eabi-none/, with an entry like this in a startup file like .zshrc:

    export PATH=~/arm-none-eabi/bin:$PATH

This allows quick and easy swapping of toolchains by just renaming directories. If you’re building a new toolchain, you can just rename the other to keep it around while you test the new one. So, to start with, add a line like the above to ~/.zshrc, ~/.bashrc, or whatever is appropriate for the shell you use. Mac OS X and most Linux distros use bash by default, I prefer zsh. The following will append that line to .zshrc, creating the file if it doesn’t already exist (modify as needed for the shell you use):

    echo "export PATH=~/arm-none-eabi/bin:\$PATH" >>.zshrc

Now, either run “export PATH=~/arm-none-eabi/bin:$PATH” command or start a fresh terminal so your path is set up before continuing, and create some directories in your home directory:

    cd ~
    mkdir arm-eabi-none arm_build
    cd arm_build

To build a GCC toolchain, you need GMP, MPFR, and MPC. These may be already installed on your system, if not, you’ll need to install them. If you use a package management system, that may simplify things. You may also want to install them on your system, or build them specifically for your GCC toolchain. I chose the last approach, statically linking them into the toolchain to avoid disturbing any existing installs and to reduce dependencies on the system.

While we’re at it, lets get some other stuff we’ll need. You’ll also need binutils, gcc-core and optionally g++, newlib, gdb, and openocd.
GMP can be obtained from, MPFR from, and MPC from The versions I used are gmp-5.0.1, mpfr-2.4.2, and mpc-0.8.1. Download and decompress these:

    tar -xjf gmp-5.0.1.tar.bz2
    tar -xjf mpfr-2.4.2.tar.bz2
    tar -xzf mpc-0.8.1.tar.gz

And the GCC toolchain…pick an appropriate mirror from and do the same for binutils, gcc-core, g++ if you’re using C++, and gdb. I used gcc-core-4.5.0, gcc-g++-4.5.0, binutils-2.20, and gdb-7.1:

    tar -xjf binutils-2.20.tar.bz2
    tar -xjf gcc-core-4.5.0.tar.bz2
    tar -xjf gcc-g++-4.5.0.tar.bz2
    tar -xjf gdb-7.1.tar.bz2

(if you’re wondering where g++ went, it untarred into the gcc-4.5.0 directory)
And newlib, from I used newlib-1.18.0:

    tar -xzf newlib-1.18.0.tar.gz

Now, to build GMP, MPFR, and MPC. Again, I’m building temporary copies and linking them statically, you can skip this step if you want to use existing installed versions, or you can install them system-wide instead.

    mkdir gmp-5.0.1/build; cd gmp-5.0.1/build
    ../configure --prefix=$HOME/arm_build/gmp --disable-shared --enable-static
    make; make install
    cd ../../
    mkdir mpfr-2.4.2/build; cd mpfr-2.4.2/build
    ../configure --prefix=$HOME/arm_build/mpfr --with-gmp=$HOME/arm_build/gmp --disable-shared --enable-static
    make; make install
    cd ../../
    mkdir mpc-0.8.1/build; cd mpc-0.8.1/build
    ../configure --prefix=$HOME/arm_build/mpc --with-gmp=$HOME/arm_build/gmp --with-mpfr=$HOME/arm_build/mpfr --disable-shared --enable-static
    make; make install
    cd ../../

There’s some “make check” targets you should run as well to make sure things are working, though I omitted them from the above.

Finally, to the GCC toolchain. First, you need to build binutils, but the version downloaded above is slightly broken. Open binutils-2.20/gas/as.h and change line 241,

    #define know(p)			/* know() checks are no-op.ed  */


    #define know(p)	do {} while(0)		/* know() checks are no-op.ed  */

When compiling this on my 64-bit Mac Pro, I also had to make some changes to binutils-2.20/binutils/strings.c to disable use of some deprecated data types and functions. This was not necessary on the 32 bit OS X and Linux systems I’ve built this on, and I don’t know if it’s needed on 64 bit Linux systems. There’s probably a cleaner way to do it, but I just commented out the relevant branches of the #ifdefs from lines 83 to 96:

    //#ifdef HAVE_FOPEN64
    //typedef off64_t file_off;
    //#define file_open(s,m) fopen64(s, m)
    typedef off_t file_off;
    #define file_open(s,m) fopen(s, m)
    //#ifdef HAVE_STAT64
    //typedef struct stat64 statbuf;
    //#define file_stat(f,s) stat64(f, s)
    typedef struct stat statbuf;
    #define file_stat(f,s) stat(f, s)

Now, go on and build binutils:

    mkdir binutils-2.20/build; cd binutils-2.20/build
    ../configure --prefix=$HOME/arm-none-eabi --target=arm-none-eabi --enable-interwork --enable-multilib --disable-nls --disable-shared --disable-threads --with-gcc --with-gnu-as --with-gnu-ld
    make; make install
    cd ../../

Building newlib for ARM requires an ARM GCC compiler, but building a full ARM GCC compiler requires newlib. You need to build an intermediate version of GCC using the –without-headers option to let it know it can’t rely on libc headers existing. Also, c++ support is unnecessary for this. Note the different make targets, “make all-gcc” and “make install-gcc”!

    mkdir gcc-4.5.0/build; cd gcc-4.5.0/build
    ../configure --prefix=$HOME/arm-none-eabi --target=arm-none-eabi --enable-interwork --enable-multilib --enable-languages=c --with-newlib --disable-nls --disable-shared --disable-threads --with-gnu-as --with-gnu-ld --with-gmp=$HOME/arm_build/gmp --with-mpfr=$HOME/arm_build/mpfr --with-mpc=$HOME/arm_build/mpc --without-headers
    make all-gcc; make install-gcc
    cd ../../

Next, build newlib:

    mkdir newlib-1.18.0/build; cd newlib-1.18.0/build
    ../configure --prefix=$HOME/arm-none-eabi --target=arm-none-eabi --enable-interwork --enable-multilib --with-gnu-as --with-gnu-ld --disable-nls
    make; make install
    cd ../../

Now that newlib’s built, you can build the full GCC:

    cd gcc-4.5.0
    rm -rf build
    mkdir build; cd build
    ../configure --prefix=$HOME/arm-none-eabi --target=arm-none-eabi --enable-interwork --enable-multilib --enable-languages=c,c++ --with-newlib --disable-nls --disable-shared --disable-threads --with-gnu-as --with-gnu-ld --with-gmp=$HOME/arm_build/gmp --with-mpfr=$HOME/arm_build/mpfr --with-mpc=$HOME/arm_build/mpc
    make; make install
    cd ../../

Now, that’s enough to allow you to compile programs, but you will need a debugger as well. Compile GDB:

    mkdir gdb-7.1/build; cd gdb-7.1/build
    ../configure --prefix=$HOME/arm-none-eabi --target=arm-none-eabi --disable-nls --with-gmp=$HOME/arm_build/gmp --with-mpfr=$HOME/arm_build/mpfr --with-mpc=$HOME/arm_build/mpc --with-libexpat
    make; make install
    cd ../../

Note that libexpat must be specified to get full support for things like memory maps sent to GDB from OpenOCD. Make sure it took…GDB will happily continue the configure and build process without XML support without telling you if it is unable to find or use the library, only giving you a “warning: Can not parse XML memory map; XML support was disabled at compile time” message at run time. You should get the following somewhere in your build output when you do make:

    checking for libexpat... yes
    checking how to link with libexpat... -lexpat
    checking for XML_StopParser... yes

I keep OpenOCD separate from my GCC toolchain, again installing it to ~/openocd so I can easily swap versions. You can get the latest release from, or check it out of the Git repository with:

    git clone git://

The release has the advantage of reliability, but I used the latest version in the repository.

Now you’ll want to configure OpenOCD to use the JTAG device you’re using. If you’re using Mac OS X and one of the common FTDI based JTAG interfaces, you’ll want to install libftdi ( first, and use –enable-ft2232_libftdi. I have not had luck getting the FTD2XX direct drivers to work, OpenOCD will run for a bit and then crash. Run “configure –help” to get a list of other supported JTAG devices. I also had to install libusb, which can be obtained from

    cd openocd
    mkdir build; cd build
    ../configure --enable-maintainer-mode --prefix=$HOME/openocd --enable-ft2232_libftdi
    make; make install

You will also need to add OpenOCD to your path:

    echo "export PATH=~/openocd/bin:\$PATH" >>~/.zshrc

Controllerless Graphical LCDs, part 2

It is useful! As expected, RAM and CPU consumption are major issues. Saving RAM by computing the data to send to the LCD line by line proved to only be possible for text and extremely simple graphics, even with overclocking. The timing requirements are far looser than those involved in generating video signals, but the refresh rate needed to avoid flicker is actually quite high, the LCDs are intended to be driven at 60 Hz. This leaves 260 microseconds to compute each line. Another annoyance is the LCD drive voltage, which is a negative supply rated to be as much as -20 volts…I’m now using the charge pump from a MAX232 level converter for the LCD supply.

I switched to frame buffers in RAM and upgraded to an ATmega32 I had lying around. It’s still not light on the CPU: even with text and frame buffer graphics, it consumes roughly 30% of the CPU time of a ATmega32 running at 16 MHz, varying depending on refresh rate and the specifics of what is being drawn, and on display size…graphics is somewhat faster than text, and displays much larger than mine probably can’t be used without blanking the display while other operations are being performed. Worse, gray pixels are indicated by setting pixels in one of two buffers, full black by setting pixels in both buffers, and displaying each buffer for two frames before switching to the other, to avoid odd effects due to the LCD responding faster in one direction. This requires two frame buffers, doubling SRAM consumption, and also requires a higher refresh rate to avoid flicker, which means even fewer cycles free for other things. I ended up using nested interrupts to allow timely LCD updates while without bringing everything else to a halt, an approach which seems to work well.

There’s not enough RAM on the ATmega32 for a full-screen frame buffer, but mixing text and graphics is fairly trivial. You could of course store larger static bitmaps in flash, this isn’t something that interested me. It is quite straightforward to split the display into quarters based on the column controllers, though, and I’ve mostly been using it as a 7×24 character text display (with 8×8 pixel characters and 1 pixel line spacing), and a 64×64 graphics area with gray support. This takes a 168 byte character buffer and two 512 byte frame buffers, 1192 bytes in total. The ATmega32 has 2048 bytes of SRAM, leaving 856 bytes of SRAM free for other uses. I could just barely do a 7×20 + 64×96 mode (1676 B), or I could drop the grays and devote up to 3/4 of the display to graphics. Since there are 2048*8 pixels on the display, you can also simply draw all RAM onto the display, with some interesting results:

The gray pixels are a bonus, the display was never intended to support them. On my display, they flicker badly at less than 80 Hz, but this likely depends a great deal on display and driving voltage. Flicker in gray shades can be reduced by setting alternating pixels in each buffer. Eliminating gray pixel support halves frame buffer RAM usage, or doubles screen area that can be used for graphics, and considerably reduces the redraw rate required to avoid flicker, reducing CPU consumption. It should also be possible to do gray values in the text area, at the cost of higher flash usage…a full 256-character set of 8×8 pixel font bitmaps takes up 2 KB, gray values would double that. Large SRAM sizes typically come along with large flash sizes though, and I am planning to investigate the possibilities of crude antialiasing for improving legibility of text.

As mentioned, the display seems to respond differently in when driven in different directions. This could be exploited to gain two different gray levels by only displaying each buffer once, but I did not find the resulting gray levels to be of much use in my display…I got “medium gray” and “almost invisible”. The possibility merits further exploration, though…different LCDs might behave differently, and other drive voltages or tweaks to the refresh timing might help.

Source code:

Driving controller-less graphical LCD

Digging around through some old parts recently, I came across an old Epson graphical LCD display that had on-board drivers, but no controller. The LCD is an Epson EG2401, reflective, no backlight, 256×64 pixels. It has drivers…one SED1190 driving the rows and four SED1180s driving the columns…but no on-board controller. The LCD is *supposed* to be hooked up to a SED1330 controller and SRAM, but since I didn’t have such a thing, this LCD sat around in a junk box for years.

I still don’t have a SED1330 controller to hook up to the LCD, but I found more information this time around, including datasheets on the drivers. These things are essentially just serial load/parallel output shift registers, with output electronics for driving the LCD. Row select is performed by shifting a 1 in and clocking it along to each row in turn, the SED1190 can handle up to 64 rows. 4 adjacent columns are written at a time: each SED1180 has 4 16-bit shift registers with their outputs interleaved. Simple in theory, but the process of clocking data in is more complicated than you’d expect to be necessary, and rather poorly documented. There doesn’t seem to be anyone else foolish enough to try to hook these LCDs up without a controller, but after some trial and error I did finally succeed:

Caveats: you’ll need a fairly fast microcontroller. The display needs to be continually refreshed, or the image will fade to nothing, and if the frame clock is not kept changing while power is applied to the LCD, the LCD screen itself may be damaged. This will consume a notable amount of processor cycles, and if the display isn’t updated fast enough, there’s visible flicker. If the line refresh rate is not constant across the display, there will be visible glitches and artifacts, essentially varying contrast from differences in the periods the LCD is driven. If the display refresh rate is too slow, the display lifetime may also be reduced. You’ll also need lots of SRAM, bitmaps read from program memory, or graphics simple enough to rasterize on the fly (sprites/bitmap characters should be possible). Representing a 256x64x1 bit bitmap takes 2048 bytes, and the ATmega16 I used only has 1024 bytes of SRAM, so I wasn’t able to simply display from a frame buffer. It’s really a job far better suited to a FPGA, or at least a faster microcontroller with more memory (like a ATmega644 or an ARM).

On the other hand, you have relatively direct control over the LCD, and can do things unsupported by the controllers. By rapidly switching pixel states, the EG2401 can be made to display gray levels surprisingly well, though large areas of gray tend to flicker visibly, and the plot display with one half-gray trace flickered badly at 16 MHz. Overclocking the AVR helped a great deal, and with it running at 26 MHz(!), the dual sine wave plot was nice and smooth. Many of the ATmega16’s peripherals are probably non-functional at this speed, but all I need to drive the LCD was GPIO.

Source code will come in a later post, I hope to optimize it further and develop it into something of actual use.

Xorshift pseudorandom number generator

In 2003, George Marsaglia published a pseudorandom number generator based on repeated shift and XOR operations, a relative of the linear feedback shift register generators. The basic 3-shift PRNG is:

int xorshift() {
    y ^= (y << a);
    y ^= (y >> b);
    return y ^= (y << c);

With y seeded with any non-zero starting value. The generator will never produce zero, which is something to be careful of, but with the right values for a, b, and c, will cycle through all non-zero values. If only a subset of the bits are used, a generator with the full period results where zeros do occur, though not as frequently as the other values in the cycle: if you take 6 bits from an 8 bit generator, you will get each non-zero 6-bit number 4 times per cycle, and only 3 zeros. Alternatively, you can simply subtract 1 from the output, and take the usual approaches to obtaining the desired range without unacceptable bias.

The published generators I've found all use 32 bit values or greater, but sometimes something simpler and smaller is needed. Here is the C code for the generators I have been testing. Note that they have been verified to be full cycle and to give reasonably random-looking results, but little more...I assume that nobody needing high quality random numbers will use such a short-period PRNG, but will use the published 32, 64, or 128 bit versions, or another generator altogether.

static uint8_t y8 = 1;
static uint16_t y16 = 1;

// returns values from 1 to 255 inclusive, period is 255
uint8_t xorshift8(void) {
    y8 ^= (y8 << 7);
    y8 ^= (y8 >> 5);
    return y8 ^= (y8 << 3);

// returns values from 1 to 65535 inclusive, period is 65535
uint16_t xorshift16(void) {
    y16 ^= (y16 << 13);
    y16 ^= (y16 >> 9);
    return y16 ^= (y16 << 7);

Its simplicity and avoidance of operations such as multiplication and division makes it particularly well suited for hardware generation. Unfortunately, it's an imperfect fit to larger AVRs: while it requires little memory, even the simple-appearing one-byte shifts for xorshift8 require several instructions to perform on an AVR, so on devices with the multiply instruction, it is a fair bit slower to compute than a linear congruential generator. However, for those devices that lack the hardware multiplier, there may be notable size and speed benefits. Larger devices with barrel shifters might also benefit (ARMs in particular, due to their ability to "fold" shifts into data-processing instructions), but devices with such instructions are also likely to be better at handling other PRNGs. There is a considerable complexity benefit for hardware or FPGA implementations, and it may still be of use in AVRs and other small microcontrollers as a simple PRNG that avoids some of the problems that LCGs have, such as poor randomness in the low bits, while not being as memory-hungry or as computation-intensive as algorithms like the Mersenne Twister.

These aren't the only choices for a, b, and c that work. For 8 and 16 bit generators, it's simple enough to perform a brute force search for possible combinations. There are 24 full-cycle 8-bit generators:

(1, 1, 2) (1, 1, 3) (1, 7, 3) (1, 7, 6) (1, 7, 7) (2, 1, 1)
(2, 5, 5) (3, 1, 1) (3, 1, 5) (3, 5, 4) (3, 5, 5) (3, 5, 7)
(3, 7, 1) (4, 5, 3) (5, 1, 3) (5, 3, 6) (5, 3, 7) (5, 5, 2)
(5, 5, 3) (6, 3, 5) (6, 7, 1) (7, 3, 5) (7, 5, 3) (7, 7, 1)

And 60 16-bit generators:

(1, 1, 14) (1, 1, 15) (1, 5, 2 ) (1, 7, 4 ) (1, 7, 11) (1, 11, 3 )
(1, 15, 6 ) (1, 15, 7 ) (2, 5, 1 ) (2, 5, 13) (2, 5, 15) (2, 7, 13)
(2, 7, 15) (3, 1, 12) (3, 1, 15) (3, 5, 11) (3, 11, 1 ) (3, 11, 11)
(3, 13, 9 ) (4, 3, 7 ) (4, 7, 1 ) (4, 11, 11) (5, 7, 14) (5, 9, 8 )
(5, 11, 6 ) (5, 11, 11) (6, 7, 13) (6, 11, 5 ) (6, 15, 1 ) (7, 1, 11)
(7, 3, 4 ) (7, 9, 8 ) (7, 9, 13) (7, 15, 1 ) (8, 9, 5 ) (8, 9, 7 )
(9, 7, 13) (9, 13, 3 ) (11, 1, 7 ) (11, 3, 13) (11, 5, 3 ) (11, 7, 1 )
(11, 11, 3 ) (11, 11, 4 ) (11, 11, 5 ) (12, 1, 3 ) (12, 3, 13) (13, 3, 11)
(13, 3, 12) (13, 5, 2 ) (13, 7, 2 ) (13, 7, 6 ) (13, 7, 9 ) (13, 9, 7 )
(14, 1, 1 ) (14, 7, 5 ) (15, 1, 1 ) (15, 1, 3 ) (15, 5, 2 ) (15, 7, 2 )

Character LCDs over SPI

Character LCDs with HD44780/KS0066U-compatible controllers are a widespread standard in electronics equipment, and are readily available and accessible to the hobbyist. However, microcontroller I/O pins are a scarce resource, and these LCDs use a parallel interface that requires 11 pins for a full implementation of the 8-bit interface. These controllers do have a 4-bit mode that reduces the requirement by 4 pins, and one pin can be saved by hard wiring the display in write mode, but 6 I/O pins must still be dedicated to the display, or at least shared with things that tolerate having the display connected. The big 4×40 displays are worse…these controllers are rather archaic, and each can only handle 2×40 lines. These “4×40” displays thus actually have two controllers, sharing data and control lines but with separate enable lines, and so require 7 IO pins at minimum.

One common solution: the 74595 shift register. This device consists of an 8 bit long shift register with separate output latches…you shift data in, and then latch it into the output registers to update all outputs simultaneously. This is essentially the same hardware used for SPI, and conveniently, the ‘595 can be wired to take input directly from a SPI bus, serving as a primitive port expander. For some reason many people bit-bang the shift register, manually toggling GPIO pins to clock data into it, but the ‘595 is perfectly capable of being driven faster and more efficiently by an AVR’s SPI hardware. 8 outputs is enough to talk to a dual-controller 4×40 LCD with one pin free for a smaller LCD or backlight control, or up to 3 separate LCDs, while only using the SPI bus and one slave select. An example for a single-controller LCD:

The shift register data is transferred to the output latches on the positive going edge of the store clock input. That input thus behaves much like a slave select, the only difference being the behavior when less than 8 bits are clocked in before the rising “deselect” edge…the chip has no “selected” state and will output whatever the last 8 bits on the bus were on the “deselect” rising edge, so make sure not to select it if you don’t intend to write to it. The output enable and shift register clear inputs are active low: the first is tied to ground so that the outputs are always enabled, and the shift register clear input is tied to VCC .

This does come at some cost. An additional part is required, obviously: the shift register itself. The 4-bit protocol is a little more complicated to initialize and use, and takes two SPI transfers for every command to the LCD. Perhaps the biggest drawback is that the shift register is incapable of reading from the LCD. Data can not be stored in the LCD DDRAM, and it is not possible to poll the LCD state, so control is purely open-loop: you must wait for the LCD to process each operation before proceeding to the next. The cost of the ‘595 is a small fraction of that of the LCD though, and readback from the display is generally not needed. And as a side benefit to all this, if the VHC logic family is used, the shift register will handle 3.3V or 5V inputs regardless of the LCD/shift register power supply…no additional translation of logic levels is necessary. With the increasing use of 3.3V parts and the high availability of old but cheap 5V LCD modules, this can be particularly useful.

When prototyping, it also takes up breadboard space, which is nearly as precious a resource as GPIO pins. I made an adaptor board for my 4×40 character module that allows it to be connected via a 5-pin connector (never mind the “screensaver”):

Some people do clever things with RC networks to automatically latch the data in the shift register after a transfer is done, which can save the slave select pin, but I’ve gone for SPI compatibility instead. With the separate slave select, the LCD can share the bus with other SPI devices.

Source code for AVR microcontrollers with SPI ports, using AVR-GCC:

More information:

Rice pudding

* 1 cup of arborio rice
* 4 cups milk, 2 cups of milk to start with and 2 for later
* 2 eggs
* 1 teaspoon salt
* 1/3-1/2 cup sugar
* seasonings…I used 2 tsp vanilla and about half a teaspoon each of cinnamon and cardamom in this batch.

1. Mix 2 c milk, rice, salt, sugar, and seasonings in crock pot.
2. Cook on high, stirring occasionally until the liquid is absorbed, a couple hours.
2. Beat 2 eggs and 2 c of milk together, mix in half of the thick rice-stuff to temper the milk and eggs (cooling the rice and warming the milk+eggs, letting you mix the two without cooking the eggs), and then mix the rice and eggs back into the crockpot.
3. Cook for half hour or so, stirring occasionally, until it starts to thicken again. It will thicken much more as it cools.
4. Let cool and enjoy

New logo, IFS images

Dug out my old iterated function system generator to make a new logo for the site. Some of the other results are in this gallery:

These are simply images of a large number of particle trajectories in a “lumpy” force landscape. In a simple example:

The particles are repelled from their origin point by an inverse square force (with a softening factor to reduce the spike at the origin: graph) and flow through a landscape derived from a smooth noise function:

The result is analogous to electrons flowing from a point source through a slightly uneven environment. Though only individual particles trajectories are traced, and the “electrons” thus can not interact with each other, they form into distinct streams.