Basic Stamp tokenizing and flashing from the Linux CLI

For those of you who aren’t familiar with the Basic Stamp, its a small microcontroller available from Parallax. It runs at a whopping 20Mhz and has a full 2K of storage on board for instructions. Although it may not sound like much, its more than enough to program the stamp to do some interesting things. The Basic Stamp is programmed in PBASIC, parallax’s version of BASIC the stamp interprets.

Rather than waste your time explaining the coolness of the Basic Stamp, (if you’ve found this page you’re probably already interested) I want to focus on how it can be utilized under linux. Currently, Parallax has a very nice PBASIC IDE but its available for windows only. It can however be run under Wine, and with the proper font settings it doesn’t look too horrible and is quite functional. But what is the fun in that?

If you’re more of a ‘vim’ guy like me, there’s a better alternative. A quick visit over to sourceforge and you’ll find a set of command line tools available for download that make it easy to tokenize code and send it to the stamp without needing to reboot into windows.

After downloading the tarball, unpack it and move into the directory. All you need to do now is build it, and it shouldn’t require much more than a simple ‘make’.

unpack…

tdavis@tdavis-64:~$ tar xvzf bstamp-2006.05.31.tar.gz
bstamp/
bstamp/bstamp_run.cpp
bstamp/tokenizer.h
bstamp/PBASIC_Tokenizer_Software_Distribution_License.txt
bstamp/pbasic_examples/
bstamp/pbasic_examples/hello.bs2
bstamp/pbasic_examples/Makefile
bstamp/pbasic_examples/touch.bs2
bstamp/Makefile
bstamp/PBASIC_Tokenizer_Software_Distribution_License.pdf
bstamp/TODO.txt
bstamp/GPL.txt
bstamp/README.txt
bstamp/CHANGES.txt
bstamp/COPYING.txt
bstamp/bstamp_tokenize.cpp
bstamp/tokenizer.so
bstamp/error_handling.cpp
tdavis@tdavis-64:~$

move into the directory where you unpacked the tarball…

tdavis@tdavis-64:~$ cd bstamp/
tdavis@tdavis-64:~/bstamp$

and build it…

tdavis@tdavis-64:~/bstamp$ make
tdavis@tdavis-64:~/bstamp$ make install

The last step is to make a symbolic link to whatever serial port your stamp is hooked up to. In my case it was /dev/ttyUSB0 because I’m using a serial to usb converter, but for a regular serial connection its likely to be /dev/ttyS0 or /dev/ttyS1. The symlink needs to point the serial device to a new location, /dev/bstamp. If at any point you encounter any problems, don’t forget to check out the README.txt that comes with the program.

tdavis@tdavis-64:~/bstamp$ sudo ln -s /dev/ttyUSB0 /dev/bstamp

Now you just need some code to tokenize, as an example here’s a simple program I wrote that does nothing more than monitor the light levels off a photo resistor and produce output accordingly. (It beeps and blinks!) Its certainly not the most beautiful code, but it does the trick.

'for Basic Stamp 2
'basic light meter that shows on 7 segment display
'and controls LEDs related to the amount
'of light detected; can also produce
'audio output through a piezo electric
'speaker based on the amount of light detected
'@ Tyler Davis 2007
' {$STAMP BS2}
' {$PBASIC 2.5}
DEBUG "program running!"
index VAR Nib
time VAR Word
dark CON 25
OUTH = %00000000
DIRH = %11111111
'FREQOUT 2, 2000, 4500 'test spk on p2


DO
GOSUB Get_RC 'grab light level info
GOSUB Delay 'delay between refreshes
GOSUB Update_Display
GOSUB sound 'play sound that changes as light
'measurments do
LOOP

Get_RC:
HIGH 0 '0 pin
PAUSE 3
RCTIME 0, 1, time
DEBUG HOME, "time = ", DEC5 time
IF (time > 200) THEN HIGH 6 'for green and
IF (time < 200) THEN LOW 6 'red lights
IF (time < 200) THEN HIGH 4
IF (time > 200) THEN LOW 4
IF (time < 35) THEN HIGH 5
IF (time > 35) THEN LOW 5
IF (time > 400) THEN HIGH 3
IF (time < 400) THEN LOW 3
RETURN
Delay:
PAUSE time
RETURN

Update_Display: 'to adjust 7 segment display
IF index = 6 THEN index = 0
LOOKUP index, [ %01000000,
%10000000,
%00000100,
%00000010,
%00000001,
%00100000 ], OUT
index = index + 1
RETURN

sound: 'to create audible sounds related to
'detected illumination levels
FREQOUT 1, 50, time + 4000
RETURN

Now I’m gonna assume you’re using your own code since my code is kind of worthless without a corresponding schematic, but I guess it could be figured out. Since I don’t feel like drawing up one I’ll just post a picture and if someone wants to try and figure it out they’re welcome to. (Sorry but they’re terrible pictures, I’ll try and get better ones up as soon as I get a chance).



Otherwise the process of tokenizing the code and writing it to the stamp is quite straightforward.

tdavis@tdavis-64:~/bstamp$ ./bstamp_tokenize lightmeter.bs2 lightmeter.tokenized
: Success
PBASIC Tokenizer Library version 1.23

tdavis@tdavis-64:~/bstamp$

tdavis@tdavis-64:~/bstamp$ cat lightmeter.tokenized | bstamp_run

