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.

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

Class Serialization in Perl

Serialization in Perl is the process of saving a class with multiple data types to a scalar (string of bytes). This can be used to save objects to a file or to transmit objects across the Internet. For this article I am going to describe the basics of creating a class in Perl and serialize it using the following packages: Data::Dumper, FreezeThaw, PHP::Serialization, and XML::Dumper.

Data types in Perl

Before we serialize anything we first need to learn a bit about the data types in Perl. There are only three data types in Perl, these are scalars, arrays and hash tables. Below is an example of each.

$myScalar = This is a Scalar;
@myArray = (Element zero,Element one,Element Two);
%myHash = ( keyOne => Data1, keyTwo => Data2);

print Scalar Data: . $myScalar . \n;
print Array element at index 1: . @myArray[1] . \n;
print Hash at KeyOne: . $myHash{keyOne} . \n;

Output:

Scalar Data: This is a Scalar
Array element at index 1: Element one
Hash at KeyOne: Data1

Like in C and C++, you can also have references to the data in each data type. The reference is not the data its self, but a location where the data can be found. By using special syntax the data can be retrieved from the reference itself.

$scalarReference = \$myScalar;
$arrayReference = \@myArray;
$hashReference = \%myHash;

print Scalar Reference: $scalarReference \n;
print Array Reference: $arrayReference \n;
print Hash Reference: $hashReference \n;

#Different ways to print the referenced data

print Scalar Data: . ${$scalarReference} . \n; #Or
print Scalar Data: . $$scalarReference . \n;

print Array element at index 1: . @{$arrayReference}[1] . \n; #Or
print Array element at index 1: . @$arrayReference[1] . \n; #Or
print Array element at index 1: . $arrayReference->[1] . \n;

print Hash at KeyOne: . ${$hashReference}{keyOne} . \n; #Or
print Hash at KeyOne: . $hashReference->{keyOne} . \n;

Output:

Scalar Reference: SCALAR(0x8153600)
Array Reference:  ARRAY(0x8153630)
Hash Reference:   HASH(0x8153690)
Scalar Data: This is a Scalar
Scalar Data: This is a Scalar
Array element at index 1: Element one
Array element at index 1: Element one
Array element at index 1: Element one
Hash at KeyOne: Data1
Hash at KeyOne: Data1

Classes in Perl

Perl was not originally designed to be an object oriented language, although it is possible to use it as one by using the following techniques. A class in Perl is basically just a module that returns a reference to a hash containing the data that is accessible to the class. This referenced is then “blessed” which means that it is bounded to the module. Perl uses some syntactical sugar to make this processes easy. Below is a test class in Perl that uses each of the data types. This class was created to test the serialization of each package.

#!/usr/bin/perl
#####################################################
#Author:Evan Salazar
#This is a just a simple perl class that uses
#different data types to be used in serialization
#####################################################
package TestClass;
use strict; #Normally use to keep data clean

#The Constructor
sub new {
print Creating the Class \n;

my $obj = {
name => {firstName => none, lastName => none}, #Test Hash
email => none@none.com, #Test Scalar
skills => undef, #Test array
gpgKey => }; #Binary Data
bless($obj);

return $obj;

}

#Set the Contact Name
sub setName {
my $self = shift;
$self->{name}->{firstName} = $_[0];
$self->{name}->{lastName} = $_[1];
}

#Set the E-Mail
sub setEmail {
my $self = shift;
$self->{email} = $_[0];
}

#Set the Skills
sub setSkills {
my $self = shift;
$self->{skills} = \@_;
}

#Set the GPG Key
sub setGpgKey {
my $self = shift;
$self->{gpgKey} = $_[0];
}

#Print all of the class Data
sub printAll {

my $self = shift;

#Print Full Name
print Name: .
$self->{name}->{firstName} .
.
$self->{name}->{firstName} . \n;
#Print E-Mail
print E-Mail: . $self->{email} . \n;

#Print Skills
print Skills: ;
for(my $i=0;$i<=$#{$self->{skills}};$i++) {
print $self->{skills}[$i] . ;
}
print \n;
print GPG Key: . unpack(H*,$self->{gpgKey}) . \n

}

1;

Perl Serialization Methods

There is no built in serialization in Perl, therefor serialization has to be done with an external package. After searching CPAN I found the following packages.

  • Data::Dumper – Serialize data into Perl code that can then be unserialized using the eval() procedure.
  • FreezeThaw – Converts objects to a string for data storage and retrieval.
  • PHP::Serialization – Serialize using a method that is compatible with the serialize() method in PHP.
  • XML::Dumper – Serialize to XML. Does not work with binary data.

These packages can be installed by downloading the source code and compiling or by using the following ‘cpan’ commands.

sudo cpan install Data::Dumper
sudo cpan install FreezeThaw
sudo cpan install PHP::Serialization
sudo cpan install XML::Dumper

