Automatically place footprints to match schematic in Kicad

03/09/2015

When you first start Kicad’s PCB editor pcbnew and read a netlist, all of the components are piled up in one place. I wrote a script that takes the schematic and pcb files and moves the footprints to match their placement in the schematic. This is a nicer starting point to route your PCB.

schematic pcb

You do need to open pcbnew and read the netlist in order to generate the initial .kicad-pcb file.

Pulse testing JFETs

27/08/2015

JFETs show up all over Wes Hayward’s books1 2, mostly on oscillators. For those only familiar with bipolars and MOSFETs, an N-channel JFET is like an N-channel MOSFET except:

  • The threshold voltage is negative: Vt = -Vp
  • The gate-source junction is a diode that must never be forward biased.

I bought a bunch of J310 N-channel JFETs. However, the specs on these parts are all over the place:

specs
So I decided to measure Idss and Vp. Turns out that the J310 will destroy itself if saturated at Idss, so the test has to be fast. I hooked up an HP8112 pulse generator to the gate and biased the drain with a small resistor to ensure saturation:
JFET pulse testing circuit
I extracted the parameters from the oscilloscope capture with a short IPython notebook:

import scipy as sp
import scipy.optimize
%matplotlib inline
from matplotlib import pyplot as plt

Vg = sp.loadtxt('jfets/DS0000.CSV', skiprows=14, delimiter=',', usecols=(0,)) / (2**8) * 10 * 2.
for ii in range(1, 4):
    Vd = sp.loadtxt('jfets/DS{:04d}.CSV'.format(ii), skiprows=14, delimiter=',', usecols=(0,)) / (2**8) * 10 * .5
    #Vd = Vd[Vg > -6]
    #Vg = Vg[Vg > -6]
    Vcc = 12
    Rd = 22
    Id = (Vcc - Vd) / Rd
    Id -= sp.mean(Id[Vg < -7])
    plt.figure(figsize=(3,3))
    plt.plot(Vg, Id*1e3, '.', color=(.5,.5,.5), label='Measured')
    def Idsat(Vg, Idss, Vp):
        return Idss * (1. - sp.maximum(Vg, Vp) / Vp)**2
    def ferror(x, Vg, Id):
        Vp, Idss = x
        return Id - Idsat(Vg, Idss, Vp)
    (Vp, Idss), _ = sp.optimize.leastsq(ferror, [-4, 55e-3], (Vg[Vg > -6], Id[Vg > -6]))
    plt.title('I$_{{dss}}$={:.0f}mA, V$_p$={:.1f}V'.format(Idss*1e3, Vp))
    Vg2 = sp.linspace(min(Vg), max(Vg), 200)
    plt.plot(Vg2, 1e3*Idsat(Vg2, Idss, Vp), 'r-', linewidth=2)
    plt.xlabel('V$_{gs}$ (V)')
    plt.ylabel('I$_d$ (mA)')
    plt.xticks(range(-8,1,4))
    plt.yticks(range(0,50,20))
    plt.tight_layout()
    plt.savefig('jfets/device{:02d}.png'.format(ii), dpi=300)

The three devices I tested are clustered pretty close on both parameters:
device01

device02

device03
[1]W. H. Hayward, R. Campbell, and B. Larkin, Experimental Methods in RF Design, Revised 1st Edition edition. Newington, CT: Amer Radio Relay League, 2009.
[2]W. H. Hayward and D. Demaw, Solid state design for the radio amateur. American Radio Relay League, 1986.

Run applications from RAM in Stellaris Launchpad

02/01/2015

I made a program to load applications to RAM and run them in the Stellaris Launchpad. On reset, it reads an SREC file from the serial port and copies it to RAM. It points the vector table to the load location (so interrupts work normally) and jumps to the application’s main() function.

The first problem was reserving RAM for the loaded application. To do this, I modified my linker script by splitting the RAM into two sections, and keeping the loader in the first section.

Afterwards, the application has to be linked so that it will run from RAM. This means using another linker script that puts it on the second section of RAM. It also places the vector table at the beginning so that the loader knows where it is.

The loader itself is a minimal SREC parser which implements the records that showed up in my SREC files.

To play around with the loader, it’s possible to make SREC files from the SDK example projects. This requires changing the entry point and linker script in the Makefile. For example, to compile project0 we change
SCATTERgcc_project0=project0.ld
ENTRY_project0=ResetISR

to
SCATTERgcc_project0=../linkprogram.ld
ENTRY_project0=main