If you run into any problems, be sure to verify you’re working with the correct serial device. Try a ‘dmesg | grep ttyS’ and see what it brings up. Or replace ‘ttyS’ with ‘ttyU’ if you have a USB connection.

Building a Delta 3d Printer Part 1

So I have always been interested in delta printers and I have finally gotten my Mendel Max 2 working well enough where I can begin to print parts to build one. I spent some time on reprap.org and Thingaverse and decided to go with the following topology:

For the frame I chose the Kossel Alt. LM8UU bearings have worked well for me in the past with my Reprap Prusa, but I like the aluminum extrusion frame used in the Kossel. The Kossel Alt frame on Thingaverse seems to be a good incorporation of both designs. I used 20mm extrusion from Mitsumi.

Parts BOM:

J-Head MK-V 0.4mm Nozzle Bowden http://www.ebay.com/itm/281188467531 $46.00
6 8mm x 800mm Precision Chromed Rod http://www.ebay.com/itm/330983575585 $91.88
12 LM8UU Bearings http://www.ebay.com/itm/181182250805 $19.99
4 GT2-20 $ 10M of GT2 Belt http://www.ebay.com/itm/331016217210 $51.90
Mega 2650 + Ramps with drivers http://www.ebay.com/itm/300956634636 $131.00
MK8 Drive Gear http://www.ebay.com/itm/281102410932 $15.00
6 Rods, 12 Set Screws, 12 Rod Ends http://www.amazon.com/gp/product/B00DZTTY5K/ $22.50
12v 30a DC PSU http://www.amazon.com/gp/product/B00D7CWSCG/ $27.48
4 NEMA 17 400 Step http://www.phidgets.com/products.php?category=23&product_id=3302_0 $60.00
PCB MK1 Heatbed http://www.makergeeks.com/pcbmk1hefor3.html $25.55
3 Misumi HFS5-2020-800 http://us.misumi-ec.com/vona2/detail/110302368740/?HissuCode=HFS5-2020-%5B50-4000%2F0.5%5D&SeriesSpec=D001%3A%3A800&PNSearch=HFS5-2020-800 $13.68
9 Misumi HFS5-2020-300 http://us.misumi-ec.com/vona2/detail/110302368740/?HissuCode=HFS5-2020-%5B50-4000%2F0.5%5D&SeriesSpec=D001%3A%3A300&PNSearch=HFS5-2020-300 $15.39
100 Misumi HNKK5-5 T-Nuts http://us.misumi-ec.com/vona2/detail/110302246940/?HissuCode=HNKK5-5&PNSearch=HNKK5-5 $19.32
Total $539.69

I already had M3 screws, M5 screws, bearings, and various gauges of wire from previous projects.

The first challenge I had was getting a good flow setting to print brackets that were able to fit the extrusions. I noticed that increasing my flow rate make a much nicer/stronger print, but I had trouble fitting the aluminum extrusion because the inside dimensions of the hole were too small. Eventually, I figured out that I had to slightly increase my nozzle diameter in slicr to 0.42mm. I was then able to fit the extrusion with a little filing.

One I printed all the supports, I was ready to start assembling the frame. I used M5 bolts which required a little drilling to fit nicely.

Once the frame was complete, I started to print the carriage and platform. I went with the following Rostock part http://www.thingiverse.com/thing:31642

For the J-Head holder I used this: http://www.thingiverse.com/thing:156860 minus the fitting holder ( the J-head already had the tube fitting attached).

To keep the machine neat, I designed a holder for the Mega and RAMPS that will fit underneath the print bed.


Next I printed the Airtripper Bowdwen Extruder BSP: http://www.thingiverse.com/thing:126778 and attached the stepper and the MK8 Gear. I had to play a bit with slicing to get the best print; I printed it using Slic3r and KissSlicer and then selected the best parts.

Now for the fun part: wiring everything up!


Wiring took about 4 hours. I made sure to solder all joints as well as use heat shrink tubing and wire connectors from Ultimachine https://ultimachine.com/content/254mm-1×3-connector-positive-latch-housing-kit-6-pack

With all the wiring complete, I now had to install the firmware. I have been fairly happy with Repetier http://www.repetier.com/ and decided to go with it again since it had delta support. In Configuration.h, I selected a Delta motion with a RAMPS motherboard, a DELTA_DIAGONAL_ROD length of 339mm, and PRINTER_RADIUS of 205mm. Once programmed, though, I was getting invalid delta move errors. I played with settings and found that lowering the DELTA_DIAGONAL_ROD to 250 would stop the errors. I read a few forums and determined it may be due to a integer overflow. I backed off the micro-stepping from 1/16th to 1/8th and I was able to keep my rod length at 339mm.

My first print was not really great. Also, I burnt up all my fans! I knew they were 5 volt fans so I just dropped the duty cycle to 40%. However the internal electronics did not like that and they started smoking. Unfortunately, I cannot find a 12V version of those little 20x20mm fans at a reasonable price, so I will probably have to make a new mount and use a 40x40mm 12V fan.

I was not expecting a perfect print, as I knew the rods were way to long and perhaps not all the same length. So I build a small jig and cut the tubes down to create a DIAGONAL_ROD_LENGTH of exactly 250mm.

I also used some epoxy glue to make sure the 4mm bolt stayed in place. After the glue fully cured, I installed the new rods, updated the firmware, and tried some more prints.