Serializing TestClass

Below is a program that will serialize TestClass initialized with some sample data. The data will be serialized using all 4 classes.

#!/usr/bin/perl
#####################################################
#Author: Evan Salazar
#Serialize The data in TestClass
#####################################################
use strict;
use Storable;
use PHP::Serialization;
use FreezeThaw;
use TestClass;
use XML::Dumper;
use Data::Dumper;

#Create the New Test Class
my $myclass = TestClass::new();

#Fill the Test Class with data
$myclass->setName(Evan,Salazar);
$myclass->setEmail(esalazar1981@gmail.com);
$myclass->setSkills(Perl,PHP,Java,C,C++);
#—–Comment out to use XML::Dumper————–#
$myclass->setGpgKey(pack(H*,11061398fe828dcd83a4b9a79594c399)); #Not really my key but 128bits of random data

#Open File for wrting Serialized Data
open(PHPSER, >phpser);
open(FREEZETHAW, >freezeThaw);
open(XMLDUMPER, >xmldumper.xml);
open(DATADUMPER, >dataDumper.pl);

#Serialize Using Data::Dumper
print Data::Dumper\n;
print DATADUMPER Data::Dumper::Dumper($myclass);

#Serialize Using FreezeThaw
print FreezeThaw\n;
print FREEZETHAW FreezeThaw::freeze($myclass);

#Serialize Using PHP::Serialization
print PHP::Serializatoin\n;
print PHPSER PHP::Serialization::serialize($myclass);

#Serialize Using XML::Dumper
print XML::Dumper\n;
my $dump = new XML::Dumper;
print XMLDUMPER $dump->pl2xml($myclass);

This is the output from each method:

dataDumper.pl

