Monday, May 13, 2013

Embedding python in Mac OS X

I have been trying to figure out how to embed Python on the Mac. Trying the simple example found at http://docs.python.org/2/extending/embedding.html,


#include <Python.h>

int
main(int argc, char *argv[])
{
  Py_SetProgramName(argv[0]);  /* optional but recommended */
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
                     "print 'Today is',ctime(time())\n");
  Py_Finalize();
  return 0;
}


I got the error message that Python.h couldn't be found:


$ gcc test.c
test.c:1:20: error: Python.h: No such file or directory


Adding the header files to the search path then led to a linking problem:


$gcc -I /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Headers test.c 
Undefined symbols for architecture x86_64:
  "_PyRun_SimpleStringFlags", referenced from:
      _main in cch6pSfx.o
  "_Py_Finalize", referenced from:
      _main in cch6pSfx.o
  "_Py_Initialize", referenced from:
      _main in cch6pSfx.o
  "_Py_SetProgramName", referenced from:
      _main in cch6pSfx.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status


The all knowing Google was of limited help-- I could not find an explanation for how to embed python on the Mac platform. After divining the error message tea leaves, and pouring over man pages, I have finally found out how to EMBED PYTHON ON THE MAC!! (cue 2001: A Space Odyssey theme!)

The magic incantation is

gcc -I /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Headers -L /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib -lpython2.7 foo.c

I have macports python installed, but if you don't, you will need to change the "/opt/local/Library..." to "/System/Library..."

The -I option adds a directory for finding header files. The -L adds a directory for finding lib files. The -lx option loads the library file named libx.dylib.

I then added a bash alias:
alias pygcc='gcc -I /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Headers -L /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib -lpython2.7'

I can now invoke the compiler using
pygcc foo.c

Another thing I found out is that the current directory is not in sys.path. You therefore can't load modules that are in the current directory. You can add the current directory by adding PySys_SetArgv(argc, argv); after the call to Py_Initialize(); so that it looks like:

Py_Initialize();
PySys_SetArgv(argc, argv);    //adds current directory to sys.path
...