The Lucy Cat I printed came out fairly well except for some problems around the neck. I have not installed the end stops yet, so I had to manually home the machine. I did this by setting all the carriages to a fixed height and then lowering z-axis till the tip just touched the bed. I then had to restart the RAMPS board so it would use that position as zero; clicking the home button or sending G28 would not zero the machine after I jogged it manually.

For the end stops I went with a traditional design that just clamps to the smooth rod.

In order to home the machine, I used the following Repetier firmware settings:

#define ENDSTOP_PULLUP_X_MIN false
#define ENDSTOP_PULLUP_Y_MIN false
#define ENDSTOP_PULLUP_Z_MIN false
#define ENDSTOP_PULLUP_X_MAX true
#define ENDSTOP_PULLUP_Y_MAX true
#define ENDSTOP_PULLUP_Z_MAX true

//set to true to invert the logic of the endstops
#define ENDSTOP_X_MIN_INVERTING true
#define ENDSTOP_Y_MIN_INVERTING true
#define ENDSTOP_Z_MIN_INVERTING true
#define ENDSTOP_X_MAX_INVERTING true
#define ENDSTOP_Y_MAX_INVERTING true
#define ENDSTOP_Z_MAX_INVERTING true

// Set the values true where you have a hardware endstop. The Pin number is taken from pins.h.

#define MIN_HARDWARE_ENDSTOP_X false
#define MIN_HARDWARE_ENDSTOP_Y false
#define MIN_HARDWARE_ENDSTOP_Z false
#define MAX_HARDWARE_ENDSTOP_X true
#define MAX_HARDWARE_ENDSTOP_Y true
#define MAX_HARDWARE_ENDSTOP_Z true

//If your axes are only moving in one direction, make sure the endstops are connected properly.
//If your axes move in one direction ONLY when the endstops are triggered, set ENDSTOPS_INVERTING to true here

//// ADVANCED SETTINGS - to tweak parameters

// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
#define X_ENABLE_ON 0
#define Y_ENABLE_ON 0
#define Z_ENABLE_ON 0

// Disables axis when it's not being used.
#define DISABLE_X false
#define DISABLE_Y false
#define DISABLE_Z false
#define DISABLE_E false

// Inverting axis direction
#define INVERT_X_DIR true
#define INVERT_Y_DIR true
#define INVERT_Z_DIR true

//// ENDSTOP SETTINGS:
// Sets direction of endstops when homing; 1=MAX, -1=MIN
#define X_HOME_DIR 1
#define Y_HOME_DIR 1
#define Z_HOME_DIR 

// Delta robot radius endstop
#define max_software_endstop_r true

//If true, axis won't move to coordinates less than zero.
#define min_software_endstop_x false
#define min_software_endstop_y false
#define min_software_endstop_z false

After some prints, I noticed a lot of play in the smooth rods and am fairly sure it was effecting print quality on things with a lot of jerky moves. I decided to provide more support for the rods on the top of the machine to try and fix the problem. I accomplished this by moving the top support down a few inches and then adding an additional support.


This greatly increased the stability of the smooth rod and helped overall performance, but at the cost of reducing the printable height. This printer is so tall that even after this modification it still has almost twice the height as my Prusa or MendelMax2.

Now that the print motions are working fairly well, I am noticing some extruding problems, especially with layer heights of less or equal to 3mm. After spending some time researching, I believe the problem is due to lack of microstepping on my extruder. In my initial parts order, two of the five stepper drivers were defective; one would not work at all and the other did not allow me to select microstepping. To get started, I put the semi-working one on the extruder. I figured it would not matter and the extruder could use the extra torque provided by not microstepping, anyway. My steps per millimeter are around 20 on a direct drive extruder using an MK8 drive-gear. This is not nearly enough and the machine leaves a blob every time the extruder ticks. I have talked to the seller of the electronics and waiting for replacement stepper drivers. Once I receive the drivers I will post the results.

Mining on an R9 290 in Linux

Picked up a couple of the newer R9 290s to add to my mining rig recently and encountered a number of problems with the latest AMD/ATI drivers as well as cgminer. It seems to be fairly common for the latest drivers to cause issues on both Linux and Windows .

The fact that cgminer no longer supports GPU’s compounds the issue, but it is a fixable problem. The latest beta drivers (13.12)need to be patched to keep them from crashing and failing entirely. More information on such can be found here. Someone was also nice enough to provide binaries for Ubuntu.

If you can get that far, you’ll quickly find that cgminer will crash upon exit (use version 3.7 and earlier if you want GPU support as its been dropped), and lock the GPU resource (fans will continue running for example) until reboot.

With their Hawaii architecture, AMD updated some things for the R9 290/290X. Specifically, they’ve updated their Overdrive engine from version 5 to 6

This means cgminer isn’t capable of handling the latest series of graphics cards. The solution involves compiling cgminer from scratch and fixing the adl calls or just disabling anything related to temperature and fan control — a bad idea considering how hard mining is on video cards. Its critical to monitor and control temps or risk destroying very expensive GPUs. So based on information attained here I went ahead and recompiled cgminer with the latest and greatest SDK and AMD drivers — it works perfectly now. No more crashes on exit.

In the adl.c file around line 472, just before the ADL_Overdrive5_FanSpeed_Get call, add a line above: ga->DefFanSpeedValue.iSpeedType=ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;