<br /> $VAR1 = bless( {<br /> ‘email’ => ‘esalazar1981@gmail.com’,<br /> ‘skills’ => [<br /> ‘Perl’,<br /> ‘PHP’,<br /> ‘Java’,<br /> ‘C’,<br /> ‘C++'<br /> ],<br /> ‘name’ => {<br /> ‘firstName’ => ‘Evan’,<br /> ‘lastName’ => ‘Salazar’<br /> },<br /> ‘gpgKey’ => ‘���������Ù’<br /> }, ‘TestClass’ );<br />

FreezeThaw

<br /> FrT;@1|>>0|$9|TestClass%8|$5|email$6|gpgKey$4|name$6|skills$22|esalazar1981@gmail.com$16|���������Ù%4|$9|firstName$8|lastName$4|Evan$7|Salazar@5|$4|Perl$3|PHP$4|Java$1|C$3|C++<br />

phpser

<br /> O:9:”TestClass”:4:{s:5:”email”;s:22:”esalazar1981@gmail.com”;s:6:”skills”;a:5:{i:0;s:4:”Perl”;i:1;s:3:”PHP”;i:2;s:4:”Java”;i:3;s:1:”C”;i:4;s:3:”C++”;}s:4:”name”;a:2:{s:9:”firstName”;s:4:”Evan”;s:8:”lastName”;s:7:”Salazar”;}s:6:”gpgKey”;s:16:”���������Ù”;}<br />

xmldumper.xml

</p> <perldata> <hashref blessed_package=”TestClass” memory_address=”0x8314de4″><br /> <item key=”email”>esalazar1981@gmail.com</item><br /> <item key=”gpgKey”>���������Ù</item><br /> <item key=”name”><br /> <hashref memory_address=”0x8152c28″><br /> <item key=”firstName”>Evan</item><br /> <item key=”lastName”>Salazar</item><br /> </hashref><br /> </item><br /> <item key=”skills”><br /> <arrayref memory_address=”0x823bcf0″><br /> <item key=”0″>Perl</item><br /> <item key=”1″>PHP</item><br /> <item key=”2″>Java</item><br /> <item key=”3″>C</item><br /> <item key=”4″>C++</item><br /> </arrayref><br /> </item><br /> </hashref> </perldata>

Unserializing the Data

Below is the program that will unseralize the data from the previous program. Note that any binary data will not be unseralized using XML::Dumper. If you need to serialize binary data with this package, consider first encoding it using UUencode or base64 encode.

#!/usr/bin/perl
#####################################################
#Author: Evan Salazar
#Unserialize the data in TestClass
#####################################################
use strict;
use Storable;
use PHP::Serialization;
use FreezeThaw;
use TestClass;
use XML::Dumper;
use Data::Dumper;

#Set Slurp mode for reading
local($/) = undef;

#Open File for reading Serialized Data
open(PHPSER, phpser);
open(FREEZETHAW, freezeThaw);
open(XMLDUMPER, xmldumper.xml);
open(DATADUMPER, dataDumper.pl);

#Unserialize Using Data::Dumper
print Data::Dumper\n;
my $dataDumper = <DATADUMPER>;
#print $dataDumper
my $VAR1;
eval($dataDumper); #Data is stored into variable $VAR1
$VAR1->printAll;
print \n;

#Unserialize Using FreezeThaw
print FreezeThaw\n;
my $freezeThaw = <FREEZETHAW>;
#print $freezeThaw;
my ($classFreeze) = FreezeThaw::thaw($freezeThaw);
$classFreeze->printAll;
print \n;

#Unserialize Using PHP::Serialization
print PHP::Serializatoin\n;
my $phpser = <PHPSER>;
#print $phpser;
my $classPHP = PHP::Serialization::unserialize($phpser);
bless($classPHP,TestClass);
$classPHP->printAll;
print \n;

#Unserialize Using XML::Dumper
print XML::Dumper\n;
my $xmlDumper = <XMLDUMPER>;
my $dump = new XML::Dumper;
my $xmlClass = $dump->xml2pl($xmlDumper);
$xmlClass->printAll;

Program Output

Data::Dumper
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key: 11061398fe828dcd83a4b9a79594c399

FreezeThaw
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key: 11061398fe828dcd83a4b9a79594c399

PHP::Serializatoin
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key: 11061398fe828dcd83a4b9a79594c399

XML::Dumper

not well-formed (invalid token) at line 4, column 21, byte 148 at /usr/lib/perl5/XML/Parser.pm line 187

If you remove the binary data you will get

Data::Dumper
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key:

FreezeThaw
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key:

PHP::Serializatoin
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key:

XML::Dumper
Name: Evan Evan
E-Mail: esalazar1981@gmail.com
Skills: Perl PHP Java C C++
GPG Key:

Conclusion

All of these methods worked well for the given class, although binary to ASCII encoding is necessary for XML serialization. I personally prefer XML serialization because the data can be used with a wide variety of languages. Also XML serialization is human readable.

AC Motor / Generator Project

This project started one night while I was lying in bed trying to visualize how an AC motor worked. I knew that it was different from a DC motor as in it did not require brushes and the speed was controlled by frequency instead of voltage. After some research I came up with this project to better my understanding of AC motors.

AC Theory:
AC Current is different from DC in that the polarity is constantly inverting in a given period. For example: Lets say you have a standard battery hooked up to a volt meter. Normally you would connect the positive lead to the positive terminal of the battery as well as the negative lead to the negative terminal. If you wish to generate an AC current you would connect the leads normally for half a second and then invert them (where the positive terminal is connected to the negative lead and the negative terminal is connected to the positive lead) for another half second. If you constantly repeat this process you will have an AC current operating at one hertz (1hz). Where a hertz is 1 / Period. The period is the time the current is positive plus the time it is negative in one cycle, so in our case 0.5s + 0.5s = 1s per period. In America AC voltage to your home is typically 110 Volts at 60hz in a smooth sine wave.

Quick Magnet Theory:
A more in depth theory about magnets can be found here. For our practical purposes all we need to know is that a magnet has two poles, north and south. Poles attract each other when placed from north to south and repel when placed north to north or south to south.

Quick Electromagnet Theory:
An electromagnet is a magnet that is created with a coil. When current passes through the coil a magnetic flux is created. Conversely when a magnetic field passes through the coil a current is created. More information can be found here.

AC Motor/Generator theory
Most of the information I used to design this motor came from this page. I placed six magnets on the rotor with alternating poles and placed 6 coils in the housing with the polarities also alternating. When an AC current is run through the coils the polarity will switch the magnets poles from north to south at the given frequency. Therefor the rotor will turn so that the poles on the magnets will always line up.

Construction:

After I had a good idea of how I was going to build this motor I needed to collect parts. I already had some bolts that I can use for coils along with copper magnet wire. So off to Hobby Lobby. There I found some ultra strong magnets along with construction Styrofoam.

The base for the motor

Dividing the rotor into 6 sections

The completed measurements

Coil winding:
At this stage I had to determine how strong of an electromagnet I needed for the magnets I bought. Since the magnets are rated at “10” in strength, I had to create a electromagnet with enough magnetic flux to successfully repel the magnet.

Along with determining the proper coil windings, I also had to label the polarity of each magnet. I used a +5V DC power supply to test the coil. After experimenting I decided to use 350 turns with 30 gauge wire.

Once the polarity was determined for the magnets, I placed them in the rotor with hot glue.
The base fully assembled

The base with coils.

After the unit was fully assembled it was time to test it out. First I tested to see if spinning the rotor would generate an AC current. I wired all of the coils in series and hooked them up to the oscilloscope. Spinning the rotor by hand produced a rough sine wave at a about 100mv. Now it is time to try powering the motor. To generate a AC current I used a HP 200A audio oscillator at around 50hz. This device cannot supply much current so I ran it at high voltage (70v) through a step down transformer (110V to 12.6-0-12.6). After playing with lining up the coils I was able to successfully power the motor.

A Video of the Motor running can be found here