Update: It seems that there is a slightly easier way to add the proper include and library directories using the python-config command (which doesn't have a man page on Mac OS BTW). Calling python-config with --includes --ldflags returns the appropriate options for gcc:

$ python-config --includes --ldflags
-I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
-L/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -ldl -framework CoreFoundation -lpython2.7 -u _PyMac_Error /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Python

So you can shorten the gcc incantation to:
gcc `python-config --includes --ldflags`
and shorten the alias to
alias pygcc='gcc `python-config --includes --ldflags`'

Sunday, May 5, 2013

Solder stencil using Shapeoko

I purchased two Sick of Beige Bus Pirate v4 from schazamp on the DangerousPrototypes forums a couple of months ago and have been dragging my feet assembling them. I used hand soldering for the SMD parts on my DIY Bus Pirate v3 but for v4, I wanted to try making a solder stencil and reflow using a hot air rework station. There have been several articles recently about etching copper and aluminum stencils and also a recent article about using a Cricut to cut a stencil out of overhead transparencies.

I recently built a Shapeoko and wondered whether it could be used to make solder stencils.

I used the Eagle CAM processor to output the tCream layer as a HPGL file. I then used a GNU hp2xx to convert the HPGL file into SVG. (It took a bit of tweaking to get hp2xx to compile on Mac OS X 10.7.)

The command

hp2xx -t -m svg tCream.pltd

will convert the .plt HPGL file into a SVG file which looks like this:
I then used Illustrator to make 0.039" circles to approximate the holes from a #61 size drill bit. I used a red fill and a small stroke to make things easy to see and keep track of but the color and even the size of the hole don't really matter-- only the center coordinates are extracted. I tried approximating the drill hole area to the area of the pad. Big pads were filled with several holes. The small pads on the TQFP chip in the middle were a bit of a challenge. I guess I could have put a drill hole in the center of each pad but ended up with a staggered line of drill holes. The end result looked like this:


Then came the task of turning the red dots into something I can send to the Shapeoko. I used the python svglib library to read in the modified SVG file and spit out all the circle coordinates. This part was surprisingly easy but kludgy. The SVG file is read into something called a ReportLab format and I had some difficulty figuring out the class/data structure-- if anyone knows of a better/cleaner/more robust way of evaluating/interrogating the report lab object, I would appreciate the help (my python introspection-fu not strong).

import svglib

dr = svglib.svg2rlg('tCream.svg')

print "G20 G17 G40 G49 G64 P0.005 G80 G90 G94"  ## magical gcode incantation to start
print "G1 Z0.15 F10"    ##lift before moving!!

for i in dr.contents[0].contents:
    if i.__class__.__name__ == 'Circle':
        #print "circle at %f, %f"%(i.cx,i.cy)
        print "G0 X%f Y%f"%(i.cx/72.,i.cy/72.)
        print "G1 Z-0.05 F15"
        print "G1 Z0.15 F15"
print "M5\nM2"  #magical gcode incantation to end

The result was a gcode program I could send to the Shapeoko:
G20 G17 G40 G49 G64 P0.005 G80 G90 G94
G1 Z0.15 F10
G0 X0.685014 Y0.568389
G1 Z-0.05 F10
G1 Z0.15 F10
G0 X0.708736 Y0.603111
.....
G0 X1.160417 Y0.848500
G1 Z-0.05 F10
G1 Z0.15 F10
M5
M2

All told, 270 holes to drill-- took about 20 minutes (I ended up breaking two drill bits). Might be able to speed things up a bit using a traveling salesman algorithm but the order extracted from the SVG file is not too bad. Here is a link to a video of the Shapeoko in action. And a picture of the completed stencil.



The whole process is surprisingly quick and easy. Drawing the circles is slightly tedious but only took 5 minutes for this small board so not too bad. Some of the pads are a bit wonky-- after the drill bit(s) broke, I rezeroed the Z axis with a new drill bit and ran the gcode again. Some of the holes have actually been drilled three times. Overall the registration between the runs was very good-- the registration between the stencil and the board is quite good. I can't wait to try it out-- I am waiting for delivery of my Mouser order.

Thursday, June 14, 2012

Soldering iron driver v1.5 build

So I finally have my soldering iron driver v1.5 from dangerousprototypes (designed by Arhi, laid out by  Arakis) in a condition that is stable and useable.

A few words of advice for people building this

  1. When you populate the board, build the power supply section first and test it to make sure it works. You don't want to find out your buck converter is not working when smoke comes out of your op amp or PIC18F.
  2. The adjustment of the trim pots in the positive temperature coefficient (PTC) amplifier is explained in a readme file in the hardware section. This adjusts the constant current source into the PTC thermistor.
    1. Remove sensor from PTC connector
    2. Attach milliampermeter to PTC connector
    3. Power the device on
    4. Turn CAL1 pot until you get exactly 1.000mA going trough. 
  3. Once you have the current source trimmer set, set the gain as follows.
    1. Remove sensor/milliampermeter and connect a 100 OHM resistor (1% or better) to PTC connector. 
    2. remove jumper from JP1
    3. Power on device 
    4. Turn the RV2 pot until you get on the top pin of JP1 exactly 3.00V
  4. I had problems with the heater control section. It turns out the opto-triac was bad. Not sure if I received a bad one or I fried it somehow. I ended up picking up a non-zero-crossing opto-triac at the local All Electronics. In case you were wondering, a non-zero-crossing works just fine.
  5. Arhi recommended not installing the capacitors for the low-pass Sallen-Key filter. I didn't see that warning until after installing them. They actually worked well with a time constant pretty close to the calculated value so I left them in.

After the board was fully populated, except for the NTC and the thermocouple amplifier sections, I squeezed everything into a plastic box. The enclosure was actually a container for Korean pepper paste (gochujang). I was impressed with Egor who correctly identified the container from a front/side shot.
Here is a picture of the top clearly showing its source.

I hooked up buttons for menu, + and -. These were interrupt driven and the switch bounces caused a lot of problems. Arhi wrote a debounce routine but the button presses were limited to 5 per second and there was no autorepeat which made adjusting the temperature a bit tedious.

I rewrote the debounce code and added autorepeat. This made the interface much easier to use. I posted the changes in the forum http://dangerousprototypes.com/forum

Here is a shot of the inside.
I need to secure the circuit board inside. There is a lot of empty space inside and I am always short on benchtop space. If I am motivated, I might move everything into a smaller enclosure (Korean soybean paste (doenjang) container perhaps). I will have to use a smaller LCD display (8x2 characters) and rewrite the firmware to be more succinct and frugal.

Here is a shot of the completed circuit board. In the second picture, you can see the diode lead art for the bridge rectifier. The capacitor to the right of the diode was a bit big and the diode was squeezed for space. There is another diode standing upright just behind the cap as well.



The transformer was salvaged from a lab freezer controller board. It has multiple primary windings for different input voltages and two separate secondary windings. In its current configuration it puts out 20V AC. Even after its been on for an hour, I can't detect a temperature increase above ambient. The triac gets a bit warm, possibly because the input voltage is lower than the expected 24V so I am going to put a heatsink on it.

Addendum: I have received several requests for precompiled binaries. I have uploaded the modified source along with the compiled binaries (with and without bootloader versions) to github. You can get them at

https://github.com/hardwhack/Soldering-iron-driver

Tuesday, May 8, 2012

Making Tris buffers by mixing

One of my least favorite lab activities is measuring pH. It dates back titrating buffers using burettes in chemistry lab-- drip dropping one droplet at a time, becoming impatient, and then overshooting. Barnacles!

I try to avoid making Tris buffers for the same reason-- it requires careful drip dropping of HCl. If you overshoot a little, you can bring the pH back using NaOH but then you have added NaCl to your buffer. I found out the hard way making TAE buffer this way-- the NaCl conducts electricity too well.

I need to make Tris pH 7.7 for protein purification and was wondering if there was a way to mix Tris base and Tris HCl to come close to the desired pH. It turns out you can using the Henderson Hasselbalch equation.

pH = pK + log([A-]/[HA])

pK for Tris is 8.1 at 25 deg C

[A-] = 0.285 and [HA] = 0.715 for a 1M solution when pH = 7.7

Using FW for Tris base and HCl that translates to 112.7g of Tris HCl and 34.5g Tris base.

Here is a python script I wrote to solve for the values. Save it as pH.py then make it executable using chmod u+x pH.py. To use it, type pH.py 7.7. Here is a sample output:

$ pH.py 7.7
For pH 7.7 Tris buffer at 25 deg
112.72 g of Tris-HCl for 1L of 1M soln
34.49 g of Tris-base for 1L of 1M soln

Here is the python script.

#!/usr/bin/python

import sys

ph = float(sys.argv[1])
pk = 8.1 ## at 25 deg
            ##N.B. per Sigma catalog, pH drops 0.03 to 0.05 per ten fold dilution
            ## also increases ~0.03 per deg C

mwb = 121.136   # FW of tris base
mwa = 157.59    # FW of tris HCl

# use henderson hasselbalch equation to solve for a and b
# pH = pKa +log10(b/a)

a = 1./(1+10**(ph-pk)) #solve for a and b
b=1.-a                  # for a+b =1, i.e. 1M soln
                        # math is your friend

print "For pH %2.1f Tris buffer at 25 deg" % (ph)

print "%.2f g of Tris-HCl for 1L of 1M soln" % (a*mwa)
print "%.2f g of Tris-base for 1L of 1M soln" % (b*mwb)

OK, this is high school chemistry, but that was a long time ago. Hope you find this useful.

Monday, April 9, 2012

ApProg430

I would like to win one of the elusive free PCB coupons from Dangerous Prototypes. Finish one, get another! How can you beat that deal? Haven't won yet, but it is only a matter of time.

I have to admit, I was one of the people who requested the opportunity to buy PCBs from the PCB drawer. When I saw Ian's breakdown of first year sales of the Bus Pirate, I felt twinges of guilt because I had not yet purchased. I plunked down my $10 and received two DIY Bus Pirates PCBs. I sent in a Mouser order for the parts (plus extra SMD resistors because they are easy to lose).

All told, the PCBs, components, plus shipping/handling came out to about $50 for the two Bus Pirates. Considering Seeed Studio will sell you one for $27, assembled, programmed, and shipped, this was starting to look like a losing proposition. Did I mention the twinges of guilt driving the purchase?

I soldered up the boards in an evening. This was my first time assembling SMD parts but after watching the HOWTO videos on Dangerous Prototypes, it wasn't so bad. Patience, flux, and desoldering braid.


When I plugged in a USB cable, the PWR LED came on and the computer recognized the FT232 chips. So far so good. Now I needed to program the PIC24 chips but I don't have a PIC programmer. I didn't want buy a PicKit because that would really make for a losing proposition. I saw that Jozef had devised a way to program the devices using a AVR microcontroller. He was kind enough to share source, precompiled binaries, and firmware. Great! But I don't have a AVR programmer. Talk about bootstrapping problems!

I do have a MSP430 Launchpad and I figured I could have the MSP430 emulate the AVR. I modified the firmware code to run on a MSP430G2553. I picked this part because it has a built in UART. You can probably modify the code to run on MSP430s with software UART but I am not going there.

Here is a picture of the programmer hooked up. PGC is on P2.0, PGD on P2.1 (through a 1K resistor), and MCLR on P2.2. The Launchpad runs at 3.6V but this is within the electrical specs for the PIC24 so I figured why not. Fortunately, it works just fine.


I programmed the v4.4 bootloader using ApProg using the Launchpad running the modified firmware. The firmware came next using the ds30 loader GUI. This is much faster than trying to program the combined bootloader/firmware using ApProg. The ApProg binary is available here.

And it works! I have two functional Bus Pirates. No more twinges of guilt. So the final cost for the two Bus Pirates (PCBs, parts, Launchpad) came out to almost exactly what I could have ordered from Seeed Studio. But mine have DIY silkscreened on the boards!

Here is the source code for the MSP430. It has been condensed into a single file. You can create a new project in code composer studio v5, copy and paste into main.c and compile. Some day, perhaps I will take the time to learn how to host files on github. Posted on github.