However I had some issues when I actually installed the SDK and compiled cgminer, it adds a number of things to /usr/include and /usr/lib and they ended up causing hardware recognition issues for me on Ubuntu 13.10. In the latest versions of AMD/ATI drivers, the SDK is ‘included’, however in practice cgminer won’t find it without specifically pointing to it. The solution was to fix adl.c in cgminer, and point to local user space copies of the latest SDK for ADL and openCL recognition/compatibility, without actually installing them. This provided access to all 5 GPUs from userspace, without even needing sudo. I highly recommend NOT installing the 6.0 ADL if you are in a similar situation, I encountered endless issues with such, since the drivers technically already include the SDK.

Depending on where you unpack the 2.9 SDK you can use the following line to successfully build cgminer with proper temp and fan control support, without having to actually install (and risk ruining your ability for cgminer to find your GPUs) the SDK:

CFLAGS=”-O2 -Wall -march=native -I/location/to/SDK/AMD-APP-SDK-v2.9-RC-lnx64/include/” LDFLAGS=”-L/location/to/SDK/AMD-APP-SDK-v2.9-RC-lnx64/lib/x86_64″ ./configure –enable-opencl –enable-scrypt

Last but not least here are some good settings for a PowerColor AXR9 290 4GBD5-MDH/OC Radeon R9 290. I’m getting about 875 Kh/s out of these particular cards with this setup. This seems to be near the top of the list for similar setups.

./cgminer –scrypt -o yourpool.com:port -u user.worker -p password -I 20 -g 1 -w 256 –auto-fan –lookup-gap 2 –thread-concurrency 24550 –gpu-memclock 1500 –gpu-engine 1000 –gpu-powertune 20 -v 1

scrypt-r9-290-settings

But thats running one of the cards fairly hot. Personally I like them to run a little cooler so I had to adjust my cooling a bit to make up for the difference. Lowering the intensity down to 19 and the powertune down to 10 yielded me lower temps but still respectable hash rates (840khash).

If you are having issues compiling, I went ahead and compiled a verison of cgminer with the adl fixes and the latest and greatest sdk. It should work on most 64 bit ubuntu systems with the latest AMD/ATI drivers. You can download it here.

I am unfamiliar with this particular hosting site, but it was free so I posted it, please double check the md5sum before opening. If it hasn’t been tampered with it should be:

md5sum cgminer-3.7.0-amd-r9-fix.tar.gz
7caacb590eb419c380b7d223797dc959

Latest mining rig:

2013-12-22(2) - Copy

LTC: LTjmMFrxm4mnRWM4wvH5WQdJPnw3fUmYiz

Drawing Lissajous Curves on a Oscilloscope