. Then we have to change the startup script in startup_gcc.c . Normally the reset routine would copy data from Flash to RAM to initialize variables, but this isn’t necessary when running from RAM. So comment out ResetISR and change the reset vector to (void (*)(void) main.

After these changes, the AXF file generated by make will be good for running from RAM. To get the SREC file, use objdump and sed to strip the header:

arm-none-eabi-objcopy -S -O srec --srec-len=8 project0/gcc/project0.axf project0/gcc/project0.srec
# Strip header
sed -i /^S0/d project0/gcc/project0.srec

I’ve automated this last step with a rule in the Makefile. This works successfully with usb_dev_mouse, project0, qs-rgb and probably all the other example projects.

Minecraft stronghold finder

18/02/2014

I wrote a simple app to triangulate Strongholds in Minecraft. Instead of wasting a bunch of Eyes of Ender trying to get to a Stronghold, you can just do a couple of throws and get a good estimate of its position.

You can check out the app or look at the source code

Python bindings for Ngspice

17/02/2014

I wrote a set of Python bindings for the Ngspice simulation engine. It’s meant to add the clarity and power of Python to electronics simulations. For instance, you can simulate a circuit while varying different parameters and produce highly customized plots of your results, while minimizing your exposure to SPICE syntax.

More details on the project page.

Build your own Wigner-Seitz cells

18/08/2013

I made templates you can print out to build the Wigner-Seitz cells for hexagonal, body-centered cubic and face-centered cubic crystals. Check out the ideal result:

hexagonal_thumb bcc_thumb fcc_thumb

And the actual result:

Hexagonal photoBCC photoFCC photo

You can print these out to build your own:

I used blender to model the cells in 3D and UV-unwrapped them into svg files. These I edited with inkscape to add the edge tabs.

Deploying Flask to Apache2 on Ubuntu 13.04

09/07/2013

I had some trouble deploying a Flask app with Apache2, so here’s a minimum working configuration.

Virtual environment setup

virtualenv appname
cd appname
source bin/activate
pip install flask
mkdir -p src/appname www
echo "site.addsitedir(os.path.join(base, 'src'))" >> bin/activate_this.py
echo "from .appname import *" > src/appname/__init__.py
cat > src/appname/appname.wsgi <<EOF
activate_this = '/path/to/virtualenv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

from appname import app as application
EOF
cat > src/appname/appname.py <<EOF
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "Success?"

if __name__ == '__main__':
    app.run()
EOF

Virtual host configuration

<VirtualHost *:80>
    ServerName host.name
    ServerAlias www.host.name
    DocumentRoot /path/to/virtualenv/www
    <Directory /path/to/virtualenv/www>
        Order allow,deny
        Allow from all
    </Directory>
    WSGIScriptAlias /connote /path/to/virtualenv/src/connote/connote.wsgi
    WSGIDaemonProcess host.name processes=2 threads=15
    WSGIProcessGroup host.name
    <Directory /path/to/virtualenv/src/connote>
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog /path/to/virtualenv/var/error.log
    LogLevel debug
</VirtualHost>

Ising model simulations

26/06/2013

I’ve been playing around with Monte Carlo simulations of the Ising model. The idea is that you have a grid of dipoles (think bar magnets) which interact with their neighbours. They can point up or down, and they feel a force from their neighbours which tends to make them parallel. However, there’s also random thermal motion which flips them randomly.

Depending on the ratio of interaction energy to thermal energy, different behaviors emerge from the lattice. The most interesting one is that below the critical temperature, the lattice spontaneously magnetizes, meaning there’s an imbalance between up and down. This models what happens in ferromagnets, which can retain magnetization if they are below the Curie temperature.

Here is the simulation code and a pretty video.

Android RenderScript: Solution to ‘Cannot find symbol’ forEach_root

17/06/2013

I’ve been playing around with RenderScript and found a problem only referenced in this StackOverflow question. Unfortunately, my solution brings another problem with it because it makes the app incompatible with my cellphone.

Ubuntu ARM toolchain compiles Stellaris USB examples correctly

22/12/2012

I managed to get the StellarisWare libraries and examples working without Sourcery Codebench. Based on these two articles:

The complete StellarisWare suite compiles without errors, and the examples I tried (including usb_dev_serial and usb_dev_mouse) work correctly. This is an improvement over summon-arm-toolchain, which compiled non-functional USB examples.

Instructions for Ubuntu 12.10:

  1. # Install toolchain
    sudo aptitude install gcc-arm-linux-gnueabi
    # Download and compile newlib (had trouble with the toolchain's libc and libm)
    wget ftp://sources.redhat.com/pub/newlib/newlib-1.18.0.tar.gz
    tar xzf newlib-1.18.0.tar.gz
    cd newlib-1.18.0/
    ./configure --target arm-linux-gnueabi --disable-newlib-supplied-syscalls
    make

    This makes the files libc.a and libm.a in the subdirectory arm-linux-gnueabi/newlib

  2. Unzip the StellarisWare files, and in the root directory edit makedefs. Search for the following settings and change them, replacing something with the directory where you unzipped newlib
    PREFIX=arm-linux-gnueabi
    LIBC=/something/newlib-1.18.0/arm-linux-gnueabi/newlib/libc.a
    LIBM=/something/newlib-1.18.0/arm-linux-gnueabi/newlib/libm.a

    Also change CFLAGS, adding the line with -fno-stack-protector, so it looks like this:

    CFLAGS=-mthumb             \
           ${CPU}              \
           ${FPU}              \
           -Os                 \
           -ffunction-sections \
           -fdata-sections     \
           -MD                 \
           -std=c99            \
           -Wall               \
           -pedantic           \
           -DPART_${PART}      \
           -fno-stack-protector \
           -c
  3. To compile everything, run make clean and make

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.