Lissajous curves (http://en.wikipedia.org/wiki/Lissajous_curve) are two dimensional figures where the points (x,y) are defined by sine functions with different coefficients:

x = sin(t)
y = sin(at+b)

By modifying a and b over the period t, a wide variety of fascinating curves can be drawn, some of which look almost 3D!

For example, if y is a sine wave that is exactly 90 degrees offset (“out of phase”) from x, the plot is a perfect circle:

x = sin(t)
y = sin(t+pi/2)


(credit: Wikipedia)

In the lab, an oscilloscope is the ideal instrument for plotting x and y coordinates. Typically, an oscilloscope will plot the voltage of an primary input on the y axis vs. time on the x- axis.

scope_5

However, most oscilloscope will allow you to supply an external input that will allow you to directly control the x axis. We can connect a function generator to both the x and y axis and begin to draw Lissajous patterns.

IMG_0920

IMG_0888

By shifting the frequency and phase of the signals, you can get different shapes. However, even at the office we don’t yet have two (working) function generators which can be phase locked. In the picture above, you can see that we’re using a HP33120A and a HP 200AB. The 33120A has a trigger input, but no such luck for the old-school 200AB. With some fiddling, they can be brought into phase, but it’s much easier and more fun to build our own frequency generators. That’s where the DAC Shields and an Arduino come in.

IMG_0914

The DAC Shield has inputs for positive and negative power and an output for the signal. For this exercise, we’ll be using two bench power supplies (Mastech HYB3003 and Mastech HYB3003), but you could also use two batteries.


IMG_0925

The output of one shield is connected to the X-axis input of the ‘scope the other is connected to the Y-axis. On the Tektronix 2246 shown here, channel 1 can be set to drive the X-axis.
The trick to initially plotting a circle is to make sure that the amplitude of both axis move the cursor equal amounts, so make sure to set both “volts/div” settings the same.

IMG_0933

To start with a circle we simply write a program that generates a sine wave at a given frequency on channel 1 and then creates a second sine wave on channel two which is 90 degrees out of phase.

while(true):
write(channel1, sin(t));
write(channel2 sin(t+pi/2))

While this pseudo code is close, some considerations have to be made due to the discrete nature of the DAC. For instance, the resolution of the DAC will determine the value of the minimum output, zero and the maximum output. In this case we have a 12bit DAC with positive and negative supply rails at 10 V and -10V, respectively. Writing a “0″ to the DAC will result in an output of -10V. Similarly, writing “2048″ will output 0V and “4096″ will output 10V.

Thus, we need to scale our original pseudo equations:

write (channel1, (sin(t) * 2048 + 2047))

Where t = 0 would be 2047, t=pi/2 is 4096 and ….

Another consideration is the base frequency for the sine wave; this will depend on how fast you can write to the DAC and how many cycles it takes to compute the sine wave. Inserting different delays between samples of the wave generates different frequencies. For example if you the second channel is doubled in frequency from the first you will generate the following shape.

IMG_0931

Also by increasing the phase of one the the sine wave though every iteration of the loop the figure can be animated as seen here on a Rigol MSO4050 in which we are evaluating.

Example source code and schematic for the DAC shield can be found on Github here, Also the Power DAC Shield can be purchased from Tindie.

power_dac_shield_banner1-01

 

experiments-with-audio-vacuum-tubes

Previously I tested a El84 using series of 9 volt batteries to generate the high B+ voltages. While it was very simple by nature, it still fell short of the desired voltages that are required to make a useful audio amplifier. Normally the solution to this problem is to use a step up transformer and rectify the mains current. These transformers are not cheap, very heavy, and costly to ship, but above all I did not have one at the time. Another option is direct rectification of the mains AC. This technique has been used in radios of the past and is extremely dangerous! Without a fuse this circuit will draw as much current as you house will deliver. Also the ground of the circuit will be directly coupled to the neutral of your home. If you use a non polarized plug or there is a mis-wiring of your outlets, the ground of your circuit would complete a direct 120v path with the “ground” of another circuit. So for initial testing I decided to go with a boost converter.

The Boost conveterter

The operating principal of a boost converter is very simple, am inductor is charged and then released though a diode to charge a capacitor. This principal is used in switch mode power supply units. Most switching regulators are designed to work at lower voltages, say bump up a 5V supply to a 12V supply. I have a few MC34063A switching regulators I bought a while back for the exactly purpose of running 12V out of a couple AA batteries.

This devices is only rated to 40V. So I had to add some supplementary components in order to ramp the voltage over 100V. To do this I did the switching using a IRF740 MOSFET. At first I tried driving the opamp directly from the regulator. In simulation this would work however I discovered that real MOSFETs have a fair amount of capacitance at high frequencies that will create a lot of resistance. So I had to create a MOSFET driver. For this I chose a 2n222 / 2n907 NPN/PNP pair. When working with high voltages it is important that all the components are rated appropriately. This is espcially important for the capacitor and diode following the MOSFET. The capacitor I chose was surplus disposable flash capacitor rated at 330V with a capacitance of 270uF. The diode is a simple rectifying diode, I may have had better performance with a Schottky diode however all the ones I have were not rated for voltages this high.

180v_Boost_Converter.png

P1020503.JPG

Designing an Audio Amplifier

For designing the audio amplifier I went back to the circuit simulator. Falstad’s simulator has a triode and the it’s model parameters can be edited by exporting and re-importing the circuit file. I asked Paul how to change the characteristic of the tube and he replied with the model that he used to simulate the triode that is as follows: ((Vgk+Vpk/mu)^1.5)/kg1 where Vgk = gate-cathode voltage and Vpk = plate-cathode. In order for me to simulate commercially available triodes I needed to find kg1 and mu values that would get me close. For this I wrote a python program using matplotlib to allow me to play with different values and visualize the results. Below are a couple screen shots.

An 12ax7 Preamp Troide, The y axes is milliamperes and the x is volts
tube_plot_12ax7.png

A El84 Poweramp Pentode running in Triode mode
tube_plot_el84.png


The source code for this project can be found on my Github account under Tube Plot. This code was developed on Ubuntu using python 2.6.5 and matplotlib.

After finding values that were close to the original data sheets (at least for the voltages I intended to run) I then did some simulations.

The Preamp
tube_preamp.png

The Poweramp
tube_poweramp.png

Putting it all together

Now that I ran some simulations I deiced to try building it all out. First I tried using the switching power supply and only the power amp state using a function generator as the preamp.

P1020509

While this did work, it was very stressful on the boost converter. A lot of current had to be drawn. I spent about a day or two playing with different inductors and switching frequencies to get optimal efficiency. In this time I blew a couple mosfets and diodes. Eventually a ham buddy of mine gave me a step up transformer to play with so I deiced to make a traditional power supply.
P1020515

I used a broken PSU as the case so I could recycle the power connectors and power switch. I also added a fuse along with the rectification circuit. This PSU reads arround 200v unloaded and 180v loaded, about the same as my switching supply.

So I could actually play music from my iPod, I built out the 12ax7 preamp. Both tubes heaters are using a 6V battery in this test. So far everything seems to work well. In the video blelow I used an old Bose speaker and played some music.

The song being played is “Against all Odds by” Brian Botkiller. The little pocket oscilloscope from Gabotronics is displaying the voltage ripple of the power supply.

Home made 555 timer from NPN and PNP transistors

Before the 555 contest was announced I was reading the free online book 50 555 Circuits from talking electronics. I was very amazed with how much could be done with the 555 timer. So I decided the best way to understand the 555 would be to try and build one. First I looked at some generic block diagrams and also the schematic diagram published in the National Semiconductor datasheet. After I understood the theory, I tested it out in my favorite circuit simulator by Paul Falstad. This program should be up to the task of simulating at a very high level.

555_circut

So far so good, Next I needed to build an SR latch out of transistors. A SR or Set Reset latch consists of two NOR gates. When S is set high Q will stay high until S is set low and R is set high. This circuit is useful in itself for button de-bouncing. I did a simulation building out the latch only using NPN transistors.

SR_Latch

After tweaking the resistor values I went ahead started building out the circuit. For reliability and ease I decided to use the Manhattan Style of construction, a variant of of Ugly Construction. This style is very popular in the QRP Ham Radio community. It consists of using little copper pads on top of a sheet of copper clad. It has many advantages including prototyping speed, high reliability, low noise, high frequency opearation, and last it allows you to mix and match through hole and surface mount parts. The disadvantages is well, it’s ugly looking.
P1020380.JPG

P1020382.JPG

Using a cheap Harbor Freight punch I cut out all the the circular pads in two different diameters. I then clean the corrosion off the pads using sand paper, This helps with soldering and gluing.

P1020411.JPG

Pads are glued to the board with a generic super glue and then fluxed and tinned with solder. I can then cut and bend the parts leads in order to solder them to the board. All NPN transistors are 2n3904 and PNP are 2n2907.

P1020414.JPG

The circuit tested just fine, Now for something a bit more challenging, designing the voltage comparators. I looked at some transistor op-amps schematics along with the LM555 data sheet schematic. The first op amp appeared to use Darlington pair NPN transistors. I simplified things a bit by directly using resistors instead of current mirrors. I played with a few variants of the circuit and decided on the one below.

Voltage-comparator-NPN

Since I was not too confident about how it would work I tested it on a breadboard first. My major concerns were if it was going to be able to drive the SR latch and if the imperfect current gain (Beta) would throw off the comparator.
P1020442.JPG


When the negative side was connected to the reference and the positive was to the variable power it worked great. However the opposite was not true. Looking back at the data sheet it appears the LM555 uses PNP transistors for the second voltage comparator. I was hopping I could just build two of these and move on. So I had to go back to the simulator and play with some other designs.

Voltage-comparator-PNP

The Transistor on the right is not part of the voltage comparator but there to simulate this interfacing with the next stage. When I interfaced with the SR latch I bypassed the 10k resistor connected to the base.

P1020461.JPG

Here I am testing both comparators connecting to the SR latch. The reference voltages is coming from three 22k resistors on the breadboard. The top refrence should be (Vcc *.66) and the bottom is (Vcc *.33). Vcc is a 9v battery and the input was a variable power supply.

P1020462.JPG

Besides having a huge mess of wires everywhere it seems to work out just fine. The switching is not perfect on 3 and 6 volts but this is probably because the battery is not perfectly 9v and the resistors are not perfect.

P1020465.JPG

Here is the final board with all the modules cleaned up and soldered together with the the series 5k resistors on the board. It should have been obvious before but this was the first time I realized why this device is called the 555, it has to be because of the three 5k series resistors that govern how the device behaves. The transistor to drain the timing capacitor is on the bread board. It was not possible to drive it directly from the latch so I had to use another transistor as a voltage follower. In the video clip it is wired as an astable oscillator with R1 and R1 at 1K and C1 = 470uF and it looks to be working satisfactory.

Here it is running much faster, R1 and R2 are still 1k but C1 is now .015uF. That should equal 34.44khz with a duty cycle of %66. From the scope I roughly measured 31.2k and visually it look to be about %66. So I would say this is functionality correctly.

P1020474.JPG

So after three weeks and using 15 BJTs plus some sacrifices to error I have a huge 555 timer. This particular design does not have the output buffer stage but than can be added easily and not need for this testing. In the unlikely even’t 555s no longer exist I am prepaid. More importantly this project has really help me understand analog circuity, an art I feel that is an art that is dying fast in the digital world. I hope this information proves to be useful or at least inspire. Maybe I will tackle an LM741 next. You can see the full photo set on my Flickr page.

References


Testing an El84 Vacuum Tube with 9v Batteries

I have always been interested in vacuum tube amplifiers, however the high voltages from the mains has always kept me from experimenting with them. About a year ago I played with an low power tube the 1t4 in a regenerative receiver. The B+ was set to 45V powered from an array of 9v batteries. I decided to revisit an old guitar amplifier project I started in high school using an EL84 power pentode.

The first part was to figure out a way to mount the tube so I could experiment with it. I found an small metal box that worked well for mounting the tube socket. I then took some wires from a broken ATX power supply and soldered them to the tube socket.

P1020321.JPG

P1020324.JPG

P1020327.JPG

P1020328.JPG

P1020329.JPG


After I had everything assembled I brought it to the test bench and wired up the test circuit below. I measured the current at the anode versus the voltage at the gate. I kept adding 9v batters to the B+ supply and noted the results.

el84-test

P1020337.JPG

Below are the results I noted along with a graph. I also included the triode configuration graph from the original datasheet.

P1020340.JPG

El84

el84-philips1969-triod

So far the data looks consistent with the original datasheet for the tube in triode mode. The tube can sink a lot more current when VG2 is around 350V running in the full pentode configuration. Even with all 12 9V batteries I might be able to drive about 1watt of audio to a speaker. I was also surprised that the heater alone took around .7 amps at 6.3V. This is definitely not the most efficient way to drive a speaker I hope to get an proper impedance matching transformer so I can hear how it performers soon.

Laser Modem with an Arduino Microcontroller

After programing the Arduino, I took out the ATMega168 and wried it into a breadboard along with a 16mhz crystal and 5 volt regulator. For the receiver I used the phototransistor wired into two logic gates of a inverting Hex Schmitt trigger. I used the Schmitt trigger to act as a buffer and ensure only proper logic level enter the USB to serial converter on the Diecimila board. While the first test was successful, I was was not able to place the led more than an inch away from the phototransistor. To allow for more range I used an AD620AN instrumentation amplifier IC. For control I wired the gain pins of the amplifier into a small 10k potentiometer. After adjusting the gain I was able to get about a foot of range with reliable data transfer. Any further and there was too much noise in the signal.

At this moment I wondered if I could use a laser to extend my range. I happened to have a small laser that I pulled from a cheap laser level. I pulled out the laser and wired it where the IR led was minus the resistor. I then pointed the laser at the phototransistor and noticed it instantly reacted. In fact I had to turn the gain on the amplifier way down to use the signal. To test my range I wired my ATMega168 to a 9v battery and mounted the laster in a small vise a few feet away. After adjusting the gain I was able to transmit data easily. Attached is a video along with the final schematic I used.


View the Laser Modem Video Here

Fractal Mountain Generation with Qt and OpenGL

The purpose of this project is to create 3d mountain terrain using a recursive midpoint displacement formula. For this project I decided a GUI would be useful, that way manipulations could be seen in real time. This would require a 3d rendering package. My choices were DirectX, OpenGL and Java3d. Since I prefer to do my development in Linux, DirectX was ruled out. I have not been very impressed with the performance of Java3d so that left me with OpenGL. After deciding on my rendering package I needed to choose a language and a GUI framework. GLUI is an excellent framework for leaning OpenGL, but lacks control over the layout of the interface. So I decided on QT by Trolltech which was just recently acquired by Nokia.

Midpoint Displacement Formula

The midpoint Displacement Formula is simply to take two points, find the midpoint and then add or subtract a random number. This formula can then be repeated for each segment creating a fractal. This same concept can be converted to 3d in what is known as the Diamond-Square algorithm. Instead of two points we take a plane defined by four points, calculate the midpoint and add a random number. We can start with one large plane and perform the algorithm. Then divide the plane into four sub-planes and repeat. A recursive function works well for this task. For the mountains to look real, it is best to shorten the range of random numbers as the algorithm progresses. Below is the midpoint Function I wrote for this program in C++.
/****************************************
*This is the recursive algorithm of the
* midpoint formula
****************************************/
int GenFractal::midpoint(int i,int start,int topx, int topy) {
//Base case
if(i<1) {
return 0;
}

//find lenght for this section
int len = (int)pow(2,i);

//Calculate midpoints

//Top middle
int x1 = topx + len/2;
int y1 = topy;

//Right middle
int x2 = topx + len;
int y2 = topy + len/2;

//Bottom middle
int x3 = x1;
int y3 = y1 + len;

//Left Middle
int x4 = x2 – len;
int y4 = y2;

//Midpoint
int xmid = x1;
int ymid = y2;

//Calculate the values of the midpoints

//Top middle
data[x1][y1] = data[topx][topy] +
(data[topx+len][topy] – data[topx][topy])/2;

//Right middle
data[x2][y2] = data[topx+len][topy] +
(data[topx+len][topy+len] – data[topx+len][topy])/2;

//Bottom middle
data[x3][y3] = data[topx][topy+len] +
(data[topx+len][topy+len] – data[topx][topy+len])/2;

//Left middle
data[x4][y4] = data[topx][topy] +
(data[topx][topy+len] – data[topx][topy])/2;

//Midpoint
data[xmid][ymid] = data[x1][y1] + (data[x3][y3] – data[x1][y1])/2;

//Decrease the varence of randomness as iterations go foward
float min = hmin * (((float)start – ((float)start – (float)i)) / (float)start);
float max = hmax * (((float)start – ((float)start – (float)i)) / (float)start);
//Add random value to midpoint from hmin to hmax

data[xmid][ymid] += (int)(min + ((float)rand() / (float) RAND_MAX) * (max – min));


//As mountians get larger add less varence of random data

//Decrease I
i–;

//Recursive steps

//Upper left quadrant
midpoint(i,start,topx,topy);

//Upper right quadrant
midpoint(i,start,x1,y1);

//Lower left quadrant
midpoint(i,start,x4, y4);

//Lower right quadrant
midpoint(i,start,xmid,ymid);

return 0;

Building the Framework
For this project I decided on using QT4 with OpenGL. Since I am running Ubuntu, I used apt-get to install the QT4 development packages.

sudo apt-get install libqt4-dev qt4-dev-tools qt4-designer qt4-doc

For my development environment I chose the Eclipse IDE for C/C++ Developers with the QT Eclipse Integration Plugin. This allows for rapid development of QT applications. I decided to use CVS for version control since it is easy to setup and is integrated into eclipse.

Building the Interface
I built the interface using the Qt4 designer. Below you can see a screen shot of my application’s layout.



Rendering
For OpenGL rendering I had to create a QGLWidget Class. Once the class is created you can then paint to this widget using regular OpenGL functions. My OpenGL skills are not nearly as good as I would like. I have a copy of the Red and Blue Book which is enough information to get a rendering window, setup lighting and draw some polygons. For this project I converted the elevation map to triangles with the normals facing up and packed them into a GLfloat array. The polygons can be rendered with the following commands.

//Create array for triangles
GLfloat * vert = fractal.getTriangles();
int length = fractal.getNumTriangles();
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,vert);

GLuint list = glGenLists(1);
glNewList(list, GL_COMPILE);

//Set Color
float colorBlue[] = { 1.0f, 0.5f, 0.0f, 0.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colorBlue);

//Draw the triangles from array
glDrawArrays(GL_TRIANGLES,0,length);

glEndList();

This same data can then be used for my RAW triangles export by simply converting it to ASCII.


Windows XP / Vista Port
After I had a satisfactory application I decided to try porting it to windows. This is so windows users can try this program without having to compile it. I simply download QT for Windows with the MinGW GNU compiler and ran ‘qmake’ and ‘make’. Thats was about all that was needed.

Conclusion

This turned out to be a very involved programming project for me. There is a saying that no software is ever finished. This project has really solidified that for me. There are still may improvements and features I would like to add. I am still not 100% satisfied with the terrain generation. I feel that I could use some improvements of my algorithm.

Download
Source Code Tarball: Mountains.Feb-4-2008.tar.gz

Source Code Zip: Mountains.Feb-4-2008.zip

Win32 Binary: Mountains-win32.zip

Encoding an image to sound

The purpose of this project is to encode an image to a sound that can be viewed with a spectrogram. For some time I have known that musical artists have encoded pictures into their music. Most notable of these is artists is Aphex Twin. Luckily I had a copy of Windolicker and a great visualization program Sonic Visualiser. After looking at the images I decided it would be cool to try and encode my own images. I saw a few programs available, but decided it would be a better challenge to write my own program from scratch using Perl.

Spectrograms

A spectrogram is a graph representing the intensity or a frequency with relation to time. Normally the frequencies are along the Y axis, with the time on the X axis. The intensity of the frequency is represented by the brightness of the color. The frequency and color can use either a linear scale or a logarithmic scale. Below is an spectrogram of a few piano chords. The audio file used can be found on Wikipedia here.

Image encoding

The idea I had to encode the image was to simply create a sine wave at a corresponding frequency to represent the Y axis, a corresponding time to represent the X axis and a corresponding amplitude to represent the pixel color intensity.

Creating Sound

The first step to encoding an image was to learn how audio formats work. At first I tried writing a script that plays a frequency to the ‘/dev/dsp’ (Which is the sound card on Linux). When writing straight to /dev/dsp you are limited by a sample rate of 8000hz and a sample size of 8bits. Below simple Perl script that plays a concert A 440hz. To execute run ‘./sin.pl > /dev/dsp’.


#!/usr/bin/perl
use Math::Trig;
use strict;
use POSIX;

my $sample = 8000;
my $frequency = 440;
my $cycles = 6;
my $period = POSIX::floor($sample / $frequency * $cycles);

while (1) {
for(my $i=1;$i<=$period;$i++)
{
my $x = 128 + sin($cycles * 2 * pi * $i / $period) * 128;
$x = POSIX::floor($x);
my $char = pack(C,$x);
print $char color=”#ff00ff”>”
;
}
}

The DSP defaults do not offer much fidelity I needed at least the fidelity of an audio CD, which is 16bits at 44.1khz. I did some of searching on CPAN to find a library that allowed me write wave files. Most of the audio libraries had a too much overhead for what I wanted to do. Instead I looked up the file format for a ‘.wav’ and coded my own library. This library is limited to only producing a 16bit 44.1khz mono wave.


#!/usr/bin/perl
#Author Evan Salazar
#——————————————–
#
#Generate a .wav file for 16 bit mono PCM
#
#——————————————-
use strict;
package SimpleWave;

sub genWave {

#Get the reference to the data array

my ($audioData) = @_;

#This is the default sample rate
my $samplerate = 44100;
my $bits = 16;
my $samples = $#{$audioData} + 1;


my $channels = 1;

#Do Calculations for data wave headers
my $byterate = $samplerate * $channels * $bits / 8;
my $blockalign = $channels * $bits / 8;
my $filesize = $samples * ($bits/8) * $channels + 36;

#RIFF Chunk;
my $riff = pack(a4Va4,RIFF,$filesize,WAVE);

#Format Chunk
my $format = pack(a4VvvVVvv,
fmt ,
16,1,
$channels,
$samplerate,
$byterate,
$blockalign,
$bits);

#Data Chunk
my $dataChunk = pack(a4V,data,$blockalign * $samples);

#Read audoData array
my $data;
for(my $i=0;$i<$samples;$i++) {

$data .= pack(v,$audioData->[$i]);
}

#Return a byte string of the wave
return $riff . $format . $dataChunk. $data;
}
1;

Reading a Bitmap

Luckily I found a simple bitmap reader on CPAN called Image::BMP. This is a nice lightweight library that dose not depend on any external libraries or compiled code. Using this library I was able to easily load and read the bitmap data.

Encoding the Image

The first pass of my program disregarded the color data and only produced a frequency for the Y axis if the color intensity was less that half the sum of all colors. Below is an example. Note: I converted the WAV to an MP3 to conserve bandwidth, at 320kbps not much data is lost.

Audio File: ohmpie.mp3

I was really shocked to fist see the image! The only tweaking I needed to do was to use a linear scale for the frequency. Also if I selected too high an amplitude for the sin wave, clipping occurred in areas with too much black. For image above I used an amplitude of about 1000 on a scale of 0 to 32768.

The next step was to add amplitude scaling to match the color intensity. For this I summed all the color channels for a given pixel and scaled it to represent the max amplitude ‘(R + G + B) / 768 * max_amplitude’. Below is a picture of me after using the scaling.


Audio File: evan.mp3

By selecting a color scheme that goes from black to white and using a linear scale for the volume I get a very good black and white image. To prevent clipping on very dark images I added an inverse option that will invert the color producing a negative image.

Audo File: evanInv.mp3

You can reverse the color scheme to go from white to black to produce the regular image

Full Program

Below you can view and/or download the full code to this program. Currently performance is not optimized. So don’t write me telling me its slow. I currently have a few idea to speed it up. Also for best results use a small image around 100px tall.

Download: imageEncode-0.7.tar.gz